// Path: src/main/java/org/calrissian/flowmix/api/Aggregator.java
// public interface Aggregator extends Serializable {
// 
//     public static final String GROUP_BY = "groupBy";
//     public static final String GROUP_BY_DELIM = "\u0000";
// 
//     void configure(Map<String, String> configuration);
// 
//     void added(WindowItem item);
// 
//     void evicted(WindowItem item);
// 
//     List<AggregatedEvent> aggregate();
// }
// 
// Path: src/main/java/org/calrissian/flowmix/api/Policy.java
// public enum Policy implements Serializable {
// 
//     COUNT, TIME, TIME_DELTA_LT
// }
// 
// Path: src/main/java/org/calrissian/flowmix/core/model/op/AggregateOp.java
// public class AggregateOp implements FlowOp, RequiresPartitioning {
// 
//     public static final String AGGREGATE = "aggregate";
// 
//     private final Class<? extends Aggregator> aggregatorClass;
//     private final Policy triggerPolicy;
//     private final Policy evictionPolicy;
//     private final long triggerThreshold;
//     private final long evictionThreshold;
//     private final boolean clearOnTrigger;
// 
//     private long windowEvictMillis;
// 
//     private Map<String,String> config;
// 
//     public AggregateOp(Class<? extends Aggregator> aggregatorClass, Policy triggerPolicy, long triggerThreshold,
//                        Policy evictionPolicy, long evictionThreshold, Map<String,String> config, boolean clearOnTrigger,
//                        long windowEvictMillis) {
//         this.aggregatorClass = aggregatorClass;
//         this.triggerPolicy = triggerPolicy;
//         this.evictionPolicy = evictionPolicy;
//         this.triggerThreshold = triggerThreshold;
//         this.evictionThreshold = evictionThreshold;
//         this.config = config;
//         this.clearOnTrigger = clearOnTrigger;
//         this.windowEvictMillis = windowEvictMillis;
//     }
// 
//     public boolean isClearOnTrigger() {
//       return clearOnTrigger;
//     }
// 
//     public Class<? extends Aggregator> getAggregatorClass() {
//         return aggregatorClass;
//     }
// 
//     public Policy getTriggerPolicy() {
//         return triggerPolicy;
//     }
// 
//     public Policy getEvictionPolicy() {
//         return evictionPolicy;
//     }
// 
//     public long getTriggerThreshold() {
//         return triggerThreshold;
//     }
// 
//     public long getEvictionThreshold() {
//         return evictionThreshold;
//     }
// 
//     public Map<String, String> getConfig() {
//       return config;
//     }
// 
//     public long getWindowEvictMillis() {
//       return windowEvictMillis;
//     }
// 
//     @Override
//     public String getComponentName() {
//         return AGGREGATE;
//     }
// }
// 
// Path: src/main/java/org/calrissian/flowmix/core/model/op/FlowOp.java
// public interface FlowOp extends Serializable {
// 
//     String getComponentName();
// }
// 
// Path: src/main/java/org/calrissian/flowmix/core/model/op/PartitionOp.java
// public class PartitionOp implements FlowOp {
// 
//   public static final String PARTITION = "partition";
//   private List<String> fields;
// 
//   public PartitionOp(List<String> fields) {
//       this.fields = fields;
//   }
// 
//   public List<String> getFields() {
//       return fields;
//   }
// 
//   @Override
//   public String getComponentName() {
//       return PARTITION;
//   }
// 
//   @Override
//   public String toString() {
//     return "PartitionOp{" +
//             "fields=" + fields +
//             '}';
//   }
// }


import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.calrissian.flowmix.api.Aggregator;
import org.calrissian.flowmix.api.Policy;
import org.calrissian.flowmix.core.model.op.AggregateOp;
import org.calrissian.flowmix.core.model.op.FlowOp;
import org.calrissian.flowmix.core.model.op.PartitionOp;
import static java.util.Collections.EMPTY_LIST;
    public AggregateBuilder trigger(Policy policy, long threshold) {
        this.triggerPolicy = policy;
        this.triggerThreshold = threshold;
        return this;
    }

    public AggregateBuilder evict(Policy policy, long threshold) {
        this.evictionPolicy = policy;
        this.evictionThreshold = threshold;
        return this;
    }

    public AggregateBuilder windowEvictMillis(long millis) {
      this.windowEvictMillis = millis;
      return this;
    }

    public StreamBuilder end() {

      if(aggregatorClass == null)
          throw new RuntimeException("Aggregator operator needs an aggregator class");

      if(triggerPolicy == null || triggerThreshold == -1)
          throw new RuntimeException("Aggregator operator needs to have trigger policy and threshold");

      if(evictionPolicy == null || evictionThreshold == -1)
          throw new RuntimeException("Aggregator operator needs to have eviction policy and threshold");

      List<FlowOp> flowOpList = getStreamBuilder().getFlowOpList();
      FlowOp op = flowOpList.size() == 0 ? null : flowOpList.get(flowOpList.size()-1);
// Path: src/main/java/org/calrissian/flowmix/api/Aggregator.java
// public interface Aggregator extends Serializable {
// 
//     public static final String GROUP_BY = "groupBy";
//     public static final String GROUP_BY_DELIM = "\u0000";
// 
//     void configure(Map<String, String> configuration);
// 
//     void added(WindowItem item);
// 
//     void evicted(WindowItem item);
// 
//     List<AggregatedEvent> aggregate();
// }
// 
// Path: src/main/java/org/calrissian/flowmix/api/Policy.java
// public enum Policy implements Serializable {
// 
//     COUNT, TIME, TIME_DELTA_LT
// }
// 
// Path: src/main/java/org/calrissian/flowmix/core/model/op/AggregateOp.java
// public class AggregateOp implements FlowOp, RequiresPartitioning {
// 
//     public static final String AGGREGATE = "aggregate";
// 
//     private final Class<? extends Aggregator> aggregatorClass;
//     private final Policy triggerPolicy;
//     private final Policy evictionPolicy;
//     private final long triggerThreshold;
//     private final long evictionThreshold;
//     private final boolean clearOnTrigger;
// 
//     private long windowEvictMillis;
// 
//     private Map<String,String> config;
// 
//     public AggregateOp(Class<? extends Aggregator> aggregatorClass, Policy triggerPolicy, long triggerThreshold,
//                        Policy evictionPolicy, long evictionThreshold, Map<String,String> config, boolean clearOnTrigger,
//                        long windowEvictMillis) {
//         this.aggregatorClass = aggregatorClass;
//         this.triggerPolicy = triggerPolicy;
//         this.evictionPolicy = evictionPolicy;
//         this.triggerThreshold = triggerThreshold;
//         this.evictionThreshold = evictionThreshold;
//         this.config = config;
//         this.clearOnTrigger = clearOnTrigger;
//         this.windowEvictMillis = windowEvictMillis;
//     }
// 
//     public boolean isClearOnTrigger() {
//       return clearOnTrigger;
//     }
// 
//     public Class<? extends Aggregator> getAggregatorClass() {
//         return aggregatorClass;
//     }
// 
//     public Policy getTriggerPolicy() {
//         return triggerPolicy;
//     }
// 
//     public Policy getEvictionPolicy() {
//         return evictionPolicy;
//     }
// 
//     public long getTriggerThreshold() {
//         return triggerThreshold;
//     }
// 
//     public long getEvictionThreshold() {
//         return evictionThreshold;
//     }
// 
//     public Map<String, String> getConfig() {
//       return config;
//     }
// 
//     public long getWindowEvictMillis() {
//       return windowEvictMillis;
//     }
// 
//     @Override
//     public String getComponentName() {
//         return AGGREGATE;
//     }
// }
// 
// Path: src/main/java/org/calrissian/flowmix/core/model/op/FlowOp.java
// public interface FlowOp extends Serializable {
// 
//     String getComponentName();
// }
// 
// Path: src/main/java/org/calrissian/flowmix/core/model/op/PartitionOp.java
// public class PartitionOp implements FlowOp {
// 
//   public static final String PARTITION = "partition";
//   private List<String> fields;
// 
//   public PartitionOp(List<String> fields) {
//       this.fields = fields;
//   }
// 
//   public List<String> getFields() {
//       return fields;
//   }
// 
//   @Override
//   public String getComponentName() {
//       return PARTITION;
//   }
// 
//   @Override
//   public String toString() {
//     return "PartitionOp{" +
//             "fields=" + fields +
//             '}';
//   }
// }


// Path: src/main/java/org/calrissian/flowmix/api/builder/AggregateBuilder.java
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.calrissian.flowmix.api.Aggregator;
import org.calrissian.flowmix.api.Policy;
import org.calrissian.flowmix.core.model.op.AggregateOp;
import org.calrissian.flowmix.core.model.op.FlowOp;
import org.calrissian.flowmix.core.model.op.PartitionOp;
import static java.util.Collections.EMPTY_LIST;

    public AggregateBuilder trigger(Policy policy, long threshold) {
        this.triggerPolicy = policy;
        this.triggerThreshold = threshold;
        return this;
    }

    public AggregateBuilder evict(Policy policy, long threshold) {
        this.evictionPolicy = policy;
        this.evictionThreshold = threshold;
        return this;
    }

    public AggregateBuilder windowEvictMillis(long millis) {
      this.windowEvictMillis = millis;
      return this;
    }

    public StreamBuilder end() {

      if(aggregatorClass == null)
          throw new RuntimeException("Aggregator operator needs an aggregator class");

      if(triggerPolicy == null || triggerThreshold == -1)
          throw new RuntimeException("Aggregator operator needs to have trigger policy and threshold");

      if(evictionPolicy == null || evictionThreshold == -1)
          throw new RuntimeException("Aggregator operator needs to have eviction policy and threshold");

      List<FlowOp> flowOpList = getStreamBuilder().getFlowOpList();
      FlowOp op = flowOpList.size() == 0 ? null : flowOpList.get(flowOpList.size()-1);
      if(op == null || !(op instanceof PartitionOp))