@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());
            final String encoding = httpHeaders.getCharsetFromContentType(StandardCharsets.UTF_8.name());
            final int additionalContentLength = callbackFunctionName.length()
                    + OPEN_PARENTHESES.length() + CLOSE_PARENTHESES.length();

            // JSONP responses should have the Content-Type header set to "application/javascript"
            httpHeaders.setContentType(APPLICATION_JAVASCRIPT);

            // the Content-Length will need to be longer
            httpHeaders.incrementContentLength(additionalContentLength);

            final IBufferFactoryComponent bufferFactory = context.getComponent(IBufferFactoryComponent.class);

            return new AbstractStream<ApiResponse>() {
                private boolean firstChunk = true;

                @Override
                public ApiResponse getHead() {
                    return response;
                }

                @Override
                protected void handleHead(ApiResponse head) {
                }

                @Override
                public void write(IApimanBuffer chunk) {
                    if (firstChunk) {
                        IApimanBuffer buffer = bufferFactory.createBuffer(callbackFunctionName.length()
                                + OPEN_PARENTHESES.length());
                        try {
                            buffer.append(callbackFunctionName, encoding);
                            buffer.append(OPEN_PARENTHESES, encoding);
                        } catch (UnsupportedEncodingException e) {
                            // TODO Review the exception handling. A better approach might be throwing an IOException.
                            throw new RuntimeException(e);
                        }
                        // Write callbackFunctionName(
                        super.write(buffer);
                        firstChunk = false;
                    }
                    super.write(chunk);
                }

                @Override
                public void end() {
                    // Write close parenth ) on end if something has been written
                    if (!firstChunk) {
                        IApimanBuffer buffer = bufferFactory.createBuffer(CLOSE_PARENTHESES.length());
                        try {
                            buffer.append(CLOSE_PARENTHESES, encoding);
                        } catch (UnsupportedEncodingException e) {
                            // TODO Review the exception handling. A better approach might be throwing an IOException.
                            throw new RuntimeException(e);
                        }
                        super.write(buffer);
                    }
                    super.end();
                }
            };
        }
        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)
plugins/jsonp-policy/src/main/java/io/apiman/plugins/jsonp_policy/JsonpPolicy.java