class ResponseBodyInterceptor implements ResponseInterceptor {
    private static final Logger LOG = LoggerFactory.getLogger(ResponseBodyInterceptor.class);
    private final BodyConfig config;
    private volatile HttpHandler next;

    public ResponseBodyInterceptor() {
        if (LOG.isInfoEnabled())
            LOG.info("ResponseBodyInterceptor is loaded");

        this.config = BodyConfig.load();
    }

    @Override
    public HttpHandler getNext() {
        return next;
    }

    @Override
    public MiddlewareHandler setNext(HttpHandler next) {
        Handlers.handlerNotNull(next);
        this.next = next;
        return this;
    }

    @Override
    public boolean isEnabled() {
        return config.isEnabled();
    }

    @Override
    public void register() {
        ModuleRegistry.registerModule(BodyConfig.CONFIG_NAME, ResponseBodyInterceptor.class.getName(), Config.getNoneDecryptedInstance().getJsonMapConfigNoCache(BodyConfig.CONFIG_NAME), null);
    }

    @Override
    public void reload() {
        config.reload();
        ModuleRegistry.registerModule(BodyConfig.CONFIG_NAME, ResponseBodyInterceptor.class.getName(), Config.getNoneDecryptedInstance().getJsonMapConfigNoCache(BodyConfig.CONFIG_NAME), null);
        if (LOG.isInfoEnabled())
            LOG.info("ResponseBodyInterceptor is reloaded.");
    }

    @Override
    public boolean isRequiredContent() {
        return true;
    }

    @Override
    public void handleRequest(HttpServerExchange exchange) throws Exception {<FILL_FUNCTION_BODY>}

    private boolean handleBody(final HttpServerExchange ex, String body, String contentType) {
        if (this.isJsonData(contentType))
            return this.attachJsonBody(ex, body);

        else if (this.isXmlData(contentType))
            return this.attachXmlBody(ex, body);

        else if (this.isFormData(contentType))
            return this.attachFormDataBody(ex, body);

        else
            return false;
    }

    /**
     * Method used to parse the body into a Map or a List and attach it into exchange.
     *
     * @param ex - current exchange
     * @param str - byte buffer body as a string
     * @return - true if successful
     */
    private boolean attachJsonBody(final HttpServerExchange ex, String str) {
        str = str.trim();
        if(str.isEmpty()) {
            // if an empty string is passed in, we should not try to parse it. Just cache it.
            this.cacheResponseBody(ex, str);
            return true;
        }
        if (str.charAt(0) == JSON_MAP_OBJECT_STARTING_CHAR) {
            this.cacheResponseBody(ex, str);
            return this.parseJsonMapObject(ex, AttachmentConstants.REQUEST_BODY, str);

        } else if (str.charAt(0) == JSON_ARRAY_OBJECT_STARTING_CHAR) {
            this.cacheResponseBody(ex, str);
            return this.parseJsonArrayObject(ex, AttachmentConstants.REQUEST_BODY, str);
        }

        setExchangeStatus(ex, CONTENT_TYPE_MISMATCH, ContentType.APPLICATION_JSON.value());
        return false;
    }

    public boolean attachXmlBody(HttpServerExchange ex, String str) {
        this.cacheResponseBody(ex, str);
        return true;
    }

    public boolean attachFormDataBody(HttpServerExchange ex, String str) {
        this.cacheResponseBody(ex, str);
        return true;
    }

    private void cacheResponseBody(HttpServerExchange exchange, String s) {
        if (this.config.isCacheRequestBody())
            exchange.putAttachment(AttachmentConstants.RESPONSE_BODY_STRING, s);
    }

}


        if (LOG.isDebugEnabled())
            LOG.debug("ResponseBodyInterceptor.handleRequest starts.");

        if (this.shouldAttachBody(exchange.getResponseHeaders())) {

            var existing = this.getBuffer(exchange);

            if (existing != null) {

                if (LOG.isTraceEnabled())
                    LOG.trace("Attach response body requirement is met and the byte buffer pool exists.");

                var completeBody = BuffersUtils.toString(existing, StandardCharsets.UTF_8);
                var contentType = exchange.getResponseHeaders().getFirst(Headers.CONTENT_TYPE);

                if (LOG.isTraceEnabled()) {
                    if(config.isLogFullResponseBody())
                        LOG.trace("contentType = " + contentType + " response body = " + completeBody);
                    else
                        LOG.trace("contentType = " + contentType + " response body = " + (completeBody.length() > 16384 ? completeBody.substring(0, 16384) : completeBody));
                }
                boolean attached = this.handleBody(exchange, completeBody, contentType);

                if (!attached && LOG.isErrorEnabled())
                    LOG.error("Failed to attach the request body to the exchange!");
            }
        }

        if (LOG.isDebugEnabled())
            LOG.debug("ResponseBodyInterceptor.handleRequest ends.");
    
<no_super_class>