class MetricX {

    // Total working time consumed by Iterators
    public static AtomicLong iteratorSum = new AtomicLong();
    // Num of Iterators
    public static AtomicLong iteratorCount = new AtomicLong();
    // Max working time consumed by Iterators
    public static AtomicLong iteratorMax = new AtomicLong();
    public AtomicLong failureCount = new AtomicLong();
    // Combined to be used to record a task's time
    private long start;
    private long end;

    private MetricX(long start) {
        this.start = start;
    }

    public static MetricX ofStart() {
        return new MetricX(System.currentTimeMillis());
    }

    public static void plusIteratorWait(long nanoSeconds) {<FILL_FUNCTION_BODY>}

    /**
     * amount of waiting
     *
     * @return millisecond
     */
    public static long getIteratorWait() {
        return iteratorSum.get() / 1_000_000;
    }

    /**
     * average of waiting
     *
     * @return millisecond
     */
    public static long getIteratorWaitAvg() {
        if (iteratorCount.get() == 0) {
            return -1;
        }
        return getIteratorWait() / iteratorCount.get();
    }

    /**
     * maximum of waiting
     *
     * @return millisecond
     */
    public static long getIteratorWaitMax() {
        return iteratorMax.get() / 1_000_000;
    }

    public static long getIteratorCount() {
        return iteratorCount.get();
    }

    public long start() {
        return this.start = System.currentTimeMillis();
    }

    public long end() {
        return this.end = System.currentTimeMillis();
    }

    public long past() {
        return this.end - this.start;
    }

    public void countFail() {
        this.failureCount.getAndIncrement();
    }

    public long getFailureCount() {
        return this.failureCount.get();
    }

}

        iteratorSum.addAndGet(nanoSeconds);
        iteratorCount.getAndIncrement();
        if (iteratorMax.get() < nanoSeconds) {
            iteratorMax.set(nanoSeconds);
        }
    
<no_super_class>