code: public static RateLimiter create(double permitsPerSecond, long warmupPeriod, TimeUnit unit) {
          Assert.isTrue(warmupPeriod >= 0, com.github.ltsopensource.core.commons.utils.StringUtils.format("warmupPeriod must not be negative: {}", warmupPeriod));
          return create(SleepingStopwatch.createFromSystemTimer(), permitsPerSecond, warmupPeriod, unit,
                  3.0);
      }
docs: Creates a {@code RateLimiter} with the specified stable throughput, given as
  "permits per second" (commonly referred to as <i>QPS</i>, queries per second), and a
  <i>warmup period</i>, during which the {@code RateLimiter} smoothly ramps up its rate,
  until it reaches its maximum rate at the end of the period (as long as there are enough
  requests to saturate it). Similarly, if the {@code RateLimiter} is left <i>unused</i> for
  a duration of {@code warmupPeriod}, it will gradually return to its "cold" state,
  i.e. it will go through the same warming up process as when it was first created.
  <p/>
  <p>The returned {@code RateLimiter} is intended for cases where the resource that actually
  fulfills the requests (e.g., a remote server) needs "warmup" time, rather than
  being immediately accessed at the stable (maximum) rate.
  <p/>
  <p>The returned {@code RateLimiter} starts in a "cold" state (i.e. the warmup period
  will follow), and if it is left unused for long enough, it will return to that state.
  
  @param permitsPerSecond the rate of the returned {@code RateLimiter}, measured in
  how many permits become available per second
  @param warmupPeriod     the duration of the period where the {@code RateLimiter} ramps up its
  rate, before reaching its stable (maximum) rate
  @param unit             the time unit of the warmupPeriod argument
  @throws IllegalArgumentException if {@code permitsPerSecond} is negative or zero or
  {@code warmupPeriod} is negative