// Path: zuul-core/src/main/java/com/netflix/zuul/netty/filter/FiltersListener.java
// public interface FiltersListener extends EventListener {
// 
//     /**
//      * @param filterPath
//      * @param filter
//      */
//     void filterAdded(Path filterPath, ZuulFilter filter);
// 
// 
//     /**
//      *
//      * @param filterPath
//      * @param filter
//      */
//     void filterRemoved(Path filterPath, ZuulFilter filter);
// 
// }
// 
// Path: zuul-core/src/main/java/com/netflix/zuul/netty/filter/ZuulFilter.java
// public interface ZuulFilter extends Ordered, Comparable<ZuulFilter> {
// 
//     /**
//      * @return
//      */
//     String type();
// 
// }
// 
// Path: zuul-core/src/main/java/com/netflix/zuul/netty/filter/ZuulPostFilter.java
// public interface ZuulPostFilter extends ZuulFilter, HttpResponseHandler {
// 
//     boolean shouldFilter(FrameworkHttpRequest request, FrameworkHttpResponse response);
// 
// }


import com.netflix.zuul.netty.filter.FiltersListener;
import com.netflix.zuul.netty.filter.ZuulFilter;
import com.netflix.zuul.netty.filter.ZuulPostFilter;
import com.netflix.zuul.netty.filter.ZuulPreFilter;
import com.netflix.zuul.proxy.core.CommonsConnectionPool;
import com.netflix.zuul.proxy.core.ConnectionPool;
import com.netflix.zuul.proxy.framework.plugins.LoggingResponseHandler;
import com.netflix.zuul.proxy.handler.*;
import org.jboss.netty.channel.*;
import org.jboss.netty.channel.socket.nio.NioClientSocketChannelFactory;
import org.jboss.netty.handler.codec.http.HttpContentCompressor;
import org.jboss.netty.handler.codec.http.HttpRequestDecoder;
import org.jboss.netty.handler.codec.http.HttpResponseEncoder;
import org.jboss.netty.handler.execution.ExecutionHandler;
import org.jboss.netty.handler.execution.OrderedMemoryAwareThreadPoolExecutor;
import org.jboss.netty.handler.timeout.IdleStateHandler;
import org.jboss.netty.util.Timer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.nio.file.Path;
import java.util.Map;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ConcurrentSkipListMap;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
        //response handlers
        addZuulPostFilters(pipeline, postFilters);

        pipeline.addLast("app-http-response-logger", HTTP_RESPONSE_LOGGER);

        //request handlers
        addZuulPreFilters(pipeline, preFilters);

        //proxy
        pipeline.addLast("proxy", new HttpProxyHandler(outboundConnectionPool, IS_REQUEST_CHUNKED_ENABLED));

        return pipeline;
    }

    private void addZuulPostFilters(ChannelPipeline pipeline, ConcurrentMap<ZuulPostFilter, Path> filters) {
        for (Map.Entry<ZuulPostFilter, Path> entry : filters.entrySet()) {
            String name = entry.getValue().toString();
            pipeline.addLast(name, new HttpResponseFrameworkHandler(name, entry.getKey()));
        }

    }

    private void addZuulPreFilters(ChannelPipeline pipeline, ConcurrentMap<ZuulPreFilter, Path> filters) {
        for (Map.Entry<ZuulPreFilter, Path> entry : filters.entrySet()) {
            String name = entry.getValue().toString();
            pipeline.addLast(name, new HttpRequestFrameworkHandler(name, entry.getKey()));
        }
    }

    @Override
// Path: zuul-core/src/main/java/com/netflix/zuul/netty/filter/FiltersListener.java
// public interface FiltersListener extends EventListener {
// 
//     /**
//      * @param filterPath
//      * @param filter
//      */
//     void filterAdded(Path filterPath, ZuulFilter filter);
// 
// 
//     /**
//      *
//      * @param filterPath
//      * @param filter
//      */
//     void filterRemoved(Path filterPath, ZuulFilter filter);
// 
// }
// 
// Path: zuul-core/src/main/java/com/netflix/zuul/netty/filter/ZuulFilter.java
// public interface ZuulFilter extends Ordered, Comparable<ZuulFilter> {
// 
//     /**
//      * @return
//      */
//     String type();
// 
// }
// 
// Path: zuul-core/src/main/java/com/netflix/zuul/netty/filter/ZuulPostFilter.java
// public interface ZuulPostFilter extends ZuulFilter, HttpResponseHandler {
// 
//     boolean shouldFilter(FrameworkHttpRequest request, FrameworkHttpResponse response);
// 
// }


// Path: netty-server/src/main/java/com/netflix/zuul/proxy/CommonHttpPipeline.java
import com.netflix.zuul.netty.filter.FiltersListener;
import com.netflix.zuul.netty.filter.ZuulFilter;
import com.netflix.zuul.netty.filter.ZuulPostFilter;
import com.netflix.zuul.netty.filter.ZuulPreFilter;
import com.netflix.zuul.proxy.core.CommonsConnectionPool;
import com.netflix.zuul.proxy.core.ConnectionPool;
import com.netflix.zuul.proxy.framework.plugins.LoggingResponseHandler;
import com.netflix.zuul.proxy.handler.*;
import org.jboss.netty.channel.*;
import org.jboss.netty.channel.socket.nio.NioClientSocketChannelFactory;
import org.jboss.netty.handler.codec.http.HttpContentCompressor;
import org.jboss.netty.handler.codec.http.HttpRequestDecoder;
import org.jboss.netty.handler.codec.http.HttpResponseEncoder;
import org.jboss.netty.handler.execution.ExecutionHandler;
import org.jboss.netty.handler.execution.OrderedMemoryAwareThreadPoolExecutor;
import org.jboss.netty.handler.timeout.IdleStateHandler;
import org.jboss.netty.util.Timer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.nio.file.Path;
import java.util.Map;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ConcurrentSkipListMap;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

        //response handlers
        addZuulPostFilters(pipeline, postFilters);

        pipeline.addLast("app-http-response-logger", HTTP_RESPONSE_LOGGER);

        //request handlers
        addZuulPreFilters(pipeline, preFilters);

        //proxy
        pipeline.addLast("proxy", new HttpProxyHandler(outboundConnectionPool, IS_REQUEST_CHUNKED_ENABLED));

        return pipeline;
    }

    private void addZuulPostFilters(ChannelPipeline pipeline, ConcurrentMap<ZuulPostFilter, Path> filters) {
        for (Map.Entry<ZuulPostFilter, Path> entry : filters.entrySet()) {
            String name = entry.getValue().toString();
            pipeline.addLast(name, new HttpResponseFrameworkHandler(name, entry.getKey()));
        }

    }

    private void addZuulPreFilters(ChannelPipeline pipeline, ConcurrentMap<ZuulPreFilter, Path> filters) {
        for (Map.Entry<ZuulPreFilter, Path> entry : filters.entrySet()) {
            String name = entry.getValue().toString();
            pipeline.addLast(name, new HttpRequestFrameworkHandler(name, entry.getKey()));
        }
    }

    @Override
    public void filterAdded(Path filterPath, ZuulFilter filter) {