/**
 * Copyright 2011 eBusiness Information, Groupe Excilys (www.excilys.com)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.excilys.ebi.gatling.recorder.http.channel;

import java.util.concurrent.Executors;

import org.jboss.netty.bootstrap.ClientBootstrap;
import org.jboss.netty.bootstrap.ServerBootstrap;
import org.jboss.netty.channel.ChannelFactory;
import org.jboss.netty.channel.ChannelHandler;
import org.jboss.netty.channel.ChannelPipeline;
import org.jboss.netty.channel.ChannelPipelineFactory;
import org.jboss.netty.channel.Channels;
import org.jboss.netty.channel.socket.nio.NioClientSocketChannelFactory;
import org.jboss.netty.handler.codec.http.HttpChunkAggregator;
import org.jboss.netty.handler.codec.http.HttpRequestDecoder;
import org.jboss.netty.handler.codec.http.HttpRequestEncoder;
import org.jboss.netty.handler.codec.http.HttpResponseDecoder;
import org.jboss.netty.handler.codec.http.HttpResponseEncoder;

public class BootstrapFactory {

	private static final BootstrapFactory INSTANCE = new BootstrapFactory();

	private static final int MAX_CONTENT_LENGTH = 1024 * 1024;

	private final ChannelFactory channelFactory = new NioClientSocketChannelFactory(Executors.newCachedThreadPool(), Executors.newCachedThreadPool());

	private final HttpRequestDecoder httpRequestDecoder = new HttpRequestDecoder();

	private final HttpResponseEncoder httpResponseEncoder = new HttpResponseEncoder();

	private final HttpRequestEncoder httpRequestEncoder = new HttpRequestEncoder();

	private final HttpResponseDecoder httpResponseDecoder = new HttpResponseDecoder();

	private BootstrapFactory() {
	}

	public static BootstrapFactory getBootstrapFactory() {
		return INSTANCE;
	}

	public ServerBootstrap newServerBootstrap(final ChannelHandler handler) {

		ServerBootstrap bootstrap = new ServerBootstrap(channelFactory);

		bootstrap.setPipelineFactory(new ChannelPipelineFactory() {
			@Override
			public ChannelPipeline getPipeline() throws Exception {
				return Channels.pipeline(httpRequestDecoder, httpResponseEncoder, handler);
			}
		});

		bootstrap.setOption("tcpNoDelay", true);
		bootstrap.setOption("keepAlive", true);

		return bootstrap;
	}

	public ClientBootstrap newClientBootstrap(final ChannelHandler handler) {
		ClientBootstrap bootstrap = new ClientBootstrap(channelFactory);
		bootstrap.setPipelineFactory(new ChannelPipelineFactory() {
			@Override
			public ChannelPipeline getPipeline() throws Exception {
				return Channels.pipeline(httpRequestEncoder, httpResponseDecoder, new HttpChunkAggregator(MAX_CONTENT_LENGTH), handler);
			}
		});
		return bootstrap;
	}
	
	public void releaseExternalResources() {
		channelFactory.releaseExternalResources();
	}
}

@@ -689,16 +689,61 @@
 annel;%0A%0A
+import java.util.concurrent.ExecutorService;%0A
 import j
@@ -1177,32 +1177,105 @@
 ChannelFactory;%0A
+import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;%0A
 import org.jboss
@@ -1741,16 +1741,94 @@
  1024;%0A%0A
+%09private final ExecutorService threadPool = Executors.newCachedThreadPool();%0A%0A
 %09private
@@ -1850,16 +1850,22 @@
 actory c
+lientC
 hannelFa
@@ -1910,61 +1910,21 @@
 ory(
-Executors.newCachedThreadPool(), Executors.newCachedT
+threadPool, t
 hrea
@@ -1928,18 +1928,16 @@
 readPool
-()
 );%0A%0A%09pri
@@ -1951,298 +1951,555 @@
 nal 
-HttpRequestDecoder httpRequestDecoder = new HttpRequestDecoder();%0A%0A%09private final HttpResponseEncoder httpResponseEncoder = new HttpResponseEncoder();%0A%0A%09private final HttpRequestEncoder httpRequestEncoder = new HttpRequestEncoder();%0A%0A%09private final HttpResponseDecoder httpResponseDe
+ChannelFactory serverChannelFactory = new NioServerSocketChannelFactory(threadPool, threadPool);%0A%0A%09private BootstrapFactory() %7B%0A%09%7D%0A%0A%09public static BootstrapFactory getBootstrapFactory() %7B%0A%09%09return INSTANCE;%0A%09%7D%0A%0A%09public ClientBootstrap newClientBootstrap(final ChannelHandler handler) %7B%0A%09%09ClientBootstrap bootstrap = new ClientBootstrap(clientChannelFactory);%0A%09%09bootstrap.setPipelineFactory(new ChannelPipelineFactory() %7B%0A%09%09%09@Override%0A%09%09%09public ChannelPipeline getPipeline() throws Exception %7B%0A%09%09%09%09return Channels.pipeline(new HttpRequestEn
 coder
- =
+(),
  new
@@ -2524,118 +2524,94 @@
 er()
-;%0A%0A%09private BootstrapFactory() %7B%0A%09%7D%0A%0A%09public static BootstrapFactory getBootstrapFactory() %7B%0A%09%09return INSTANCE
+, new HttpChunkAggregator(MAX_CONTENT_LENGTH), handler);%0A%09%09%09%7D%0A%09%09%7D);%0A%09%09return bootstrap
 ;%0A%09%7D
@@ -2730,33 +2730,39 @@
 ServerBootstrap(
-c
+serverC
 hannelFactory);%0A
@@ -2917,33 +2917,37 @@
 annels.pipeline(
-h
+new H
 ttpRequestDecode
@@ -2943,27 +2943,33 @@
 questDecoder
-, h
+(), new H
 ttpResponseE
@@ -2974,16 +2974,18 @@
 eEncoder
+()
 , handle
@@ -3122,450 +3122,65 @@
 lic 
-ClientBootstrap newClientBootstrap(final ChannelHandler handler) %7B%0A%09%09ClientBootstrap bootstrap = new ClientBootstrap(channelFactory);%0A%09%09bootstrap.setPipelineFactory(new ChannelPipelineFactory() %7B%0A%09%09%09@Override%0A%09%09%09public ChannelPipeline getPipeline() throws Exception %7B%0A%09%09%09%09return Channels.pipeline(httpRequestEncoder, httpResponseDecoder, new HttpChunkAggregator(MAX_CONTENT_LENGTH), handler);%0A%09%09%09%7D%0A%09%09%7D);%0A%09%09return bootstrap;%0A%09%7D%0A%09%0A%09public void 
+void releaseExternalResources() %7B%0A%09%09clientChannelFactory.
 rele
@@ -3201,22 +3201,27 @@
 ources()
- %7B%0A%09%09c
+;%0A%09%09serverC
 hannelFa

Fix ChannelFactories