// Path: jsonp-policy/src/main/java/io/apiman/plugins/jsonp_policy/beans/JsonpConfigBean.java
// public class JsonpConfigBean {
// 
// 	@JsonProperty
//     private String callbackParamName;
// 
//     /**
//      * @return the parameter name used to specify the callback function 
//      */
//     public String getCallbackParamName() {
//         return callbackParamName;
//     }
// 
//     /**
//      * @param callbackParamName the parameter name used to specify the callback function
//      */
//     public void setCallbackParamName(String callbackParamName) {
//         this.callbackParamName = callbackParamName;
//     }
// }
// 
// Path: jsonp-policy/src/main/java/io/apiman/plugins/jsonp_policy/http/HttpHeaders.java
// public class HttpHeaders {
// 
//     private static final String CONTENT_TYPE = "Content-Type"; //$NON-NLS-1$
//     private static final String CONTENT_LENGTH = "Content-Length"; //$NON-NLS-1$
// 
//     private final HeaderMap headers;
// 
//     /**
//      * Constructor.
//      *
//      * @param headers headers map
//      */
//     public HttpHeaders(HeaderMap headers) {
//         this.headers = headers;
//     }
// 
//     /**
//      * Extract the charset from the Content-Type header. When not present, the default charset is returned.
//      *
//      * @param defaultCharset the default charset
//      * @return charset
//      */
//     public String getCharsetFromContentType(String defaultCharset) {
//         String charset = null;
//         String contentTypeStr = headers.get(CONTENT_TYPE);
//         if (contentTypeStr != null) {
//             charset = new ContentType(contentTypeStr).getCharset();
//         }
//         return charset != null ? charset : defaultCharset;
//     }
// 
//     /**
//      * Set the type/subtype value of the Content-Type header.
//      *
//      * @param typeSubtype the type/subtype value
//      */
//     public void setContentType(String typeSubtype) {
//         String contentTypeStr = headers.get(CONTENT_TYPE);
//         if (contentTypeStr != null) {
//             ContentType contentType = new ContentType(contentTypeStr);
//             contentType.setTypeSubtype(typeSubtype);
//             headers.put(CONTENT_TYPE, contentType.toString());
//         } else {
//             headers.put(CONTENT_TYPE, typeSubtype);
//         }
//     }
// 
//     /**
//      * @param additionalContentLength the additional content length
//      */
//     public void incrementContentLength(int additionalContentLength) {
//         String cl = headers.get(CONTENT_LENGTH);
//         if (cl != null && cl.length() > 0) {
//             int clength = new Integer(cl).intValue();
//             headers.put(CONTENT_LENGTH, String.valueOf(clength + additionalContentLength));
//         }
//     }
// 
// }


import io.apiman.gateway.engine.beans.ApiRequest;
import io.apiman.gateway.engine.beans.ApiResponse;
import io.apiman.gateway.engine.components.IBufferFactoryComponent;
import io.apiman.gateway.engine.io.AbstractStream;
import io.apiman.gateway.engine.io.IApimanBuffer;
import io.apiman.gateway.engine.io.IReadWriteStream;
import io.apiman.gateway.engine.policies.AbstractMappedPolicy;
import io.apiman.gateway.engine.policy.IDataPolicy;
import io.apiman.gateway.engine.policy.IPolicyChain;
import io.apiman.gateway.engine.policy.IPolicyContext;
import io.apiman.plugins.jsonp_policy.beans.JsonpConfigBean;
import io.apiman.plugins.jsonp_policy.http.HttpHeaders;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
    @Override
    protected void doApply(ApiRequest request, IPolicyContext context, JsonpConfigBean config,
            IPolicyChain<ApiRequest> chain) {
        String callbackParamName = config.getCallbackParamName();
        String callbackFunctionName = request.getQueryParams().get(callbackParamName);
        request.getQueryParams().remove(callbackParamName);
        if (callbackFunctionName != null) {
            context.setAttribute(CALLBACK_FUNCTION_NAME, callbackFunctionName);
        }
        super.doApply(request, context, config, chain);
    }

    /**
     * @see io.apiman.gateway.engine.policy.IDataPolicy#getRequestDataHandler(io.apiman.gateway.engine.beans.ApiRequest, io.apiman.gateway.engine.policy.IPolicyContext, java.lang.Object)
     */
    @Override
    public IReadWriteStream<ApiRequest> getRequestDataHandler(ApiRequest request,
            IPolicyContext context, Object policyConfiguration) {
        return null;
    }

    /**
     * @see io.apiman.gateway.engine.policy.IDataPolicy#getResponseDataHandler(io.apiman.gateway.engine.beans.ApiResponse, io.apiman.gateway.engine.policy.IPolicyContext, java.lang.Object)
     */
    @Override
    public IReadWriteStream<ApiResponse> getResponseDataHandler(final ApiResponse response,
            IPolicyContext context, Object policyConfiguration) {
        final String callbackFunctionName = (String) context.getAttribute(CALLBACK_FUNCTION_NAME, null);

        if (callbackFunctionName != null) {
// Path: jsonp-policy/src/main/java/io/apiman/plugins/jsonp_policy/beans/JsonpConfigBean.java
// public class JsonpConfigBean {
// 
// 	@JsonProperty
//     private String callbackParamName;
// 
//     /**
//      * @return the parameter name used to specify the callback function 
//      */
//     public String getCallbackParamName() {
//         return callbackParamName;
//     }
// 
//     /**
//      * @param callbackParamName the parameter name used to specify the callback function
//      */
//     public void setCallbackParamName(String callbackParamName) {
//         this.callbackParamName = callbackParamName;
//     }
// }
// 
// Path: jsonp-policy/src/main/java/io/apiman/plugins/jsonp_policy/http/HttpHeaders.java
// public class HttpHeaders {
// 
//     private static final String CONTENT_TYPE = "Content-Type"; //$NON-NLS-1$
//     private static final String CONTENT_LENGTH = "Content-Length"; //$NON-NLS-1$
// 
//     private final HeaderMap headers;
// 
//     /**
//      * Constructor.
//      *
//      * @param headers headers map
//      */
//     public HttpHeaders(HeaderMap headers) {
//         this.headers = headers;
//     }
// 
//     /**
//      * Extract the charset from the Content-Type header. When not present, the default charset is returned.
//      *
//      * @param defaultCharset the default charset
//      * @return charset
//      */
//     public String getCharsetFromContentType(String defaultCharset) {
//         String charset = null;
//         String contentTypeStr = headers.get(CONTENT_TYPE);
//         if (contentTypeStr != null) {
//             charset = new ContentType(contentTypeStr).getCharset();
//         }
//         return charset != null ? charset : defaultCharset;
//     }
// 
//     /**
//      * Set the type/subtype value of the Content-Type header.
//      *
//      * @param typeSubtype the type/subtype value
//      */
//     public void setContentType(String typeSubtype) {
//         String contentTypeStr = headers.get(CONTENT_TYPE);
//         if (contentTypeStr != null) {
//             ContentType contentType = new ContentType(contentTypeStr);
//             contentType.setTypeSubtype(typeSubtype);
//             headers.put(CONTENT_TYPE, contentType.toString());
//         } else {
//             headers.put(CONTENT_TYPE, typeSubtype);
//         }
//     }
// 
//     /**
//      * @param additionalContentLength the additional content length
//      */
//     public void incrementContentLength(int additionalContentLength) {
//         String cl = headers.get(CONTENT_LENGTH);
//         if (cl != null && cl.length() > 0) {
//             int clength = new Integer(cl).intValue();
//             headers.put(CONTENT_LENGTH, String.valueOf(clength + additionalContentLength));
//         }
//     }
// 
// }


// Path: jsonp-policy/src/main/java/io/apiman/plugins/jsonp_policy/JsonpPolicy.java
import io.apiman.gateway.engine.beans.ApiRequest;
import io.apiman.gateway.engine.beans.ApiResponse;
import io.apiman.gateway.engine.components.IBufferFactoryComponent;
import io.apiman.gateway.engine.io.AbstractStream;
import io.apiman.gateway.engine.io.IApimanBuffer;
import io.apiman.gateway.engine.io.IReadWriteStream;
import io.apiman.gateway.engine.policies.AbstractMappedPolicy;
import io.apiman.gateway.engine.policy.IDataPolicy;
import io.apiman.gateway.engine.policy.IPolicyChain;
import io.apiman.gateway.engine.policy.IPolicyContext;
import io.apiman.plugins.jsonp_policy.beans.JsonpConfigBean;
import io.apiman.plugins.jsonp_policy.http.HttpHeaders;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;

    @Override
    protected void doApply(ApiRequest request, IPolicyContext context, JsonpConfigBean config,
            IPolicyChain<ApiRequest> chain) {
        String callbackParamName = config.getCallbackParamName();
        String callbackFunctionName = request.getQueryParams().get(callbackParamName);
        request.getQueryParams().remove(callbackParamName);
        if (callbackFunctionName != null) {
            context.setAttribute(CALLBACK_FUNCTION_NAME, callbackFunctionName);
        }
        super.doApply(request, context, config, chain);
    }

    /**
     * @see io.apiman.gateway.engine.policy.IDataPolicy#getRequestDataHandler(io.apiman.gateway.engine.beans.ApiRequest, io.apiman.gateway.engine.policy.IPolicyContext, java.lang.Object)
     */
    @Override
    public IReadWriteStream<ApiRequest> getRequestDataHandler(ApiRequest request,
            IPolicyContext context, Object policyConfiguration) {
        return null;
    }

    /**
     * @see io.apiman.gateway.engine.policy.IDataPolicy#getResponseDataHandler(io.apiman.gateway.engine.beans.ApiResponse, io.apiman.gateway.engine.policy.IPolicyContext, java.lang.Object)
     */
    @Override
    public IReadWriteStream<ApiResponse> getResponseDataHandler(final ApiResponse response,
            IPolicyContext context, Object policyConfiguration) {
        final String callbackFunctionName = (String) context.getAttribute(CALLBACK_FUNCTION_NAME, null);

        if (callbackFunctionName != null) {
            HttpHeaders httpHeaders = new HttpHeaders(response.getHeaders());