@Override
 public Matcher visit(Select select) {
   Condition condition = select.getCondition();
   if (condition != null) {
     return condition.accept(this);
   } else {
     return new MatchAll();
   }
 }
 @Override
 public List<DataRecord> visit(Select select) {
   if (!select.isProjection()) {
     return records;
   } else {
     List<DataRecord> filteredRecords = new LinkedList<DataRecord>();
     for (TypedExpression expression : select.getSelectedFields()) {
       expression.accept(this);
     }
     if (!aggregateProjection.isEmpty()) {
       for (FieldMetadata fieldMetadata : aggregateProjection.keySet()) {
         explicitProjection.addField(fieldMetadata);
       }
       for (Map.Entry<FieldMetadata, AggregateValueBuilder> entry :
           aggregateProjection.entrySet()) {
         Collection<Object> aggregateValues = entry.getValue().getValues(records);
         for (Object aggregateValue : aggregateValues) {
           DataRecord newRecord =
               new DataRecord(explicitProjection, UnsupportedDataRecordMetadata.INSTANCE);
           newRecord.set(entry.getKey(), aggregateValue);
           filteredRecords.add(newRecord);
         }
       }
     } else if (!recordProjection.isEmpty()) {
       ComplexTypeMetadata explicitProjection =
           new ComplexTypeMetadataImpl("", "ExplicitProjectionType", true);
       for (FieldMetadata fieldMetadata : recordProjection.keySet()) {
         explicitProjection.addField(fieldMetadata);
       }
       for (DataRecord inputReport : records) {
         DataRecord newRecord =
             new DataRecord(explicitProjection, UnsupportedDataRecordMetadata.INSTANCE);
         for (Map.Entry<FieldMetadata, ValueBuilder> entry : recordProjection.entrySet()) {
           newRecord.set(entry.getKey(), entry.getValue().getValue(inputReport));
         }
       }
     }
     return filteredRecords;
   }
 }