class Refill {

    final long periodNanos;
    final long tokens;
    final boolean refillIntervally;
    final long timeOfFirstRefillMillis;
    final boolean useAdaptiveInitialTokens;

    private Refill(long tokens, Duration period, boolean refillIntervally, long timeOfFirstRefillMillis, boolean useAdaptiveInitialTokens) {
        if (period == null) {
            throw BucketExceptions.nullRefillPeriod();
        }
        if (tokens <= 0) {
            throw BucketExceptions.nonPositivePeriodTokens(tokens);
        }
        this.periodNanos = period.toNanos();
        if (periodNanos <= 0) {
            throw BucketExceptions.nonPositivePeriod(periodNanos);
        }
        if (tokens > periodNanos) {
            throw BucketExceptions.tooHighRefillRate(periodNanos, tokens);
        }

        this.tokens = tokens;
        this.refillIntervally = refillIntervally;
        this.timeOfFirstRefillMillis = timeOfFirstRefillMillis;
        this.useAdaptiveInitialTokens = useAdaptiveInitialTokens;
    }

    @Deprecated
    public static Refill of(long tokens, Duration period) {
        return greedy(tokens, period);
    }

    @Deprecated
    public static Refill smooth(long tokens, Duration period) {
        return greedy(tokens, period);
    }

    /**
     * This method is deprecated, you should use {@link BandwidthBuilderRefillStage#refillGreedy(long, Duration)}
     *
     * @deprecated
     */
    @Deprecated
    public static Refill greedy(long tokens, Duration period) {
        return new Refill(tokens, period, false, Bandwidth.UNSPECIFIED_TIME_OF_FIRST_REFILL, false);
    }

    /**
     * This method is deprecated, you should use {@link BandwidthBuilderRefillStage#refillIntervally(long, Duration)}
     *
     * @deprecated
     */
    @Deprecated
    public static Refill intervally(long tokens, Duration period) {
        return new Refill(tokens, period, true, Bandwidth.UNSPECIFIED_TIME_OF_FIRST_REFILL, false);
    }


    /**
     * This method is deprecated, you should use {@link BandwidthBuilderRefillStage#refillIntervallyAligned(long, Duration, Instant)} or 
     * {@link BandwidthBuilderRefillStage#refillIntervallyAlignedWithAdaptiveInitialTokens(long, Duration, Instant)}
     *
     * @deprecated
     */
    @Deprecated
    public static Refill intervallyAligned(long tokens, Duration period, Instant timeOfFirstRefill, boolean useAdaptiveInitialTokens) {<FILL_FUNCTION_BODY>}

    @Override
    public String toString() {
        final StringBuilder sb = new StringBuilder("Refill{");
        sb.append("periodNanos=").append(periodNanos);
        sb.append(", tokens=").append(tokens);
        sb.append(", refillIntervally=").append(refillIntervally);
        sb.append(", timeOfFirstRefillMillis=").append(timeOfFirstRefillMillis);
        sb.append(", useAdaptiveInitialTokens=").append(useAdaptiveInitialTokens);
        sb.append('}');
        return sb.toString();
    }

}

        long timeOfFirstRefillMillis = timeOfFirstRefill.toEpochMilli();
        if (timeOfFirstRefillMillis < 0) {
            throw BucketExceptions.nonPositiveTimeOfFirstRefill(timeOfFirstRefill);
        }
        return new Refill(tokens, period, true, timeOfFirstRefillMillis, useAdaptiveInitialTokens);
    
<no_super_class>