/**
  * Subclasses might override this method to define the meta data transformation performed by this
  * operator. The default implementation takes all attributes specified by the {@link
  * AttributeSubsetSelector} and passes them to {@link #modifyAttributeMetaData(ExampleSetMetaData,
  * AttributeMetaData)} and replaces them accordingly.
  *
  * @throws UndefinedParameterError
  */
 @Override
 protected ExampleSetMetaData modifyMetaData(ExampleSetMetaData exampleSetMetaData)
     throws UndefinedParameterError {
   ExampleSetMetaData subsetMetaData =
       attributeSelector.getMetaDataSubset(exampleSetMetaData, isSupportingAttributeRoles());
   checkSelectedSubsetMetaData(subsetMetaData);
   for (AttributeMetaData amd : subsetMetaData.getAllAttributes()) {
     Collection<AttributeMetaData> replacement = null;
     replacement = modifyAttributeMetaData(exampleSetMetaData, amd);
     if (replacement != null) {
       if (replacement.size() == 1) {
         AttributeMetaData replacementAttribute = replacement.iterator().next();
         replacementAttribute.setRole(
             exampleSetMetaData.getAttributeByName(amd.getName()).getRole());
       }
       exampleSetMetaData.removeAttribute(amd);
       exampleSetMetaData.addAllAttributes(replacement);
     }
   }
   return exampleSetMetaData;
 }
  private ExampleSetMetaData applyRulesOnMetaData(
      List<String> rules, MetaData metaData, FilterConditon condition)
      throws UndefinedParameterError {
    if (metaData == null || !(metaData instanceof ExampleSetMetaData) || condition == null) {
      return new ExampleSetMetaData();
    }
    ExampleSetMetaData sortedMetaData = new ExampleSetMetaData();
    ExampleSetMetaData originalMetaData = (ExampleSetMetaData) metaData;
    Collection<AttributeMetaData> allAttributes = originalMetaData.getAllAttributes();

    // iterate over all rules
    for (String currentRule : rules) {

      // iterate over all original attributes and check if rule applies
      Iterator<AttributeMetaData> iterator = allAttributes.iterator();
      while (iterator.hasNext()) {
        AttributeMetaData attrMD = iterator.next();

        // skip special attributes
        if (attrMD.isSpecial()) {
          continue;
        }

        // if rule applies, remove attribute from unmachted list and add it to rules matched
        // list
        if (condition.match(currentRule, attrMD.getName())) {
          iterator.remove();
          sortedMetaData.addAttribute(attrMD);
        }
      }
    }

    if (!getParameterAsString(PARAMETER_HANDLE_UNMATCHED_ATTRIBUTES)
        .equals(REMOVE_UNMATCHED_MODE)) {
      sortedMetaData.addAllAttributes(allAttributes);
    }

    return sortedMetaData;
  }