class AveragingProgressTracker extends ProgressTracker {

    @Override
    protected long estimateIsolatedDelay(final long now) {
        final long open = tasksOpen();
        if (open <= noDelayThreshold) {
            return 0L;
        }
        if (open >= tasksOpenLimit) {
            return defaultTicksPerTask();
        }

        /*
         * Calculate the task capacity relative to the limit on open tasks. In real terms this value can be
         * in the open interval (0.0, 0.5).
         */
        final double relativeRemainingCapacity = 1.0 - (double) open / tasksOpenLimit;

        /*
         * Calculate delay coefficient. It increases in inverse proportion to relative remaining capacity, approaching
         * infinity as remaining capacity approaches 0.0.
         */
        final double delayCoefficient = (0.5 - relativeRemainingCapacity) / relativeRemainingCapacity;
        final long delay = (long) (ticksWorkedPerClosedTask(now) * delayCoefficient);

        /*
         * Cap the result to defaultTicksPerTask, since the calculated delay may overstep it.
         */
        return Math.min(delay, defaultTicksPerTask());
    }

    private  AveragingProgressTracker(final long limit, final long ticksPerTask);
      AveragingProgressTracker(final long limit);
      AveragingProgressTracker(final ProgressTracker oldTracker, final long limit, final long now);
      AveragingProgressTracker(final AveragingProgressTracker oldTracker, final long now);

}