class RequestLimit {
    @SuppressWarnings("unused")
    private volatile int requests;
    private volatile int max;

    private static final AtomicIntegerFieldUpdater<RequestLimit> requestsUpdater = AtomicIntegerFieldUpdater.newUpdater(RequestLimit.class, "requests");
    public static LimitConfig config = (LimitConfig) Config.getInstance().getJsonObjectConfig(LimitConfig.CONFIG_NAME, LimitConfig.class);


    /**
     * The handler that will be invoked if the queue is full.
     */
    private volatile HttpHandler failureHandler = new ResponseCodeHandler(config.getErrorCode());

    private final Queue<SuspendedRequest> queue;

    private final ExchangeCompletionListener COMPLETION_LISTENER = new ExchangeCompletionListener() {

        @Override
        public void exchangeEvent(final HttpServerExchange exchange, final NextListener nextListener) {
            SuspendedRequest task = null;
            boolean found = false;
            while ((task = queue.poll()) != null) {
                try {
                    task.exchange.addExchangeCompleteListener(COMPLETION_LISTENER);
                    task.exchange.dispatch(task.next);
                    found = true;
                    break;
                } catch (Throwable e) {
                    UndertowLogger.ROOT_LOGGER.error("Suspended request was skipped", e);
                }
            }

            if (!found) {
                decrementRequests();
            }

            nextListener.proceed();
        }
    };


    public RequestLimit(int maximumConcurrentRequests) {
        this(maximumConcurrentRequests, -1);
    }

    /**
     * Construct a new instance. The maximum number of concurrent requests must be at least one.
     *
     * @param maximumConcurrentRequests the maximum concurrent requests
     * @param queueSize                 The maximum number of requests to queue
     */
    public RequestLimit(int maximumConcurrentRequests, int queueSize) {
        if (maximumConcurrentRequests < 1) {
            throw new IllegalArgumentException("Maximum concurrent requests must be at least 1");
        }
        max = maximumConcurrentRequests;

        this.queue = new LinkedBlockingQueue<>(queueSize <= 0 ? Integer.MAX_VALUE : queueSize);
    }

    public void handleRequest(final HttpServerExchange exchange, final HttpHandler next) throws Exception {<FILL_FUNCTION_BODY>}

    /**
     * Get the maximum concurrent requests.
     *
     * @return the maximum concurrent requests
     */
    public int getMaximumConcurrentRequests() {
        return max;
    }

    /**
     * Set the maximum concurrent requests.  The value must be greater than or equal to one.
     *
     * @param newMax the maximum concurrent requests
     * @return max concurrent requests
     */
    public int setMaximumConcurrentRequests(int newMax) {
        if (newMax < 1) {
            throw new IllegalArgumentException("Maximum concurrent requests must be at least 1");
        }
        int oldMax = this.max;
        this.max = newMax;
        if(newMax > oldMax) {
            synchronized (this) {
                while (!queue.isEmpty()) {
                    int oldVal, newVal;
                    do {
                        oldVal = requests;
                        if (oldVal >= max) {
                            return oldMax;
                        }
                        newVal = oldVal + 1;
                    } while (!requestsUpdater.compareAndSet(this, oldVal, newVal));
                    SuspendedRequest res = queue.poll();
                    res.exchange.dispatch(res.next);
                }
            }
        }
        return oldMax;
    }

    private void decrementRequests() {
        requestsUpdater.decrementAndGet(this);
    }

    public HttpHandler getFailureHandler() {
        return failureHandler;
    }

    public void setFailureHandler(HttpHandler failureHandler) {
        this.failureHandler = failureHandler;
    }

    private static final class SuspendedRequest {
        final HttpServerExchange exchange;
        final HttpHandler next;

        private SuspendedRequest(HttpServerExchange exchange, HttpHandler next) {
            this.exchange = exchange;
            this.next = next;
        }
    }

}

        int oldVal, newVal;
        do {
            oldVal = requests;
            if (oldVal >= max) {
                exchange.dispatch(SameThreadExecutor.INSTANCE, new Runnable() {
                    @Override
                    public void run() {
                        //we have to try again in the sync block
                        //we need to have already dispatched for thread safety reasons
                        synchronized (this) {
                            int oldVal, newVal;
                            do {
                                oldVal = requests;
                                if (oldVal >= max) {
                                    if (!queue.offer(new SuspendedRequest(exchange, next))) {
                                        Connectors.executeRootHandler(failureHandler, exchange);
                                    }
                                    return;
                                }
                                newVal = oldVal + 1;
                            } while (!requestsUpdater.compareAndSet(RequestLimit.this, oldVal, newVal));
                            exchange.addExchangeCompleteListener(COMPLETION_LISTENER);
                            exchange.dispatch(next);
                        }
                    }
                });
                return;
            }
            newVal = oldVal + 1;
        } while (!requestsUpdater.compareAndSet(this, oldVal, newVal));
        exchange.addExchangeCompleteListener(COMPLETION_LISTENER);
        next.handleRequest(exchange);
    
<no_super_class>