class StartTimeHolder {
    protected long time;

    long startTime() {
      if (time == 0) {
        return System.nanoTime();
      } else {
        return time;
      }
    }
  }

  private final ThreadLocal<StartTimeHolder> tlIntendedStartTime = new ThreadLocal<Measurements.StartTimeHolder>() {
    protected StartTimeHolder initialValue() {
      return new StartTimeHolder();
    }
  };

  public void setIntendedStartTimeNs(long time) {
    if (measurementInterval == 0) {
      return;
    }
    tlIntendedStartTime.get().time = time;
  }

  public long getIntendedStartTimeNs() {
    if (measurementInterval == 0) {
      return 0L;
    }
    return tlIntendedStartTime.get().startTime();
  }

  /**
   * Report a single value of a single metric. E.g. for read latency, operation="READ" and latency is the measured
   * value.
   */
  public void measure(String operation, int latency) {
    if (measurementInterval == 1) {
      return;
    }
    try {
      OneMeasurement m = getOpMeasurement(operation);
      m.measure(latency);
    } catch (java.lang.ArrayIndexOutOfBoundsException e) {
      // This seems like a terribly hacky way to cover up for a bug in the measurement code
      System.out.println("ERROR: java.lang.ArrayIndexOutOfBoundsException - ignoring and continuing");
      e.printStackTrace();
      e.printStackTrace(System.out);
    }
  }

  /**
   * Report a single value of a single metric. E.g. for read latency, operation="READ" and latency is the measured
   * value.
   */
  public void measureIntended(String operation, int latency) {
    if (measurementInterval == 0) {
      return;
    }
    try {
      OneMeasurement m = getOpIntendedMeasurement(operation);
      m.measure(latency);
    } catch (java.lang.ArrayIndexOutOfBoundsException e) {
      // This seems like a terribly hacky way to cover up for a bug in the measurement code
      System.out.println("ERROR: java.lang.ArrayIndexOutOfBoundsException - ignoring and continuing");
      e.printStackTrace();
      e.printStackTrace(System.out);
    }
  }

  private OneMeasurement getOpMeasurement(String operation) {<FILL_FUNCTION_BODY>

    OneMeasurement m = opToMesurementMap.get(operation);
    if (m == null) {
      m = constructOneMeasurement(operation);
      OneMeasurement oldM = opToMesurementMap.putIfAbsent(operation, m);
      if (oldM != null) {
        m = oldM;
      }
    }
    return m;
  
<no_super_class>