class SmoothRateLimiterStats extends RateLimiterStats {
  /* The nanos per interval between permits */
  final long intervalNanos;

  // The amount of time, relative to the start time, that the next permit will be free.
  // Will be a multiple of intervalNanos.
  private long nextFreePermitNanos;

  SmoothRateLimiterStats(RateLimiterConfig<?> config, Stopwatch stopwatch) {
    super(stopwatch);
    intervalNanos = config.getMaxRate().toNanos();
  }

  @Override
  public synchronized long acquirePermits(long requestedPermits, Duration maxWaitTime) {<FILL_FUNCTION_BODY>}

  synchronized long getNextFreePermitNanos() {
    return nextFreePermitNanos;
  }

  @Override
  synchronized void reset() {
    stopwatch.reset();
    nextFreePermitNanos = 0;
  }
}

    long currentNanos = stopwatch.elapsedNanos();
    long requestedPermitNanos = requestedPermits * intervalNanos;
    long waitNanos;
    long newNextFreePermitNanos;

    // If a permit is currently available
    if (currentNanos >= nextFreePermitNanos) {
      // Nanos at the start of the current interval
      long currentIntervalNanos = Maths.roundDown(currentNanos, intervalNanos);
      newNextFreePermitNanos = Maths.add(currentIntervalNanos, requestedPermitNanos);
    } else {
      newNextFreePermitNanos = Maths.add(nextFreePermitNanos, requestedPermitNanos);
    }

    waitNanos = Math.max(newNextFreePermitNanos - currentNanos - intervalNanos, 0);

    if (exceedsMaxWaitTime(waitNanos, maxWaitTime))
      return -1;

    nextFreePermitNanos = newNextFreePermitNanos;
    return waitNanos;
  
<methods><variables>final non-sealed dev.failsafe.internal.RateLimiterStats.Stopwatch stopwatch