public void extractFeatures(List regions) throws FeatureExtractorException {
    // Construct a list of subregions.
    List<Region> subregions = new ArrayList<Region>();
    for (Region r : (List<Region>) regions) {
      if (r.hasAttribute(subregion_attribute)) {
        subregions.add((Region) r.getAttribute(subregion_attribute));
      } else {
        throw new FeatureExtractorException(
            "Region, " + r + ", does not have a valid subregion feature, " + subregion_attribute);
      }
    }

    try {
      // if Feature Extractor needs an attribute, copy it to the subregions.
      for (String f : fe.getRequiredFeatures()) {
        Region r = (Region) regions.get(0);
        if (r.getAttribute(f) instanceof Contour) {
          ContourUtils.assignValuesToSubregions(subregions, regions, f);
        } else {
          SubregionUtils.assignFeatureToSubregions(regions, subregion_attribute, f);
        }

      }
    } catch (AuToBIException e) {
      throw new FeatureExtractorException(e.getMessage());
    }

    fe.extractFeatures(subregions);

    // Copy extracted features from subregions to regions
    for (int i = 0; i < regions.size(); ++i) {
      Region r = (Region) regions.get(i);
      Region subregion = subregions.get(i);
      for (String feature : fe.getExtractedFeatures()) {
        r.setAttribute(feature + "_" + subregion_attribute, subregion.getAttribute(feature));
      }
    }
  }