class ThrottleRequestFilter implements RequestFilter {
    private static final Logger logger = LoggerFactory.getLogger(ThrottleRequestFilter.class);
    private final Semaphore available;
    private final int maxWait;

    public ThrottleRequestFilter(int maxConnections) {
        this(maxConnections, Integer.MAX_VALUE);
    }

    public ThrottleRequestFilter(int maxConnections, int maxWait) {
        this(maxConnections, maxWait, false);
    }

    public ThrottleRequestFilter(int maxConnections, int maxWait, boolean fair) {
        this.maxWait = maxWait;
        available = new Semaphore(maxConnections, fair);
    }

    @Override
    public <T> FilterContext<T> filter(FilterContext<T> ctx) throws FilterException {<FILL_FUNCTION_BODY>}
}

        try {
            if (logger.isDebugEnabled()) {
                logger.debug("Current Throttling Status {}", available.availablePermits());
            }
            if (!available.tryAcquire(maxWait, TimeUnit.MILLISECONDS)) {
                throw new FilterException(String.format("No slot available for processing Request %s with AsyncHandler %s", ctx.getRequest(), ctx.getAsyncHandler()));
            }
        } catch (InterruptedException e) {
            throw new FilterException(String.format("Interrupted Request %s with AsyncHandler %s", ctx.getRequest(), ctx.getAsyncHandler()));
        }

        return new FilterContext.FilterContextBuilder<>(ctx)
                .asyncHandler(ReleasePermitOnComplete.wrap(ctx.getAsyncHandler(), available))
                .build();
    
<no_super_class>