@@ -0,0 +1,1277 @@
+package ca.szc.keratin.bot.util;%0A%0Aimport java.util.concurrent.TimeUnit;%0A%0Apublic class RateLimiter%0A%7B%0A    private long lastSuccessMillis;%0A%0A    private final long cooldownMillis;%0A%0A    public RateLimiter( long cooldown, TimeUnit cooldownUnit )%0A    %7B%0A        this( cooldownUnit.toMillis( cooldown ) );%0A    %7D%0A%0A    public RateLimiter( long cooldownMillis )%0A    %7B%0A        this.cooldownMillis = cooldownMillis;%0A    %7D%0A%0A    /**%0A     * Has the cooldown time expired? Never restarts the cooldown.%0A     * %0A     * @return true iff the current time is greater than the last successful call time plus the cooldown time.%0A     */%0A    public boolean peek()%0A    %7B%0A        synchronized ( this )%0A        %7B%0A            return System.currentTimeMillis() %3E lastSuccessMillis + cooldownMillis;%0A        %7D%0A    %7D%0A%0A    /**%0A     * Has the cooldown time expired? When returning true, the cooldown is started again.%0A     * %0A     * @return true iff the current time is greater than the last successful call time plus the cooldown time.%0A     */%0A    public boolean available()%0A    %7B%0A        synchronized ( this )%0A        %7B%0A            if ( peek() )%0A            %7B%0A                lastSuccessMillis = System.currentTimeMillis();%0A                return true;%0A            %7D%0A            return false;%0A        %7D%0A    %7D%0A%7D%0A

Add generic rate limiter class to util subpackage