// Path: endpoints-control/src/main/java/com/google/api/control/model/Timestamps.java
// public final class Timestamps {
//   private static final int MILLIS_PER_SECOND = 1000;
//   private static final int NANOS_PER_MILLI = 1000000;
// 
//   private Timestamps() {}
// 
//   /**
//    * A {@code Comparator} of {@link Timestamp}
//    */
//   public static Comparator<Timestamp> COMPARATOR = new Comparator<Timestamp>() {
//     @Override
//     public int compare(Timestamp o1, Timestamp o2) {
//       int secondsOrder = Long.compare(o1.getSeconds(), o2.getSeconds());
//       if (secondsOrder != 0) {
//         return secondsOrder;
//       } else {
//         return Long.compare(o1.getNanos(), o2.getNanos());
//       }
//     }
//   };
// 
//   /**
//    * Obtain the current time from a {@link Clock}
//    *
//    * @param clock gives the current time
//    * @return a {@code Timestamp} corresponding to the ticker's current value
//    */
//   public static Timestamp now(Clock clock) {
//     return fromEpoch(clock.currentTimeMillis());
//   }
// 
//   /**
//    * Obtain the current time from the unix epoch
//    *
//    * @param epochMillis gives the current time in milliseconds since since the epoch
//    * @return a {@code Timestamp} corresponding to the ticker's current value
//    */
//   public static Timestamp fromEpoch(long epochMillis) {
//     return Timestamp
//         .newBuilder()
//         .setNanos((int) ((epochMillis % MILLIS_PER_SECOND) * NANOS_PER_MILLI))
//         .setSeconds(epochMillis / MILLIS_PER_SECOND)
//         .build();
//   }
// }


import com.google.api.MetricDescriptor.MetricKind;
import com.google.api.control.model.Timestamps;
import com.google.api.servicecontrol.v1.MetricValue;
import com.google.api.servicecontrol.v1.MetricValueSet;
import com.google.api.servicecontrol.v1.Operation;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
          MetricValueSet.newBuilder().setMetricName(name).addAllMetricValues(values));
    }
    return op.build();
  }

  private void mergeMetricValues(Operation other) {
    List<MetricValueSet> mvSets = other.getMetricValueSetsList();
    for (MetricValueSet mvSet : mvSets) {
      Map<String, MetricValue> bySignature = this.metricValues.get(mvSet.getMetricName());
      if (bySignature == null) {
        bySignature = Maps.newHashMap();
        this.metricValues.put(mvSet.getMetricName(), bySignature);
      }
      for (MetricValue mv : mvSet.getMetricValuesList()) {
        String signature = MetricValues.sign(mv).toString();
        MetricValue prior = bySignature.get(signature);
        if (prior == null) {
          bySignature.put(signature, mv);
        } else {
          MetricKind kind = this.kinds.get(mvSet.getMetricName());
          if (kind == null) {
            kind = DEFAULT_KIND;
          }
          bySignature.put(signature, MetricValues.merge(kind, prior, mv));
        }
      }
    }
  }

  private void mergeTimestamps(Operation other) {
// Path: endpoints-control/src/main/java/com/google/api/control/model/Timestamps.java
// public final class Timestamps {
//   private static final int MILLIS_PER_SECOND = 1000;
//   private static final int NANOS_PER_MILLI = 1000000;
// 
//   private Timestamps() {}
// 
//   /**
//    * A {@code Comparator} of {@link Timestamp}
//    */
//   public static Comparator<Timestamp> COMPARATOR = new Comparator<Timestamp>() {
//     @Override
//     public int compare(Timestamp o1, Timestamp o2) {
//       int secondsOrder = Long.compare(o1.getSeconds(), o2.getSeconds());
//       if (secondsOrder != 0) {
//         return secondsOrder;
//       } else {
//         return Long.compare(o1.getNanos(), o2.getNanos());
//       }
//     }
//   };
// 
//   /**
//    * Obtain the current time from a {@link Clock}
//    *
//    * @param clock gives the current time
//    * @return a {@code Timestamp} corresponding to the ticker's current value
//    */
//   public static Timestamp now(Clock clock) {
//     return fromEpoch(clock.currentTimeMillis());
//   }
// 
//   /**
//    * Obtain the current time from the unix epoch
//    *
//    * @param epochMillis gives the current time in milliseconds since since the epoch
//    * @return a {@code Timestamp} corresponding to the ticker's current value
//    */
//   public static Timestamp fromEpoch(long epochMillis) {
//     return Timestamp
//         .newBuilder()
//         .setNanos((int) ((epochMillis % MILLIS_PER_SECOND) * NANOS_PER_MILLI))
//         .setSeconds(epochMillis / MILLIS_PER_SECOND)
//         .build();
//   }
// }


// Path: endpoints-control/src/main/java/com/google/api/control/aggregator/OperationAggregator.java
import com.google.api.MetricDescriptor.MetricKind;
import com.google.api.control.model.Timestamps;
import com.google.api.servicecontrol.v1.MetricValue;
import com.google.api.servicecontrol.v1.MetricValueSet;
import com.google.api.servicecontrol.v1.Operation;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;

          MetricValueSet.newBuilder().setMetricName(name).addAllMetricValues(values));
    }
    return op.build();
  }

  private void mergeMetricValues(Operation other) {
    List<MetricValueSet> mvSets = other.getMetricValueSetsList();
    for (MetricValueSet mvSet : mvSets) {
      Map<String, MetricValue> bySignature = this.metricValues.get(mvSet.getMetricName());
      if (bySignature == null) {
        bySignature = Maps.newHashMap();
        this.metricValues.put(mvSet.getMetricName(), bySignature);
      }
      for (MetricValue mv : mvSet.getMetricValuesList()) {
        String signature = MetricValues.sign(mv).toString();
        MetricValue prior = bySignature.get(signature);
        if (prior == null) {
          bySignature.put(signature, mv);
        } else {
          MetricKind kind = this.kinds.get(mvSet.getMetricName());
          if (kind == null) {
            kind = DEFAULT_KIND;
          }
          bySignature.put(signature, MetricValues.merge(kind, prior, mv));
        }
      }
    }
  }

  private void mergeTimestamps(Operation other) {
    if (Timestamps.COMPARATOR.compare(other.getStartTime(), op.getStartTime()) == -1) {