[httpcomponents-core] 01/01: Imported Upstream version 4.3

Emmanuel Bourg ebourg-guest at alioth.debian.org
Mon Aug 5 16:53:37 UTC 2013


This is an automated email from the git hooks/post-receive script.

ebourg-guest pushed a commit to annotated tag upstream/4.3
in repository httpcomponents-core.

commit 89519e14516363e50adce02126da6c77b59d0063
Author: Emmanuel Bourg <ebourg at apache.org>
Date:   Mon Aug 5 18:29:15 2013 +0200

    Imported Upstream version 4.3
---
 BUILDING.txt                                       |   39 +-
 LICENSE.txt                                        |    5 +-
 RELEASE_NOTES.txt                                  |  281 +++--
 httpcore-ab/pom.xml                                |   35 +-
 .../apache/http/benchmark/BenchmarkConnection.java |   49 +-
 .../org/apache/http/benchmark/BenchmarkWorker.java |  135 +--
 .../apache/http/benchmark/CommandLineUtils.java    |   70 +-
 .../java/org/apache/http/benchmark/Config.java     |   73 +-
 .../apache/http/benchmark/CountingInputStream.java |   18 +-
 .../http/benchmark/CountingOutputStream.java       |   10 +-
 .../org/apache/http/benchmark/HttpBenchmark.java   |  124 +--
 .../org/apache/http/benchmark/ResultProcessor.java |   97 +-
 .../java/org/apache/http/benchmark/Results.java    |  133 +++
 .../main/java/org/apache/http/benchmark/Stats.java |    6 +-
 .../org/apache/http/benchmark}/HttpServer.java     |   81 +-
 .../java/org/apache/http/benchmark/SmokeTest.java  |   90 ++
 httpcore-benchmark/pom.xml                         |  129 ---
 .../java/org/apache/http/benchmark/Benchmark.java  |   96 --
 .../http/benchmark/httpcore/HttpCoreNIOServer.java |  141 ---
 .../http/benchmark/httpcore/HttpCoreServer.java    |  154 ---
 .../http/benchmark/httpcore/HttpListener.java      |  104 --
 .../apache/http/benchmark/httpcore/HttpWorker.java |   97 --
 .../http/benchmark/httpcore/NHttpListener.java     |   80 --
 .../benchmark/httpcore/NRandomDataHandler.java     |  204 ----
 .../http/benchmark/httpcore/RandomDataHandler.java |  132 ---
 .../benchmark/httpcore/StdHttpWorkerCallback.java  |   67 --
 .../http/benchmark/jetty/JettyNIOServer.java       |  104 --
 .../apache/http/benchmark/jetty/JettyServer.java   |  104 --
 .../http/benchmark/jetty/RandomDataHandler.java    |   95 --
 .../httpcore-tutorial-simplified-chinese.pdf       |  Bin 851769 -> 0 bytes
 httpcore-contrib/pom.xml                           |   87 --
 .../contrib/compress/GzipCompressingEntity.java    |   86 --
 .../contrib/compress/GzipDecompressingEntity.java  |   65 --
 .../contrib/compress/ResponseGzipCompress.java     |   73 --
 .../contrib/compress/ResponseGzipUncompress.java   |   70 --
 .../http/contrib/logging/LoggingIOSession.java     |  234 ----
 .../LoggingNHttpClientConnectionFactory.java       |   62 --
 .../contrib/logging/LoggingNHttpClientHandler.java |  139 ---
 .../LoggingNHttpServerConnectionFactory.java       |   62 --
 .../logging/LoggingNHttpServiceHandler.java        |  138 ---
 .../http/contrib/sip/BasicCompactHeader.java       |  114 --
 .../http/contrib/sip/BasicCompactHeaderMapper.java |  208 ----
 .../http/contrib/sip/BasicSipLineParser.java       |   77 --
 .../http/contrib/sip/BufferedCompactHeader.java    |  166 ---
 .../org/apache/http/contrib/sip/CompactHeader.java |   60 -
 .../http/contrib/sip/CompactHeaderMapper.java      |   95 --
 .../contrib/sip/EnglishSipReasonPhraseCatalog.java |  266 -----
 .../org/apache/http/contrib/sip/SipException.java  |   73 --
 .../org/apache/http/contrib/sip/SipStatus.java     |  267 -----
 .../org/apache/http/contrib/sip/SipVersion.java    |   89 --
 httpcore-nio/pom.xml                               |   58 +-
 .../org/apache/http/examples/nio/NHttpClient.java  |   43 +-
 .../http/examples/nio/NHttpReverseProxy.java       |   70 +-
 .../org/apache/http/examples/nio/NHttpServer.java  |   61 +-
 .../impl/nio/DefaultClientIOEventDispatch.java     |   40 +-
 .../impl/nio/DefaultServerIOEventDispatch.java     |   36 +-
 .../http/impl/nio/SSLClientIOEventDispatch.java    |   56 +-
 .../http/impl/nio/SSLServerIOEventDispatch.java    |   54 +-
 .../http/impl/nio/codecs/HttpRequestParser.java    |   16 +-
 .../http/impl/nio/codecs/HttpRequestWriter.java    |    4 +-
 .../http/impl/nio/codecs/HttpResponseParser.java   |   16 +-
 .../http/impl/nio/codecs/HttpResponseWriter.java   |    4 +-
 .../apache/http/impl/nio/reactor/SSLIOSession.java |    2 +-
 .../http/impl/nio/reactor/SSLIOSessionHandler.java |    0
 .../nio/reactor/SSLIOSessionHandlerAdaptor.java    |    0
 .../org/apache/http/impl/nio/reactor/SSLMode.java  |    2 +-
 .../http/impl/nio/reactor/SSLSetupHandler.java     |    0
 .../impl/nio/reactor/SSLSetupHandlerAdaptor.java   |    0
 .../http/impl/nio/reactor/SessionHandle.java       |   13 +-
 .../impl/nio/ssl/SSLClientIOEventDispatch.java     |   37 +-
 .../impl/nio/ssl/SSLServerIOEventDispatch.java     |   35 +-
 .../org/apache/http/impl/nio/ssl/package.html      |    0
 .../http/nio/params/NIOReactorParamBean.java       |    7 +-
 .../apache/http/nio/params/NIOReactorParams.java   |   44 +-
 .../http/nio/protocol/AsyncNHttpClientHandler.java |   83 +-
 .../nio/protocol/AsyncNHttpServiceHandler.java     |  131 ++-
 .../BasicAsyncRequestExecutionHandler.java         |   50 +-
 .../nio/protocol/BufferingHttpClientHandler.java   |   13 +-
 .../nio/protocol/BufferingHttpServiceHandler.java  |   17 +-
 .../apache/http/nio/protocol/EventListener.java    |    0
 .../protocol/HttpAsyncRequestExecutionHandler.java |    3 +
 .../protocol/HttpAsyncRequestHandlerRegistry.java  |    6 +-
 .../nio/protocol/HttpRequestExecutionHandler.java  |    3 +-
 .../apache/http/nio/protocol/NHttpHandlerBase.java |   27 +-
 .../nio/protocol/NHttpRequestExecutionHandler.java |    6 +-
 .../http/nio/protocol/NHttpRequestHandler.java     |    0
 .../nio/protocol/NHttpRequestHandlerRegistry.java  |    4 +-
 .../nio/protocol/NHttpRequestHandlerResolver.java  |    0
 .../http/nio/protocol/NHttpResponseTrigger.java    |    0
 .../apache/http/nio/protocol/NullNHttpEntity.java  |    7 +-
 .../nio/protocol/SimpleNHttpRequestHandler.java    |    0
 .../nio/protocol/ThrottlingHttpClientHandler.java  |  109 +-
 .../nio/protocol/ThrottlingHttpServiceHandler.java |  123 +--
 .../http/impl/nio/DefaultHttpClientIODispatch.java |   70 +-
 .../http/impl/nio/DefaultHttpServerIODispatch.java |   68 +-
 .../impl/nio/DefaultNHttpClientConnection.java     |  181 +++-
 .../nio/DefaultNHttpClientConnectionFactory.java   |  143 ++-
 .../impl/nio/DefaultNHttpServerConnection.java     |  191 +++-
 .../nio/DefaultNHttpServerConnectionFactory.java   |  130 ++-
 .../impl/nio/NHttpClientEventHandlerAdaptor.java   |    2 +-
 .../apache/http/impl/nio/NHttpConnectionBase.java  |  183 +++-
 .../org/apache/http/impl/nio/SSLContextUtils.java} |   34 +-
 .../impl/nio/SSLNHttpClientConnectionFactory.java  |  197 +++-
 .../impl/nio/SSLNHttpServerConnectionFactory.java  |  196 +++-
 .../impl/nio/codecs/AbstractContentDecoder.java    |   75 +-
 .../impl/nio/codecs/AbstractContentEncoder.java    |  113 +-
 .../impl/nio/codecs/AbstractMessageParser.java     |  108 +-
 .../impl/nio/codecs/AbstractMessageWriter.java     |   42 +-
 .../apache/http/impl/nio/codecs/ChunkDecoder.java  |   44 +-
 .../apache/http/impl/nio/codecs/ChunkEncoder.java  |  109 +-
 .../impl/nio/codecs/DefaultHttpRequestParser.java  |   73 +-
 ...r.java => DefaultHttpRequestParserFactory.java} |   59 +-
 .../impl/nio/codecs/DefaultHttpRequestWriter.java  |   34 +-
 ...r.java => DefaultHttpRequestWriterFactory.java} |   38 +-
 .../impl/nio/codecs/DefaultHttpResponseParser.java |   68 +-
 .../codecs/DefaultHttpResponseParserFactory.java   |   71 ++
 .../impl/nio/codecs/DefaultHttpResponseWriter.java |   34 +-
 ....java => DefaultHttpResponseWriterFactory.java} |   38 +-
 .../http/impl/nio/codecs/IdentityDecoder.java      |   20 +-
 .../http/impl/nio/codecs/IdentityEncoder.java      |   72 +-
 .../impl/nio/codecs/LengthDelimitedDecoder.java    |   47 +-
 .../impl/nio/codecs/LengthDelimitedEncoder.java    |  119 +-
 .../http/impl/nio/pool/BasicNIOConnFactory.java    |   73 +-
 .../http/impl/nio/pool/BasicNIOConnPool.java       |  139 ++-
 .../http/impl/nio/pool/BasicNIOPoolEntry.java      |   12 +-
 .../http/impl/nio/reactor/AbstractIODispatch.java  |   31 +-
 .../http/impl/nio/reactor/AbstractIOReactor.java   |  121 +--
 .../nio/reactor/AbstractMultiworkerIOReactor.java  |  143 +--
 .../http/impl/nio/reactor/BaseIOReactor.java       |   54 +-
 .../apache/http/impl/nio/reactor/ChannelEntry.java |    5 +-
 .../nio/reactor/DefaultConnectingIOReactor.java    |   75 +-
 .../nio/reactor/DefaultListeningIOReactor.java     |   63 +-
 .../http/impl/nio/reactor/ExceptionEvent.java      |    2 +-
 .../http/impl/nio/reactor/IOReactorConfig.java     |  297 +++--
 .../http/impl/nio/reactor/IOSessionImpl.java       |   53 +-
 .../http/impl/nio/reactor/InterestOpEntry.java     |   20 +-
 .../impl/nio/reactor/ListenerEndpointImpl.java     |   13 +-
 .../impl/nio/reactor/SessionInputBufferImpl.java   |  225 ++--
 .../impl/nio/reactor/SessionOutputBufferImpl.java  |  207 +++-
 .../impl/nio/reactor/SessionRequestHandle.java     |   10 +-
 .../http/impl/nio/reactor/SessionRequestImpl.java  |   31 +-
 .../org/apache/http/nio/ContentDecoderChannel.java |    4 +-
 .../org/apache/http/nio/ContentEncoderChannel.java |    6 +-
 .../org/apache/http/nio/FileContentEncoder.java    |    1 -
 .../org/apache/http/nio/NHttpClientIOTarget.java   |    6 +-
 .../apache/http/nio/NHttpMessageParserFactory.java |   20 +-
 .../apache/http/nio/NHttpMessageWriterFactory.java |   13 +-
 .../org/apache/http/nio/NHttpServerIOTarget.java   |    6 +-
 .../http/nio/entity/BufferingNHttpEntity.java      |   28 +-
 .../http/nio/entity/ConsumingNHttpEntity.java      |    6 +-
 .../nio/entity/ConsumingNHttpEntityTemplate.java   |   19 +-
 .../http/nio/entity/ContentBufferEntity.java       |    7 +-
 .../apache/http/nio/entity/ContentInputStream.java |    9 +-
 .../apache/http/nio/entity/ContentListener.java    |    2 +-
 .../http/nio/entity/ContentOutputStream.java       |   11 +-
 .../nio/entity/EntityAsyncContentProducer.java     |   16 +-
 .../apache/http/nio/entity/NByteArrayEntity.java   |   18 +-
 .../org/apache/http/nio/entity/NFileEntity.java    |   46 +-
 .../apache/http/nio/entity/NHttpEntityWrapper.java |   19 +-
 .../org/apache/http/nio/entity/NStringEntity.java  |   19 +-
 .../http/nio/entity/ProducingNHttpEntity.java      |    6 +-
 .../http/nio/entity/SkipContentListener.java       |    5 +-
 .../java/org/apache/http/nio/entity/package.html   |    2 +-
 .../apache/http/nio/params/NIOReactorPNames.java   |    4 +-
 .../apache/http/nio/pool/AbstractNIOConnPool.java  |  573 ++++++----
 .../org/apache/http/nio/pool/LeaseRequest.java     |   45 +-
 .../apache/http/nio/pool/RouteSpecificPool.java    |   53 +-
 .../http/nio/pool/SocketAddressResolver.java       |   21 +-
 .../nio/protocol/AbstractAsyncRequestConsumer.java |   15 +-
 .../protocol/AbstractAsyncResponseConsumer.java    |   17 +-
 ...r.java => BasicAsyncClientExchangeHandler.java} |  185 ++--
 .../nio/protocol/BasicAsyncRequestConsumer.java    |    5 +-
 .../nio/protocol/BasicAsyncRequestHandler.java     |    5 +-
 .../nio/protocol/BasicAsyncRequestProducer.java    |   23 +-
 .../nio/protocol/BasicAsyncResponseConsumer.java   |    5 +-
 .../nio/protocol/BasicAsyncResponseProducer.java   |   15 +-
 ...er.java => HttpAsyncClientExchangeHandler.java} |  100 +-
 .../http/nio/protocol/HttpAsyncExchange.java       |    9 +-
 .../nio/protocol/HttpAsyncRequestConsumer.java     |    5 +-
 .../nio/protocol/HttpAsyncRequestExecutor.java     |  194 ++--
 ...ver.java => HttpAsyncRequestHandlerMapper.java} |   19 +-
 .../protocol/HttpAsyncRequestHandlerResolver.java  |    6 +-
 .../nio/protocol/HttpAsyncRequestProducer.java     |    8 +-
 .../http/nio/protocol/HttpAsyncRequester.java      |  150 ++-
 .../nio/protocol/HttpAsyncResponseProducer.java    |    3 -
 .../apache/http/nio/protocol/HttpAsyncService.java |  289 ++---
 .../http/nio/protocol/NullRequestConsumer.java     |    2 +-
 .../http/nio/protocol/NullRequestHandler.java      |    2 +-
 ....java => UriHttpAsyncRequestHandlerMapper.java} |   54 +-
 .../apache/http/nio/reactor/IOReactorStatus.java   |    2 +-
 .../org/apache/http/nio/reactor/IOSession.java     |    2 -
 .../http/nio/reactor/ListeningIOReactor.java       |    2 +-
 .../http/nio/reactor/SessionBufferStatus.java      |    3 -
 .../http/nio/reactor/SessionInputBuffer.java       |    4 +-
 .../apache/http/nio/reactor/SocketAccessor.java    |    2 +-
 .../apache/http/nio/reactor/ssl/SSLIOSession.java  |  109 +-
 .../apache/http/nio/util/ContentInputBuffer.java   |    5 +-
 .../apache/http/nio/util/ContentOutputBuffer.java  |    5 +-
 .../http/nio/util/DirectByteBufferAllocator.java   |    8 +-
 .../org/apache/http/nio/util/ExpandableBuffer.java |   19 +-
 .../http/nio/util/HeapByteBufferAllocator.java     |    8 +-
 .../apache/http/nio/util/SharedInputBuffer.java    |   53 +-
 .../apache/http/nio/util/SharedOutputBuffer.java   |   77 +-
 .../apache/http/nio/util/SimpleInputBuffer.java    |   11 +-
 .../apache/http/nio/util/SimpleOutputBuffer.java   |   15 +-
 .../org/apache/http/nio/version.properties         |    2 +-
 httpcore-nio/src/site/apt/index.apt                |   44 -
 httpcore-nio/src/site/resources/css/site.css       |    1 -
 httpcore-nio/src/site/site.xml                     |   40 -
 ...ontentDecoderMock.java => ByteChannelMock.java} |   49 +-
 .../java/org/apache/http/HttpCoreNIOTestBase.java  |  155 ---
 .../http/LoggingClientConnectionFactory.java       |   52 -
 .../http/LoggingServerConnectionFactory.java       |   52 -
 .../org/apache/http/ReadableByteChannelMock.java   |   21 +-
 .../org/apache/http/WritableByteChannelMock.java   |  158 +++
 .../apache/http/impl/nio/TestContentChannel.java   |    6 +-
 .../impl/nio/TestDefaultNHttpClientConnection.java |  670 ++++++++++++
 .../impl/nio/TestDefaultNHttpServerConnection.java |  672 ++++++++++++
 .../http/impl/nio/TestNHttpConnectionBase.java     |  277 +++++
 .../nio/codecs/CodecTestUtils.java}                |   58 +-
 .../http/impl/nio/codecs/TestChunkDecoder.java     |  274 +++--
 .../http/impl/nio/codecs/TestChunkEncoder.java     |  235 ++--
 .../impl/nio/codecs/TestHttpMessageParser.java     |  189 ++--
 .../http/impl/nio/codecs/TestIdentityDecoder.java  |  292 +++--
 .../http/impl/nio/codecs/TestIdentityEncoder.java  |  520 ++++++++-
 .../nio/codecs/TestLengthDelimitedDecoder.java     |  303 +++---
 .../nio/codecs/TestLengthDelimitedEncoder.java     |  672 +++++++++---
 .../http/impl/nio/pool/TestBasicNIOConnPool.java   |   98 +-
 .../http/impl/nio/reactor/ExceptionEventTest.java  |    4 +-
 .../impl/nio/reactor/TestBaseIOReactorSSL.java     |  170 ---
 .../impl/nio/reactor/TestDefaultIOReactors.java    |  148 +--
 .../impl/nio/reactor/TestDefaultIOReactorsSSL.java |   17 +-
 .../nio/reactor/TestDefaultListeningIOReactor.java |   59 +-
 .../impl/nio/reactor/TestSessionInOutBuffers.java  |  359 +++---
 .../java/org/apache/http/nio/integration/Job.java  |  139 ---
 .../nio/integration/RequestExecutionHandler.java   |  106 --
 .../http/nio/integration/RequestHandler.java       |  103 --
 .../nio/integration/RndTestPatternGenerator.java   |    6 +-
 .../http/nio/integration/SimpleRequestHandler.java |   16 +-
 .../nio/integration/TestAsyncNHttpHandlers.java    | 1141 --------------------
 .../apache/http/nio/integration/TestCustomSSL.java |  148 +++
 .../TestHttpAsyncHandlerCancellable.java           |  112 +-
 .../nio/integration/TestHttpAsyncHandlers.java     |  563 +++++-----
 .../TestHttpAsyncPrematureTermination.java         |  129 +--
 .../nio/integration/TestHttpsAsyncHandlers.java    |   17 +-
 .../nio/integration/TestHttpsAsyncTimeout.java     |   67 +-
 .../http/nio/integration/TestPipelining.java       |   91 +-
 .../integration/TestThrottlingNHttpHandlers.java   |  853 ---------------
 .../http/nio/integration/TestTruncatedChunks.java  |  145 +--
 .../org/apache/http/nio/pool/TestNIOConnPool.java  |  393 ++++---
 .../http/nio/pool/TestRouteSpecificPool.java       |  175 ++-
 ...va => TestBasicAsyncClientExchangeHandler.java} |  169 ++-
 .../protocol/TestBasicAsyncRequestConsumer.java    |    4 +-
 .../nio/protocol/TestBasicAsyncRequestHandler.java |    7 +-
 .../protocol/TestBasicAsyncRequestProducer.java    |   12 +-
 .../protocol/TestBasicAsyncResponseConsumer.java   |    8 +-
 .../protocol/TestBasicAsyncResponseProducer.java   |   12 +-
 .../nio/protocol/TestErrorResponseProducer.java    |    7 +-
 .../nio/protocol/TestHttpAsyncRequestExecutor.java |  211 ++--
 .../http/nio/protocol/TestHttpAsyncRequester.java  |  104 +-
 .../http/nio/protocol/TestHttpAsyncService.java    |  298 +++--
 .../TestUriHttpAsyncRequestHandlerMapper.java      |  107 ++
 .../apache/http/nio/testserver/HttpClientNio.java  |  312 ++++++
 .../http/nio/testserver/HttpCoreNIOTestBase.java   |   87 ++
 .../http/{ => nio}/testserver/HttpServerNio.java   |   74 +-
 .../LoggingClientConnectionFactory.java}           |   19 +-
 .../{ => nio/testserver}/LoggingIOSession.java     |   29 +-
 .../testserver}/LoggingNHttpClientConnection.java  |   28 +-
 .../testserver}/LoggingNHttpServerConnection.java  |   28 +-
 .../LoggingSSLClientConnectionFactory.java         |   39 +-
 .../LoggingSSLServerConnectionFactory.java         |   39 +-
 .../LoggingServerConnectionFactory.java}           |   20 +-
 .../http/{ => nio/testserver}/SSLTestContexts.java |   36 +-
 .../SimpleIOReactorExceptionHandler.java           |    5 +-
 .../org/apache/http/{ => nio/testserver}/Wire.java |   24 +-
 .../apache/http/nio/util/ContentDecoderMock.java   |    5 +-
 .../apache/http/nio/util/ContentEncoderMock.java   |   18 +-
 .../java/org/apache/http/nio/util/TestBuffers.java |   58 +-
 .../org/apache/http/testserver/HttpClientNio.java  |  145 ---
 .../testserver/NHttpClientEventHandlerAdaptor.java |  101 --
 .../testserver/NHttpServerEventHandlerAdaptor.java |  101 --
 httpcore-osgi/pom.xml                              |   34 +-
 .../src/main/appended-resources/META-INF/LICENSE   |  180 +--
 .../src/main/appended-resources/META-INF/NOTICE    |    2 +
 httpcore/pom.xml                                   |   78 +-
 .../org/apache/http/examples/ElementalHttpGet.java |   59 +-
 .../apache/http/examples/ElementalHttpPost.java    |   71 +-
 .../apache/http/examples/ElementalHttpServer.java  |  113 +-
 .../http/examples/ElementalPoolingHttpGet.java     |   54 +-
 .../http/examples/ElementalReverseProxy.java       |  104 +-
 .../src/main/appended-resources/META-INF/LICENSE   |  180 +--
 .../src/main/appended-resources/META-INF/NOTICE    |    2 +
 .../http/impl/AbstractHttpClientConnection.java    |   60 +-
 .../http/impl/AbstractHttpServerConnection.java    |   47 +-
 .../http/impl/DefaultHttpClientConnection.java     |   37 +-
 .../http/impl/DefaultHttpServerConnection.java     |   40 +-
 .../http/impl/SocketHttpClientConnection.java      |   65 +-
 .../http/impl/SocketHttpServerConnection.java      |   71 +-
 .../http/impl/entity/EntityDeserializer.java       |   25 +-
 .../apache/http/impl/entity/EntitySerializer.java  |   25 +-
 .../http/impl/io/AbstractSessionInputBuffer.java   |  130 ++-
 .../http/impl/io/AbstractSessionOutputBuffer.java  |  110 +-
 .../org/apache/http/impl/io/HttpRequestParser.java |   19 +-
 .../org/apache/http/impl/io/HttpRequestWriter.java |    3 +
 .../apache/http/impl/io/HttpResponseParser.java    |   19 +-
 .../apache/http/impl/io/HttpResponseWriter.java    |    3 +
 .../org/apache/http/impl/io/SocketInputBuffer.java |   42 +-
 .../apache/http/impl/io/SocketOutputBuffer.java    |   32 +-
 .../apache/http/params/DefaultedHttpParams.java    |   22 +-
 .../apache/http/params/HttpAbstractParamBean.java  |   11 +-
 .../http/params/HttpConnectionParamBean.java       |   16 +-
 .../apache/http/params/HttpConnectionParams.java   |  107 +-
 .../apache/http/params/HttpProtocolParamBean.java  |    6 +-
 .../org/apache/http/params/HttpProtocolParams.java |   81 +-
 .../apache/http/params/SyncBasicHttpParams.java    |    6 +-
 .../apache/http/protocol/BasicHttpProcessor.java   |   53 +-
 .../apache/http/protocol/DefaultedHttpContext.java |   15 +-
 .../org/apache/http/protocol/ExecutionContext.java |    6 +
 .../http/protocol/HttpRequestHandlerRegistry.java  |   11 +-
 .../apache/http/protocol/SyncBasicHttpContext.java |    2 +-
 .../org/apache/http/util/ExceptionUtils.java       |   10 +-
 .../org/apache/http/ContentTooLongException.java   |    2 +-
 .../main/java/org/apache/http/HeaderElement.java   |    2 +-
 .../EofSensor.java => HttpConnectionFactory.java}  |   13 +-
 .../apache/http/HttpEntityEnclosingRequest.java    |    2 -
 .../src/main/java/org/apache/http/HttpHost.java    |   92 +-
 .../src/main/java/org/apache/http/HttpMessage.java |    9 +
 .../main/java/org/apache/http/HttpResponse.java    |   15 +-
 .../src/main/java/org/apache/http/HttpVersion.java |    4 +-
 ...eption.java => MessageConstraintException.java} |   14 +-
 .../org/apache/http/NoHttpResponseException.java   |    2 +-
 .../main/java/org/apache/http/ParseException.java  |    2 +-
 .../java/org/apache/http/ProtocolException.java    |    4 +-
 .../main/java/org/apache/http/ProtocolVersion.java |   52 +-
 .../http/UnsupportedHttpVersionException.java      |    1 -
 .../java/org/apache/http/annotation/GuardedBy.java |   27 +-
 .../java/org/apache/http/annotation/Immutable.java |   27 +-
 .../org/apache/http/annotation/NotThreadSafe.java  |   27 +-
 .../org/apache/http/annotation/ThreadSafe.java     |   27 +-
 .../org/apache/http/concurrent/BasicFuture.java    |   11 +-
 .../org/apache/http/concurrent/FutureCallback.java |    5 +-
 .../org/apache/http/config/ConnectionConfig.java   |  192 ++++
 .../main/java/org/apache/http/config/Lookup.java   |   15 +-
 .../org/apache/http/config/MessageConstraints.java |  113 ++
 .../Registry.java}                                 |   41 +-
 .../RegistryBuilder.java}                          |   41 +-
 .../java/org/apache/http/config/SocketConfig.java  |  197 ++++
 .../org/apache/http/entity/AbstractHttpEntity.java |   12 +-
 .../org/apache/http/entity/BasicHttpEntity.java    |   31 +-
 .../org/apache/http/entity/BufferedHttpEntity.java |   15 +-
 .../org/apache/http/entity/ByteArrayEntity.java    |   17 +-
 .../apache/http/entity/ContentLengthStrategy.java  |    2 +-
 .../java/org/apache/http/entity/ContentType.java   |  136 ++-
 .../org/apache/http/entity/EntityTemplate.java     |   13 +-
 .../java/org/apache/http/entity/FileEntity.java    |   24 +-
 .../org/apache/http/entity/HttpEntityWrapper.java  |   17 +-
 .../org/apache/http/entity/InputStreamEntity.java  |   80 +-
 .../org/apache/http/entity/SerializableEntity.java |   32 +-
 .../java/org/apache/http/entity/StringEntity.java  |   36 +-
 .../org/apache/http/impl/BHttpConnectionBase.java  |  393 +++++++
 .../java/org/apache/http/impl/ConnSupport.java     |   75 ++
 .../http/impl/DefaultBHttpClientConnection.java    |  182 ++++
 .../impl/DefaultBHttpClientConnectionFactory.java  |  103 ++
 .../http/impl/DefaultBHttpServerConnection.java    |  174 +++
 .../impl/DefaultBHttpServerConnectionFactory.java  |  103 ++
 .../http/impl/DefaultConnectionReuseStrategy.java  |   42 +-
 .../http/impl/DefaultHttpRequestFactory.java       |   13 +-
 .../http/impl/DefaultHttpResponseFactory.java      |   49 +-
 .../http/impl/EnglishReasonPhraseCatalog.java      |   14 +-
 .../http/impl/HttpConnectionMetricsImpl.java       |   10 +-
 .../http/impl/NoConnectionReuseStrategy.java       |   13 +-
 .../DisallowIdentityContentLengthStrategy.java     |   11 +-
 .../http/impl/entity/LaxContentLengthStrategy.java |   68 +-
 .../impl/entity/StrictContentLengthStrategy.java   |   29 +-
 .../apache/http/impl/io/AbstractMessageParser.java |  124 ++-
 .../apache/http/impl/io/AbstractMessageWriter.java |   41 +-
 .../apache/http/impl/io/ChunkedInputStream.java    |   43 +-
 .../apache/http/impl/io/ChunkedOutputStream.java   |   46 +-
 .../http/impl/io/ContentLengthInputStream.java     |   36 +-
 .../http/impl/io/ContentLengthOutputStream.java    |   30 +-
 .../http/impl/io/DefaultHttpRequestParser.java     |   75 +-
 .../impl/io/DefaultHttpRequestParserFactory.java   |   71 ++
 ...stWriter.java => DefaultHttpRequestWriter.java} |   28 +-
 ...r.java => DefaultHttpRequestWriterFactory.java} |   38 +-
 .../http/impl/io/DefaultHttpResponseParser.java    |   75 +-
 .../impl/io/DefaultHttpResponseParserFactory.java  |   71 ++
 ...eWriter.java => DefaultHttpResponseWriter.java} |   28 +-
 ....java => DefaultHttpResponseWriterFactory.java} |   38 +-
 .../http/impl/io/HttpTransportMetricsImpl.java     |    4 +-
 .../apache/http/impl/io/IdentityInputStream.java   |    8 +-
 .../apache/http/impl/io/IdentityOutputStream.java  |   12 +-
 ...nputBuffer.java => SessionInputBufferImpl.java} |  202 ++--
 ...putBuffer.java => SessionOutputBufferImpl.java} |  162 ++-
 .../apache/http/impl/pool/BasicConnFactory.java    |  131 ++-
 .../org/apache/http/impl/pool/BasicConnPool.java   |   45 +-
 .../org/apache/http/impl/pool/BasicPoolEntry.java  |    2 +-
 .../main/java/org/apache/http/io/EofSensor.java    |    3 +
 .../java/org/apache/http/io/HttpMessageParser.java |    6 +-
 ...ofSensor.java => HttpMessageParserFactory.java} |   11 +-
 .../java/org/apache/http/io/HttpMessageWriter.java |    2 +-
 .../apache/http/io/HttpMessageWriterFactory.java   |   17 +-
 .../org/apache/http/io/SessionInputBuffer.java     |    4 +
 .../apache/http/message/AbstractHttpMessage.java   |   40 +-
 .../java/org/apache/http/message/BasicHeader.java  |    8 +-
 .../apache/http/message/BasicHeaderElement.java    |   31 +-
 .../http/message/BasicHeaderElementIterator.java   |   21 +-
 .../apache/http/message/BasicHeaderIterator.java   |   21 +-
 .../http/message/BasicHeaderValueFormatter.java    |  147 ++-
 .../http/message/BasicHeaderValueParser.java       |  170 ++-
 .../message/BasicHttpEntityEnclosingRequest.java   |    2 +-
 .../org/apache/http/message/BasicHttpRequest.java  |   41 +-
 .../org/apache/http/message/BasicHttpResponse.java |  133 ++-
 .../apache/http/message/BasicLineFormatter.java    |  103 +-
 .../org/apache/http/message/BasicLineParser.java   |  200 ++--
 .../http/message/BasicListHeaderIterator.java      |   30 +-
 .../apache/http/message/BasicNameValuePair.java    |   28 +-
 .../org/apache/http/message/BasicRequestLine.java  |   22 +-
 .../org/apache/http/message/BasicStatusLine.java   |   18 +-
 .../apache/http/message/BasicTokenIterator.java    |   69 +-
 .../org/apache/http/message/BufferedHeader.java    |   15 +-
 .../java/org/apache/http/message/HeaderGroup.java  |   44 +-
 .../org/apache/http/message/LineFormatter.java     |    2 +-
 .../java/org/apache/http/message/LineParser.java   |    4 +-
 .../java/org/apache/http/message/ParserCursor.java |    6 +-
 .../org/apache/http/params/AbstractHttpParams.java |   45 +-
 .../org/apache/http/params/BasicHttpParams.java    |   44 +-
 .../apache/http/params/CoreConnectionPNames.java   |    4 +
 .../org/apache/http/params/CoreProtocolPNames.java |   10 +-
 .../org/apache/http/params/HttpParamConfig.java    |   78 ++
 .../java/org/apache/http/params/HttpParams.java    |    9 +-
 .../org/apache/http/params/HttpParamsNames.java    |    4 +
 .../org/apache/http/pool/AbstractConnPool.java     |  210 ++--
 .../main/java/org/apache/http/pool/PoolEntry.java  |   21 +-
 .../EofSensor.java => pool/PoolEntryCallback.java} |   14 +-
 .../java/org/apache/http/pool/PoolEntryFuture.java |   40 +-
 .../main/java/org/apache/http/pool/PoolStats.java  |   36 +-
 .../org/apache/http/pool/RouteSpecificPool.java    |   68 +-
 .../org/apache/http/protocol/BasicHttpContext.java |   13 +-
 .../org/apache/http/protocol/ChainBuilder.java     |  126 +++
 .../main/java/org/apache/http/protocol/HTTP.java   |    4 +-
 .../java/org/apache/http/protocol/HttpContext.java |   11 +-
 .../org/apache/http/protocol/HttpCoreContext.java  |  152 +++
 .../apache/http/protocol/HttpDateGenerator.java    |    2 +-
 .../apache/http/protocol/HttpProcessorBuilder.java |  151 +++
 .../apache/http/protocol/HttpRequestExecutor.java  |  141 +--
 ...Resolver.java => HttpRequestHandlerMapper.java} |   19 +-
 .../http/protocol/HttpRequestHandlerResolver.java  |    4 +-
 .../http/protocol/HttpRequestInterceptorList.java  |    3 +
 .../http/protocol/HttpResponseInterceptorList.java |    3 +
 .../java/org/apache/http/protocol/HttpService.java |  178 ++-
 .../http/protocol/ImmutableHttpProcessor.java      |   60 +-
 .../apache/http/protocol/RequestConnControl.java   |    7 +-
 .../org/apache/http/protocol/RequestContent.java   |   15 +-
 .../java/org/apache/http/protocol/RequestDate.java |   10 +-
 .../http/protocol/RequestExpectContinue.java       |   49 +-
 .../apache/http/protocol/RequestTargetHost.java    |   26 +-
 .../org/apache/http/protocol/RequestUserAgent.java |   37 +-
 .../apache/http/protocol/ResponseConnControl.java  |   24 +-
 .../org/apache/http/protocol/ResponseContent.java  |   19 +-
 .../org/apache/http/protocol/ResponseDate.java     |   10 +-
 .../org/apache/http/protocol/ResponseServer.java   |   30 +-
 ...istry.java => UriHttpRequestHandlerMapper.java} |   61 +-
 .../apache/http/protocol/UriPatternMatcher.java    |   64 +-
 .../java/org/apache/http/protocol/package.html     |    2 +-
 .../src/main/java/org/apache/http/util/Args.java   |  111 ++
 .../main/java/org/apache/http/util/Asserts.java    |   48 +-
 .../java/org/apache/http/util/ByteArrayBuffer.java |   46 +-
 .../java/org/apache/http/util/CharArrayBuffer.java |   72 +-
 .../java/org/apache/http/util/CharsetUtils.java    |   43 +-
 .../java/org/apache/http/util/EncodingUtils.java   |   63 +-
 .../java/org/apache/http/util/EntityUtils.java     |   85 +-
 .../main/java/org/apache/http/util/LangUtils.java  |    6 +-
 .../main/java/org/apache/http/util/NetUtils.java   |   37 +-
 .../main/java/org/apache/http/util/TextUtils.java  |   31 +-
 .../java/org/apache/http/util/VersionInfo.java     |  111 +-
 .../resources/org/apache/http/version.properties   |    2 +-
 httpcore/src/site/apt/index.apt                    |   44 -
 httpcore/src/site/resources/css/site.css           |    1 -
 httpcore/src/site/site.xml                         |   40 -
 .../java/org/apache/http/TestHttpExceptions.java   |    2 +-
 .../test/java/org/apache/http/TestHttpHost.java    |   98 +-
 .../test/java/org/apache/http/TestHttpVersion.java |   26 +-
 .../apache/http/concurrent/TestBasicFuture.java    |   55 +-
 .../java/org/apache/http/config/TestRegistry.java  |   26 +-
 .../apache/http/entity/TestAbstractHttpEntity.java |    6 +-
 .../apache/http/entity/TestBasicHttpEntity.java    |   28 +-
 .../apache/http/entity/TestBufferedHttpEntity.java |   30 +-
 .../apache/http/entity/TestByteArrayEntity.java    |   30 +-
 .../org/apache/http/entity/TestContentType.java    |   76 +-
 .../org/apache/http/entity/TestEntityTemplate.java |   18 +-
 .../org/apache/http/entity/TestFileEntity.java     |   18 +-
 .../apache/http/entity/TestHttpEntityWrapper.java  |   24 +-
 .../apache/http/entity/TestInputStreamEntity.java  |  100 +-
 .../apache/http/entity/TestSerializableEntity.java |   46 +-
 .../org/apache/http/entity/TestStringEntity.java   |   28 +-
 .../apache/http/impl/SessionInputBufferMock.java   |   76 +-
 .../apache/http/impl/SessionOutputBufferMock.java  |   49 +-
 .../apache/http/impl/TestBHttpConnectionBase.java  |  390 +++++++
 .../org/apache/http/impl/TestBasicRequest.java     |   17 +-
 .../impl/TestDefaultBHttpClientConnection.java     |  168 +++
 .../impl/TestDefaultBHttpServerConnection.java     |  188 ++++
 .../impl/TestDefaultConnectionReuseStrategy.java   |   50 +-
 .../http/impl/TestEnglishReasonPhraseCatalog.java  |   13 +-
 .../http/impl/TestNoConnectionReuseStrategy.java   |   15 +-
 .../apache/http/impl/entity/DummyHttpMessage.java  |   13 +-
 .../TestDisallowIdentityContentLengthStrategy.java |   12 +-
 .../http/impl/entity/TestEntityDeserializer.java   |  356 ------
 .../http/impl/entity/TestEntitySerializer.java     |  188 ----
 .../impl/entity/TestLaxContentLengthStrategy.java  |  118 +-
 .../entity/TestStrictContentLengthStrategy.java    |   35 +-
 .../org/apache/http/impl/io/TestChunkCoding.java   |  195 ++--
 .../http/impl/io/TestContentLengthInputStream.java |   60 +-
 .../impl/io/TestContentLengthOutputStream.java     |   30 +-
 .../http/impl/io/TestIdentityInputStream.java      |   31 +-
 .../http/impl/io/TestIdentityOutputStream.java     |   51 +-
 .../org/apache/http/impl/io/TestMessageParser.java |   55 +-
 .../org/apache/http/impl/io/TestRequestParser.java |   87 +-
 .../apache/http/impl/io/TestResponseParser.java    |   84 +-
 ...onBuffers.java => TestSessionInOutBuffers.java} |  410 ++++---
 .../http/impl/io/TestSocketOutputBuffer.java       |  197 ----
 .../http/impl/io/TimeoutByteArrayInputStream.java  |   30 +-
 .../apache/http/impl/pool/TestBasicConnPool.java   |   34 +-
 .../org/apache/http/integration/TestSyncHttp.java  |  375 +++----
 .../apache/http/message/TestAbstractMessage.java   |   46 +-
 .../message/TestBasicHeaderElementIterator.java    |   21 +-
 .../http/message/TestBasicHeaderIterator.java      |   15 +-
 .../message/TestBasicHeaderValueFormatter.java     |   71 +-
 .../http/message/TestBasicHeaderValueParser.java   |   33 +-
 .../apache/http/message/TestBasicHttpResponse.java |  101 ++
 .../http/message/TestBasicLineFormatter.java       |   42 +-
 .../apache/http/message/TestBasicLineParser.java   |   42 +-
 .../org/apache/http/message/TestBasicMessages.java |   33 +-
 .../http/message/TestBasicTokenIterator.java       |   60 +-
 .../apache/http/message/TestBufferedHeader.java    |   34 +-
 .../java/org/apache/http/message/TestHeader.java   |   28 +-
 .../org/apache/http/message/TestHeaderElement.java |   39 +-
 .../org/apache/http/message/TestHeaderGroup.java   |   92 +-
 .../org/apache/http/message/TestNameValuePair.java |   24 +-
 .../org/apache/http/message/TestRequestLine.java   |   26 +-
 .../org/apache/http/message/TestStatusLine.java    |   24 +-
 .../apache/http/params/TestBasicHttpParams.java    |   73 --
 .../http/params/TestDefaultedHttpParams.java       |   98 --
 .../java/org/apache/http/pool/TestConnPool.java    |  333 +++---
 .../java/org/apache/http/pool/TestPoolEntry.java   |   27 +-
 .../apache/http/pool/TestRouteSpecificPool.java    |   97 +-
 .../http/protocol/TestBasicHttpProcessor.java      |  127 ---
 .../org/apache/http/protocol/TestChainBuilder.java |   67 ++
 .../http/protocol/TestHttpExecutionContext.java    |   14 +-
 .../http/protocol/TestHttpRequestExecutor.java     |  242 ++---
 .../protocol/TestHttpRequestHandlerRegistry.java   |  244 -----
 .../org/apache/http/protocol/TestHttpService.java  |  419 ++++---
 .../http/protocol/TestStandardInterceptors.java    |  682 ++++++------
 .../protocol/TestUriHttpRequestHandlerMapper.java  |  103 ++
 .../http/protocol/TestUriPatternMatcher.java       |  155 +++
 .../org/apache/http/testserver/HttpClient.java     |   63 +-
 .../org/apache/http/testserver/HttpServer.java     |   80 +-
 .../testserver/LoggingBHttpClientConnection.java   |  102 +-
 .../testserver/LoggingBHttpServerConnection.java   |  102 +-
 .../apache/http/testserver/LoggingInputStream.java |   82 +-
 .../http/testserver/LoggingOutputStream.java       |   38 +-
 .../java/org/apache/http/testserver}/Wire.java     |   41 +-
 .../test/java/org/apache/http/util/TestArgs.java   |  170 +++
 .../TestAsserts.java}                              |   60 +-
 .../org/apache/http/util/TestByteArrayBuffer.java  |  102 +-
 .../org/apache/http/util/TestCharArrayBuffer.java  |  120 +-
 .../org/apache/http/util/TestEncodingUtils.java    |   66 +-
 .../java/org/apache/http/util/TestEntityUtils.java |   80 +-
 .../java/org/apache/http/util/TestLangUtils.java   |   18 +-
 pom.xml                                            |  143 +--
 src/docbkx/advanced.xml                            |  283 ++---
 src/docbkx/fundamentals.xml                        |  520 ++++-----
 src/docbkx/nio-ext.xml                             |  420 +++----
 src/docbkx/preface.xml                             |    4 +-
 src/docbkx/resources/css/hc-tutorial.css           |    4 +-
 src/docbkx/resources/xsl/fopdf.xsl                 |    8 +-
 src/docbkx/resources/xsl/html.xsl                  |    4 +-
 src/docbkx/resources/xsl/html_chunk.xsl            |    4 +-
 src/main/assembly/bin.xml                          |   85 --
 src/main/assembly/build.xml                        |   70 --
 src/main/assembly/osgi-bin.xml                     |   80 --
 src/main/assembly/src.xml                          |   48 -
 src/site/apt/download.apt                          |   66 --
 src/site/apt/examples.apt                          |   62 --
 src/site/apt/index.apt                             |   61 --
 src/site/resources/css/site.css                    |    1 -
 src/site/site.xml                                  |   45 -
 586 files changed, 21787 insertions(+), 23035 deletions(-)

diff --git a/BUILDING.txt b/BUILDING.txt
index 0c73a97..9922796 100644
--- a/BUILDING.txt
+++ b/BUILDING.txt
@@ -1,14 +1,12 @@
-Building HttpComponents Core 
+Building HttpComponents Core
 ============================
 
 (1) Requisites
 --------------
 JDK 1.5+ is required in order to compile and run HttpCore.
 
-HttpCore utilizes Maven 2 as a distribution management and packaging tool.
-Version 2.2.1 or later is recommended. Maven 3.0.x can also be used 
-to build HttpCore, however it is known to be incompatible with the Clover 
-plugin used to generate web site content. 
+HttpCore utilizes Maven as a distribution management and packaging tool.
+Version 3.0.3 or later is required.
 
 Maven installation and configuration instructions can be found here:
 
@@ -20,9 +18,9 @@ Execute the following command in order to compile and test the components
 
 mvn test
 
-(3) Building packages 
+(3) Building packages
 
-Execute the following command in order to build the JAR packages and install 
+Execute the following command in order to build the JAR packages and install
 them to the local repository:
 
 mvn install
@@ -35,7 +33,7 @@ httpcore-osgi/target/org.apache.httpcomponents.httpcore_<VERSION>.jar
 
 where <VERSION> is the release version
 
-(4) Building documentation 
+(4) Building documentation
 
 Execute the following command in order to generate javadoc:
 
@@ -45,28 +43,3 @@ Execute the following command in order to generate the tutorial in html and pdf
 
 mvn docbkx:generate-pdf docbkx:generate-html
 
-(5) Building distribution assemblies 
-
-Execute the following command in order to build the distribution assemblies
-
-mvn package assembly:assembly
-
-(6) Fix EOL in source files
-
-Fix the archive files so the source files have the correct EOL settings:
-
-mvn antrun:run
-
-(7) Building project web site 
-
-Execute the following command in order to generate the project web site:
-
-mvn site -Dmaven.clover.licenseLocation=<path>/clover.license
-
-where <path> is a full path to Clover license file
-
-ASF committers can obtain a copy of Clover license donated to the ASF from the SVN repository
-at the following location:
-
-https://svn.apache.org/repos/private/committers/donated-licenses/clover
-
diff --git a/LICENSE.txt b/LICENSE.txt
index 879d3fd..72819a9 100644
--- a/LICENSE.txt
+++ b/LICENSE.txt
@@ -1,3 +1,4 @@
+
                                  Apache License
                            Version 2.0, January 2004
                         http://www.apache.org/licenses/
@@ -178,9 +179,9 @@
 =========================================================================
 
 This project contains annotations in the package org.apache.http.annotation
-which are derived from JCIP-ANNOTATIONS 
+which are derived from JCIP-ANNOTATIONS
 Copyright (c) 2005 Brian Goetz and Tim Peierls.
-See http://www.jcip.net and the Creative Commons Attribution License 
+See http://www.jcip.net and the Creative Commons Attribution License
 (http://creativecommons.org/licenses/by/2.5)
 Full text: http://creativecommons.org/licenses/by/2.5/legalcode
 
diff --git a/RELEASE_NOTES.txt b/RELEASE_NOTES.txt
index 63c5199..dc3fd76 100644
--- a/RELEASE_NOTES.txt
+++ b/RELEASE_NOTES.txt
@@ -1,15 +1,143 @@
+Release 4.3
+-------------------
+
+This is the first stable (GA) release of HttpCore 4.3. The most notable features in the 4.3
+branch are:
+
+* Deprecation of preference and configuration API based on HttpParams interface in favor of
+  constructor injection and plain configuration objects.
+
+* Reliance on object immutability instead of access synchronization for thread safety.
+  Several old classes whose instances can be shared by multiple request exchanges have
+  been replaced by immutable equivalents.
+
+The 4.3 branch also contains performance optimizations such as reduced TCP packet fragmentation
+and more efficient lease / release operations for pools of persistent connections on the client
+side.
+
+This release also includes all fixes from the 4.2.x release branch.
+
+Users of HttpCore 4.2 are encouraged to upgrade.
+
+
+Changelog
+-------------------
+
+* [HTTPCORE-343] AbstractNIOConnPool to fire request callbacks outside the pool lock.
+  This makes it possible to re-enter pool methods from a callback event.
+  Contributed by Oleg Kalnichevski <olegk at apache.org>
+
+* [HTTPCORE-340] AbstractNIOConnPool to support lease timeout distinct from connect timeout.
+  Contributed by Ignat Alexeyenko <ignatalexeyenko at gmail.com>
+
+* Blocking connections do not clean session input buffer when closed (input data from a read
+  operation may still remain in the buffer if the connection is re-opened).
+  Contributed by Oleg Kalnichevski <olegk at apache.org>
+
+
+
+Release 4.2.5
+-------------------
+
+This maintenance release fixes a number of bugs found in NIO components since 4.2.4. We advise
+users of HttpCore NIO of all versions to upgrade.
+
+This is likely to be the last release in the 4.2.x branch.
+
+
+Changelog
+-------------------
+
+* [HTTPCORE-345] EntityAsyncContentProducer fails to release resources allocated by the underlying
+  entity when #produceContent is never invoked.
+  Contributed by Tad Whitenight <tadwhitenight at gmail.com>
+
+* Non-blocking connection pool to avoid scanning the entire queue of pending connection requests
+  on each connection lease / release operation (under heavy load the request queue can contain
+  a significant number of pending requests, a full linear scan of which can cause massive
+  performance degradation).
+  Contributed by Oleg Kalnichevski <olegk at apache.org>
+
+* Use bulk ByteBuffer#put method instead of single byte ByteBuffer#put
+  Contributed by Oleg Kalnichevski <olegk at apache.org>
+
+* [HTTPCORE-336]  Unhandled CancelledKeyException leads to a shutdown of the underlying IOReactor.
+  Contributed by Thomas Dudek <mail.dudek at gmail.com>
+
+
+
+Release 4.3-BETA2
+-------------------
+
+This is the second BETA release from the 4.3.x release branch. This release addresses performance
+issues in the non-blocking connection pool implementation and also includes a number of performance
+improvements in the low level NIO based transport components.
+
+Changelog
+-------------------
+
+* [HTTPCORE-300] ContentType to provide support for custom parameters.
+  Contributed by Oleg Kalnichevski <olegk at apache.org>
+
+* Non-blocking connection pool to avoid scanning the entire queue of pending connection requests
+  on each connection lease / release operation (under heavy load the request queue can contain
+  a significant number of pending requests, a full linear scan of which can cause massive
+  performance degradation).
+  Contributed by Oleg Kalnichevski <olegk at apache.org>
+
+* Basic connection pool implementations to perform default port resolution for HTTP and HTTPS
+  schemes.
+  Contributed by Oleg Kalnichevski <olegk at apache.org>
+
+* Use bulk ByteBuffer#put method instead of single byte ByteBuffer#put
+  Contributed by Oleg Kalnichevski <olegk at apache.org>
+
+* [HTTPCORE-336]  Unhandled CancelledKeyException leads to a shutdown of the underlying IOReactor.
+  Contributed by Thomas Dudek <mail.dudek at gmail.com>
+
+
+Release 4.3-BETA1
+-------------------
+
+This is the first BETA release from the 4.3.x release branch. The main theme of the 4.3 release
+series is streamlining of component configuration and deprecation of the old configuration
+API based on HttpParams in favor of constructor-based dependency injection and plain objects
+for configuration parameters.
+
+This release also includes performance optimizations intended to reduce TCP packet fragmentation
+when writing out HTTP messages both in blocking and non-blocking I/O modes, which should result
+in up to 20% higher throughput for short entity enclosing messages.
+
+This release also includes all fixes from the stable 4.2.x release branch.
+
+
+Changelog
+-------------------
+
+* Reduced TCP packet fragmentation when writing out message content with blocking and
+  non-blocking connections.
+  Contributed by Oleg Kalnichevski <olegk at apache.org>
+
+* [HTTPCORE-330] Clarify InputStreamEntity length constructor argument.
+  Contributed by John McCarthy <jmsignup at gmail.com>
+
+* [HTTPCORE-323] Undocumented UnsupportedCharsetException in ContentType#getOrDefault.
+  Contributed by Gary D. Gregory <ggregory at apache.org>
+
+
+
 Release 4.2.4
 -------------------
 
-This maintenance release fixes a number of bugs found in NIO components since 4.2.3. We advise 
+This maintenance release fixes a number of bugs found in NIO components since 4.2.3. We advise
 users of HttpCore NIO of all versions to upgrade.
 
 Changelog
 -------------------
 
 * [HTTPCORE-334] https request to a non-responsive but alive port over a non-blocking connection
-  results in a busy loop in one of I/O dispatch threads. 
-  Contributed by Scott Stanton <snstanton at gmail.com> 
+  results in a busy loop in one of I/O dispatch threads.
+  Contributed by Scott Stanton <snstanton at gmail.com>
 
 * [HTTPCORE-331] BasicFuture no longer executes notification callbacks inside a synchronized block.
   Contributed by Oleg Kalnichevski <olegk at apache.org>
@@ -22,11 +150,26 @@ Changelog
 
 
 
+Release 4.1-ALPHA1
+-------------------
+
+This is the first release from the 4.3.x release branch. The main focus of the 4.3 release
+series is streamlining of component configuration and deprecation of the old configuration
+API based on HttpParams in favor of constructor based dependency injection and plain objects
+for configuration parameters.
+
+We are kindly asking all upstream projects to review API changes and help us improve
+the APIs by providing feedback and sharing ideas on dev at hc.apache.org.
+
+This release also includes all fixes from the stable 4.2.x release branch.
+
+
+
 Release 4.2.3
 -------------------
 
-This maintenance release fixes a number of bugs found since 4.2.2 including 
-a major bug in the NIO module that can cause an infinite loop in SSL sessions under special 
+This maintenance release fixes a number of bugs and found since 4.2.2 including
+a major bug in the NIO module that can cause an infinite loop in SSL sessions under special
 circumstances when the remote peer terminates the session in the middle of SSL handshake.
 Please note this issue does not affect blocking I/O components used by HttpClient.
 
@@ -35,21 +178,21 @@ We advise users of HttpCore NIO of all versions to upgrade.
 Changelog
 -------------------
 
-* [HTTPCORE-319, HTTPCORE-322] Non-blocking SSLIOSession can enter an infinite loop under 
+* [HTTPCORE-319, HTTPCORE-322] Non-blocking SSLIOSession can enter an infinite loop under
   special circumstances when the remote peer terminates the session in the middle of SSL handshake.
-  Contributed by Paul Donohue <apache-jira at PaulSD.com> and 
+  Contributed by Paul Donohue <apache-jira at PaulSD.com> and
   Oleg Kalnichevski <olegk at apache.org>
 
 * [HTTPCORE-316] HeaderGroup#clone removes headers from the original object.
-  Contributed by Markus Thies <markus at dr-thies.com> 
+  Contributed by Markus Thies <markus at dr-thies.com>
 
-* [HTTPCORE-315] AbstractNIOConnPool fails to correctly deallocate connection if it is immediately 
+* [HTTPCORE-315] AbstractNIOConnPool fails to correctly deallocate connection if it is immediately
   released from the session request callback causing a resource leak.
-  Contributed by Scott Stanton <snstanton at gmail.com> 
+  Contributed by Scott Stanton <snstanton at gmail.com>
 
-* [HTTPCORE-313] ContentType#parse now ignores empty and blank charset attributes. 
-  HttpEntityUtils#toString now throws checked I/O exception if it  encounters an unsupported 
-  charset. 
+* [HTTPCORE-313] ContentType#parse now ignores empty and blank charset attributes.
+  HttpEntityUtils#toString now throws checked I/O exception if it  encounters an unsupported
+  charset.
   Contributed by Oleg Kalnichevski <olegk at apache.org>
 
 
@@ -68,22 +211,22 @@ Changelog
 * [HTTPCORE-312] NIO length delimited content encoder incorrectly handles messages larger than 2GB.
   Contributed by Oleg Kalnichevski <olegk at apache.org>
 
-* [HTTPCORE-310] Fixed regression in DefaultConnectionReuseStrategy causing it to incorrectly 
-  flag connections as non-reusable after a 204, 205 or 304 response. 
+* [HTTPCORE-310] Fixed regression in DefaultConnectionReuseStrategy causing it to incorrectly
+  flag connections as non-reusable after a 204, 205 or 304 response.
   Contributed by Oleg Kalnichevski <olegk at apache.org>
 
-* [HTTPCORE-309] Fixed regression in HttpAsyncRequestExecutor causing it to handle 204, 205 
+* [HTTPCORE-309] Fixed regression in HttpAsyncRequestExecutor causing it to handle 204, 205
   and 304 responses incorrectly by returning a message with an enclosed content body.
   Contributed by Oleg Kalnichevski <olegk at apache.org>
 
 * [HTTPCORE-306] I/O reactor TCP_NODELAY parameter now defaults to true.
   Contributed by Oleg Kalnichevski <olegk at apache.org>
 
-* [HTTPASYNC-21] request execution handler does not get closed in case of a premature HTTP 
+* [HTTPASYNC-21] request execution handler does not get closed in case of a premature HTTP
   exchange termination.
   Contributed by Oleg Kalnichevski <olegk at apache.org>
 
-* [HTTPCORE-303] ContentType made Serializable. 
+* [HTTPCORE-303] ContentType made Serializable.
   Contributed by Oleg Kalnichevski <olegk at apache.org>
 
 
@@ -91,19 +234,19 @@ Changelog
 Release 4.2.1
 -------------------
 
-This is a maintenance release that fixes a non-critical number of bugs found since 4.2. 
+This is a maintenance release that fixes a non-critical number of bugs found since 4.2.
 Users of HttpCore 4.2 are encouraged to upgrade.
 
 Changelog
 -------------------
 
-* [HTTPCORE-299] ContentType should rely on Charset#name() instead of Charset#toString() 
+* [HTTPCORE-299] ContentType should rely on Charset#name() instead of Charset#toString()
   for building header value.
   Contributed by Oleg Kalnichevski <olegk at apache.org>
 
 * [HTTPCORE-263] Under rare circumstances incorrectly delineated or garbled HTTP message
   can cause an IndexOutOfBoundsException in AbstractSessionInputBuffer#readLine()
-  Contributed by Michael Pujos <bubbleguuum at free.fr> 
+  Contributed by Michael Pujos <bubbleguuum at free.fr>
 
 * Made connection pools use FIFO algorithm instead of LIFO when leasing / releasing persistent
   connections.
@@ -111,7 +254,7 @@ Changelog
 
 * [HTTPCORE-298] Fixed non-blocking SSLIOSession state can getting out of sync with the underlying
   IOSession in case the I/O session is terminated by the I/O reactor rather than by the protocol
-  handler. 
+  handler.
   Contributed by Sandeep Tamhankar <sandman at electric-cloud.com>
 
 * Fixed NPE in StringEntity constructor thrown if ContentType#getCharset is null.
@@ -121,39 +264,39 @@ Changelog
 Release 4.2
 -------------------
 
-This is the first stable (GA) release of HttpCore 4.2. The most notable features included in this 
-release are connection pool components for blocking and non-blocking HTTP connections and new 
+This is the first stable (GA) release of HttpCore 4.2. The most notable features included in this
+release are connection pool components for blocking and non-blocking HTTP connections and new
 asynchronous client and server side protocol handlers.
 
-New protocol handling API used in conjunction with connection pooling components is expected to 
+New protocol handling API used in conjunction with connection pooling components is expected to
 make development of asynchronous HTTP client agents and HTTP proxies easier and less error prone.
 
-Connection pool components are based on mature code migrated from HttpClient and HttpAsyncClient 
-modules but have a slightly different API that makes a better use of Java standard concurrent 
-primitives. 
+Connection pool components are based on mature code migrated from HttpClient and HttpAsyncClient
+modules but have a slightly different API that makes a better use of Java standard concurrent
+primitives.
 
 Changelog
 -------------------
 
-* Fixed HttpAsyncRequestExecutor incorrect execution of message exchanges that span across multiple 
-  hosts (for instance, in case of a request redirect).  
+* Fixed HttpAsyncRequestExecutor incorrect execution of message exchanges that span across multiple
+  hosts (for instance, in case of a request redirect).
   Contributed by Oleg Kalnichevski <olegk at apache.org>
 
 * AbstractHttpClientConnection#isResponseAvailable method now catches SocketTimeoutException
   and returns false.
   Contributed by Oleg Kalnichevski <olegk at apache.org>
 
-* [HTTPCORE-296] Server side connections (both blocking and non-blocking) can now handle entity 
+* [HTTPCORE-296] Server side connections (both blocking and non-blocking) can now handle entity
   enclosing requests without Content-Length and Transfer-Encoding headers.
   Contributed by Oleg Kalnichevski <olegk at apache.org>
 
-* [HTTPCORE-295] [HTTPCORE-288] Provided direct access to the underlying socket of non-blocking 
+* [HTTPCORE-295] [HTTPCORE-288] Provided direct access to the underlying socket of non-blocking
   HTTP connection to allow modification of socket level settings such as TCP_NODELAY, SO_KEEPALIVE,
   TrafficClass, etc.
   Contributed by Oleg Kalnichevski <olegk at apache.org>
 
-* [HTTPCORE-289] HttpAsyncService fails to invoke Cancellable#cancel() when the ongoing HTTP 
-  exchange is aborted by the client. 
+* [HTTPCORE-289] HttpAsyncService fails to invoke Cancellable#cancel() when the ongoing HTTP
+  exchange is aborted by the client.
   Contributed by Oleg Kalnichevski <olegk at apache.org>
 
 Incompatible changes
@@ -178,14 +321,14 @@ org.apache.http.nio.protocol.NHttpServiceHandlerBase
 Release 4.2-BETA1
 -------------------
 
-This is the first BETA release of HttpCore 4.2. This release comes with completely redesigned 
-and rewritten asynchronous protocol handlers. New protocol handling API used in conjunction with 
-connection pooling components is expected to make development of asynchronous HTTP client agents 
+This is the first BETA release of HttpCore 4.2. This release comes with completely redesigned
+and rewritten asynchronous protocol handlers. New protocol handling API used in conjunction with
+connection pooling components is expected to make development of asynchronous HTTP client agents
 and HTTP proxies easier and less error prone.
 
-Sample application shipped with the release include an example of an HTTP file server capable of 
-direct channel (zero copy) data transfer and an example of a non-blocking, fully streaming reverse 
-proxy.  
+Sample application shipped with the release include an example of an HTTP file server capable of
+direct channel (zero copy) data transfer and an example of a non-blocking, fully streaming reverse
+proxy.
 
 This release also incorporates bug fixes from the stable 4.1.x branch and includes an updated
 HttpCore tutorial.
@@ -195,7 +338,7 @@ HttpCore tutorial.
 Release 4.1.4
 -------------------
 
-This is a maintenance release that fixes a number of bugs found since 4.1.3. It is also likely 
+This is a maintenance release that fixes a number of bugs found since 4.1.3. It is also likely
 to be the last release in the 4.1.x branch.
 
 Changelog
@@ -205,22 +348,22 @@ Changelog
   leading to an abnormal termination of the I/O reactor.
   Contributed by Oleg Kalnichevski <olegk at apache.org>
 
-* [HTTPCORE-257] Fixed incorrect results produced by DefaultConnectionReuseStrategy when handling 
-  response messages whose content entity has been decoded or modified by a protocol interceptor. 
+* [HTTPCORE-257] Fixed incorrect results produced by DefaultConnectionReuseStrategy when handling
+  response messages whose content entity has been decoded or modified by a protocol interceptor.
   Contributed by Oleg Kalnichevski <olegk at apache.org>
 
-* [HTTPCORE-283] Workaround for a bug causing termination of the I/O reactor in case of exception 
+* [HTTPCORE-283] Workaround for a bug causing termination of the I/O reactor in case of exception
   thrown by NHttpServiceHandler#requestReceived or NHttpClientHandler#responseReceived
   methods. A more comprehensive fix for the bug applied to the 4.2 branch.
   Contributed by Oleg Kalnichevski <olegk at apache.org>
 
 * [HTTPCORE-281] ResponseConnControl protocol interceptor does not correctly populate connection
-  persistence control headers when sending a HTTP/1.1 response message in response to a HTTP/1.0 
+  persistence control headers when sending a HTTP/1.1 response message in response to a HTTP/1.0
   request message.
   Contributed by William R. Speirs <bill.speirs at gmail.com>
 
-* [HTTPCORE-282] The default value of the internal event mask of newly created non-blocking I/O 
-  is not correctly initialized, which causes the READ interest bit to get cleared in the interest 
+* [HTTPCORE-282] The default value of the internal event mask of newly created non-blocking I/O
+  is not correctly initialized, which causes the READ interest bit to get cleared in the interest
   op queuing mode unless the event mask is explicitly reset.
   Contributed by Sadeep Jayasumana <sadeep at wso2.com> and Oleg Kalnichevski <olegk at apache.org>
 
@@ -232,33 +375,33 @@ Changelog
 Release 4.2-ALPHA2
 -------------------
 
-This is the second ALPHA release of HttpCore 4.2. This release comes with completely redesigned 
-and rewritten asynchronous protocol handlers. New protocol handling API used in conjunction with 
-connection pooling components introduced in the previous ALPHA release is expected to make 
+This is the second ALPHA release of HttpCore 4.2. This release comes with completely redesigned
+and rewritten asynchronous protocol handlers. New protocol handling API used in conjunction with
+connection pooling components introduced in the previous ALPHA release is expected to make
 development of asynchronous HTTP client agents and HTTP proxies easier and less error prone.
 
-Sample application shipped with the release include an example of an HTTP file server capable of 
-direct channel (zero copy) data transfer and an example of a non-blocking, fully streaming reverse 
-proxy.  
+Sample application shipped with the release include an example of an HTTP file server capable of
+direct channel (zero copy) data transfer and an example of a non-blocking, fully streaming reverse
+proxy.
 
 We are kindly asking existing and prospective users of HttpCore to review and try out the
-new protocol handlers and give us feedback while the 4.2 API is still not final. If no major flaws 
-are discovered the 4.2 API is expected to be frozen with the next BETA release. 
+new protocol handlers and give us feedback while the 4.2 API is still not final. If no major flaws
+are discovered the 4.2 API is expected to be frozen with the next BETA release.
 
-Please note that new features included in this release are still considered experimental and 
-their API may change in the future ALPHA releases. This release also marks the end of support for 
-Java 1.3. As of this release HttpCore requires Java 1.5 for all its components. Several classes and 
-methods deprecated between versions 4.0-beta1 and 4.0 GA (more than two years ago) have been 
+Please note that new features included in this release are still considered experimental and
+their API may change in the future ALPHA releases. This release also marks the end of support for
+Java 1.3. As of this release HttpCore requires Java 1.5 for all its components. Several classes and
+methods deprecated between versions 4.0-beta1 and 4.0 GA (more than two years ago) have been
 removed in this release.
 
 Changelog
 -------------------
 
-* [HTTPCORE-270] Fixed IllegalStateException in AbstractSessionOutputBuffer and 
+* [HTTPCORE-270] Fixed IllegalStateException in AbstractSessionOutputBuffer and
   AbstractSessionInputBuffer.
   Contributed by William R. Speirs <bill.speirs at gmail.com>
 
-* [HTTPCORE-269] Connection pools incorrectly handle lease requests when the max limit for the given 
+* [HTTPCORE-269] Connection pools incorrectly handle lease requests when the max limit for the given
   route has been exceeded and all connections in the route pool are stateful.
   Contributed by Oleg Kalnichevski <olegk at apache.org>
 
@@ -266,18 +409,18 @@ Changelog
 Release 4.2-ALPHA1
 -------------------
 
-This is the first ALPHA release of 4.2. The most notable feature included in this release is 
-support for connection pools of blocking and non-blocking HTTP connections. Connection pool 
-components are based on mature code migrated from HttpClient and HttpAsyncClient modules but have 
-a slightly different API that makes a better use of Java standard concurrent primitives. 
+This is the first ALPHA release of 4.2. The most notable feature included in this release is
+support for connection pools of blocking and non-blocking HTTP connections. Connection pool
+components are based on mature code migrated from HttpClient and HttpAsyncClient modules but have
+a slightly different API that makes a better use of Java standard concurrent primitives.
 
 Support for connection pools in HttpCore is expected to make development of client and proxy HTTP
 services easier and less error prone.
 
-Please note that new features included in this release are still considered experimental and 
-their API may change in the future ALPHA releases. This release also marks the end of support for 
-Java 1.3. As of this release HttpCore requires Java 1.5 for all its components. Several classes and 
-methods deprecated between versions 4.0-beta1 and 4.0 GA (more than two years ago) have been 
+Please note that new features included in this release are still considered experimental and
+their API may change in the future ALPHA releases. This release also marks the end of support for
+Java 1.3. As of this release HttpCore requires Java 1.5 for all its components. Several classes and
+methods deprecated between versions 4.0-beta1 and 4.0 GA (more than two years ago) have been
 removed in this release.
 
 Changelog
diff --git a/httpcore-ab/pom.xml b/httpcore-ab/pom.xml
index 58ccbcb..32ac03f 100644
--- a/httpcore-ab/pom.xml
+++ b/httpcore-ab/pom.xml
@@ -30,15 +30,15 @@
   <parent>
     <groupId>org.apache.httpcomponents</groupId>
     <artifactId>httpcomponents-core</artifactId>
-    <version>4.2.4</version>
+    <version>4.3</version>
   </parent>
   <artifactId>httpcore-ab</artifactId>
-  <name>HttpCore AB clone</name>
+  <name>Apache HttpCore Benchmarking Tool</name>
   <description>
    AB clone based on HttpCore
   </description>
   <url>http://hc.apache.org/httpcomponents-core-ga</url>
-  <packaging>jar</packaging>  
+  <packaging>jar</packaging>
 
   <dependencies>
     <dependency>
@@ -53,30 +53,11 @@
       <version>1.2</version>
       <scope>compile</scope>
     </dependency>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <scope>test</scope>
+    </dependency>
   </dependencies>
 
-  <properties>
-    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
-    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
-    <maven.compile.source>1.5</maven.compile.source>
-    <maven.compile.target>1.5</maven.compile.target>
-    <maven.compile.optimize>true</maven.compile.optimize>
-    <maven.compile.deprecation>true</maven.compile.deprecation>
-  </properties>
-
-  <build>
-    <plugins>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-compiler-plugin</artifactId>
-        <configuration>
-          <source>${maven.compile.source}</source>
-          <target>${maven.compile.target}</target>
-          <optimize>${maven.compile.optimize}</optimize>
-          <showDeprecations>${maven.compile.deprecation}</showDeprecations>
-        </configuration>
-      </plugin>
-    </plugins>
-  </build>
-
 </project>
diff --git a/httpcore-ab/src/main/java/org/apache/http/benchmark/BenchmarkConnection.java b/httpcore-ab/src/main/java/org/apache/http/benchmark/BenchmarkConnection.java
index 145b424..5b695b8 100644
--- a/httpcore-ab/src/main/java/org/apache/http/benchmark/BenchmarkConnection.java
+++ b/httpcore-ab/src/main/java/org/apache/http/benchmark/BenchmarkConnection.java
@@ -26,59 +26,30 @@
  */
 package org.apache.http.benchmark;
 
-import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
 
-import org.apache.http.HttpException;
-import org.apache.http.HttpMessage;
-import org.apache.http.entity.BasicHttpEntity;
-import org.apache.http.impl.DefaultHttpClientConnection;
-import org.apache.http.impl.entity.EntityDeserializer;
-import org.apache.http.impl.entity.EntitySerializer;
-import org.apache.http.impl.entity.LaxContentLengthStrategy;
-import org.apache.http.impl.entity.StrictContentLengthStrategy;
+import org.apache.http.impl.DefaultBHttpClientConnection;
 import org.apache.http.io.SessionInputBuffer;
 import org.apache.http.io.SessionOutputBuffer;
 
-class BenchmarkConnection extends DefaultHttpClientConnection {
+class BenchmarkConnection extends DefaultBHttpClientConnection {
 
     private final Stats stats;
-    
-    BenchmarkConnection(final Stats stats) {
-        super();
+
+    BenchmarkConnection(final int bufsize, final Stats stats) {
+        super(bufsize);
         this.stats = stats;
     }
 
     @Override
-    protected EntityDeserializer createEntityDeserializer() {
-        return new EntityDeserializer(new LaxContentLengthStrategy()) {
-
-            @Override
-            protected BasicHttpEntity doDeserialize(
-                    final SessionInputBuffer inbuffer, 
-                    final HttpMessage message) throws HttpException, IOException {
-                BasicHttpEntity entity = super.doDeserialize(inbuffer, message);
-                InputStream instream = entity.getContent();
-                entity.setContent(new CountingInputStream(instream, stats));
-                return entity;
-            }
-            
-        };
+    protected OutputStream createOutputStream(final long len, final SessionOutputBuffer outbuffer) {
+        return new CountingOutputStream(super.createOutputStream(len, outbuffer), this.stats);
     }
 
     @Override
-    protected EntitySerializer createEntitySerializer() {
-        return new EntitySerializer(new StrictContentLengthStrategy()) {
-
-            @Override
-            protected OutputStream doSerialize(
-                    final SessionOutputBuffer outbuffer, 
-                    final HttpMessage message) throws HttpException, IOException {
-                return new CountingOutputStream(super.doSerialize(outbuffer, message), stats);
-            }
-            
-        };
+    protected InputStream createInputStream(final long len, final SessionInputBuffer inbuffer) {
+        return new CountingInputStream(super.createInputStream(len, inbuffer), this.stats);
     }
-    
+
 }
diff --git a/httpcore-ab/src/main/java/org/apache/http/benchmark/BenchmarkWorker.java b/httpcore-ab/src/main/java/org/apache/http/benchmark/BenchmarkWorker.java
index 5f56afe..2bee2b5 100644
--- a/httpcore-ab/src/main/java/org/apache/http/benchmark/BenchmarkWorker.java
+++ b/httpcore-ab/src/main/java/org/apache/http/benchmark/BenchmarkWorker.java
@@ -45,14 +45,11 @@ import org.apache.http.HttpResponse;
 import org.apache.http.HttpStatus;
 import org.apache.http.entity.ContentType;
 import org.apache.http.impl.DefaultConnectionReuseStrategy;
-import org.apache.http.params.HttpConnectionParams;
-import org.apache.http.params.HttpParams;
-import org.apache.http.protocol.BasicHttpContext;
-import org.apache.http.protocol.BasicHttpProcessor;
-import org.apache.http.protocol.ExecutionContext;
 import org.apache.http.protocol.HTTP;
-import org.apache.http.protocol.HttpContext;
+import org.apache.http.protocol.HttpCoreContext;
+import org.apache.http.protocol.HttpProcessor;
 import org.apache.http.protocol.HttpRequestExecutor;
+import org.apache.http.protocol.ImmutableHttpProcessor;
 import org.apache.http.protocol.RequestConnControl;
 import org.apache.http.protocol.RequestContent;
 import org.apache.http.protocol.RequestExpectContinue;
@@ -68,56 +65,44 @@ import org.apache.http.protocol.RequestUserAgent;
 class BenchmarkWorker implements Runnable {
 
     private final byte[] buffer = new byte[4096];
-    private final int verbosity;
-    private final HttpContext context;
-    private final BasicHttpProcessor httpProcessor;
+    private final HttpCoreContext context;
+    private final HttpProcessor httpProcessor;
     private final HttpRequestExecutor httpexecutor;
     private final ConnectionReuseStrategy connstrategy;
     private final HttpRequest request;
     private final HttpHost targetHost;
-    private final int count;
-    private final boolean keepalive;
+    private final Config config;
     private final SocketFactory socketFactory;
     private final Stats stats = new Stats();
 
     public BenchmarkWorker(
             final HttpRequest request,
             final HttpHost targetHost,
-            int count,
-            boolean keepalive,
-            int verbosity,
-            final SocketFactory socketFactory) {
-
+            final SocketFactory socketFactory,
+            final Config config) {
         super();
-        this.context = new BasicHttpContext(null);
+        this.context = new HttpCoreContext();
         this.request = request;
         this.targetHost = targetHost;
-        this.count = count;
-        this.keepalive = keepalive;
-
-        this.httpProcessor = new BasicHttpProcessor();
+        this.config = config;
+        this.httpProcessor = new ImmutableHttpProcessor(
+                new RequestContent(),
+                new RequestTargetHost(),
+                new RequestConnControl(),
+                new RequestUserAgent("HttpCore-AB/1.1"),
+                new RequestExpectContinue(true));
         this.httpexecutor = new HttpRequestExecutor();
 
-        // Required request interceptors
-        this.httpProcessor.addInterceptor(new RequestContent());
-        this.httpProcessor.addInterceptor(new RequestTargetHost());
-        // Recommended request interceptors
-        this.httpProcessor.addInterceptor(new RequestConnControl());
-        this.httpProcessor.addInterceptor(new RequestUserAgent());
-        this.httpProcessor.addInterceptor(new RequestExpectContinue());
-
-        this.connstrategy = new DefaultConnectionReuseStrategy();
-        this.verbosity = verbosity;
+        this.connstrategy = DefaultConnectionReuseStrategy.INSTANCE;
         this.socketFactory = socketFactory;
     }
 
     public void run() {
-
         HttpResponse response = null;
-        BenchmarkConnection conn = new BenchmarkConnection(this.stats);
+        final BenchmarkConnection conn = new BenchmarkConnection(8 * 1024, stats);
 
-        String scheme = targetHost.getSchemeName();
-        String hostname = targetHost.getHostName();
+        final String scheme = targetHost.getSchemeName();
+        final String hostname = targetHost.getHostName();
         int port = targetHost.getPort();
         if (port == -1) {
             if (scheme.equalsIgnoreCase("https")) {
@@ -128,32 +113,28 @@ class BenchmarkWorker implements Runnable {
         }
 
         // Populate the execution context
-        this.context.setAttribute(ExecutionContext.HTTP_CONNECTION, conn);
-        this.context.setAttribute(ExecutionContext.HTTP_TARGET_HOST, this.targetHost);
-        this.context.setAttribute(ExecutionContext.HTTP_REQUEST, this.request);
+        this.context.setTargetHost(this.targetHost);
 
         stats.start();
+        final int count = config.getRequests();
         for (int i = 0; i < count; i++) {
 
             try {
                 resetHeader(request);
                 if (!conn.isOpen()) {
-                    
-                    Socket socket;
+
+                    final Socket socket;
                     if (socketFactory != null) {
                         socket = socketFactory.createSocket();
                     } else {
                         socket = new Socket();
                     }
-                    
-                    HttpParams params = request.getParams();
-                    int connTimeout = HttpConnectionParams.getConnectionTimeout(params);
-                    int soTimeout = HttpConnectionParams.getSoTimeout(params);
 
-                    socket.setSoTimeout(soTimeout);
-                    socket.connect(new InetSocketAddress(hostname, port), connTimeout);
-                    
-                    conn.bind(socket, params);
+                    final int timeout = config.getSocketTimeout();
+                    socket.setSoTimeout(timeout);
+                    socket.connect(new InetSocketAddress(hostname, port), timeout);
+
+                    conn.bind(socket);
                 }
 
                 try {
@@ -164,9 +145,9 @@ class BenchmarkWorker implements Runnable {
                     // Finalize response
                     this.httpexecutor.postProcess(response, this.httpProcessor, this.context);
 
-                } catch (HttpException e) {
+                } catch (final HttpException e) {
                     stats.incWriteErrors();
-                    if (this.verbosity >= 2) {
+                    if (config.getVerbosity() >= 2) {
                         System.err.println("Failed HTTP request : " + e.getMessage());
                     }
                     conn.shutdown();
@@ -181,20 +162,20 @@ class BenchmarkWorker implements Runnable {
                     stats.incFailureCount();
                 }
 
-                HttpEntity entity = response.getEntity();
+                final HttpEntity entity = response.getEntity();
                 if (entity != null) {
-                    ContentType ct = ContentType.getOrDefault(entity);
+                    final ContentType ct = ContentType.getOrDefault(entity);
                     Charset charset = ct.getCharset();
                     if (charset == null) {
                         charset = HTTP.DEF_CONTENT_CHARSET;
                     }
                     long contentlen = 0;
-                    InputStream instream = entity.getContent();
-                    int l = 0;
+                    final InputStream instream = entity.getContent();
+                    int l;
                     while ((l = instream.read(this.buffer)) != -1) {
                         contentlen += l;
-                        if (this.verbosity >= 4) {
-                            String s = new String(this.buffer, 0, l, charset.name());
+                        if (config.getVerbosity() >= 4) {
+                            final String s = new String(this.buffer, 0, l, charset.name());
                             System.out.print(s);
                         }
                     }
@@ -202,25 +183,25 @@ class BenchmarkWorker implements Runnable {
                     stats.setContentLength(contentlen);
                 }
 
-                if (this.verbosity >= 4) {
+                if (config.getVerbosity() >= 4) {
                     System.out.println();
                     System.out.println();
                 }
 
-                if (!keepalive || !this.connstrategy.keepAlive(response, this.context)) {
+                if (!config.isKeepAlive() || !this.connstrategy.keepAlive(response, this.context)) {
                     conn.close();
                 } else {
                     stats.incKeepAliveCount();
                 }
 
-            } catch (IOException ex) {
+            } catch (final IOException ex) {
                 stats.incFailureCount();
-                if (this.verbosity >= 2) {
+                if (config.getVerbosity() >= 2) {
                     System.err.println("I/O error: " + ex.getMessage());
                 }
-            } catch (Exception ex) {
+            } catch (final Exception ex) {
                 stats.incFailureCount();
-                if (this.verbosity >= 2) {
+                if (config.getVerbosity() >= 2) {
                     System.err.println("Generic error: " + ex.getMessage());
                 }
             }
@@ -229,7 +210,7 @@ class BenchmarkWorker implements Runnable {
         stats.finish();
 
         if (response != null) {
-            Header header = response.getFirstHeader("Server");
+            final Header header = response.getFirstHeader("Server");
             if (header != null) {
                 stats.setServerName(header.getValue());
             }
@@ -237,39 +218,39 @@ class BenchmarkWorker implements Runnable {
 
         try {
             conn.close();
-        } catch (IOException ex) {
+        } catch (final IOException ex) {
             stats.incFailureCount();
-            if (this.verbosity >= 2) {
+            if (config.getVerbosity() >= 2) {
                 System.err.println("I/O error: " + ex.getMessage());
             }
         }
     }
 
-    private void verboseOutput(HttpResponse response) {
-        if (this.verbosity >= 3) {
+    private void verboseOutput(final HttpResponse response) {
+        if (config.getVerbosity() >= 3) {
             System.out.println(">> " + request.getRequestLine().toString());
-            Header[] headers = request.getAllHeaders();
-            for (int h = 0; h < headers.length; h++) {
-                System.out.println(">> " + headers[h].toString());
+            final Header[] headers = request.getAllHeaders();
+            for (final Header header : headers) {
+                System.out.println(">> " + header.toString());
             }
             System.out.println();
         }
-        if (this.verbosity >= 2) {
+        if (config.getVerbosity() >= 2) {
             System.out.println(response.getStatusLine().getStatusCode());
         }
-        if (this.verbosity >= 3) {
+        if (config.getVerbosity() >= 3) {
             System.out.println("<< " + response.getStatusLine().toString());
-            Header[] headers = response.getAllHeaders();
-            for (int h = 0; h < headers.length; h++) {
-                System.out.println("<< " + headers[h].toString());
+            final Header[] headers = response.getAllHeaders();
+            for (final Header header : headers) {
+                System.out.println("<< " + header.toString());
             }
             System.out.println();
         }
     }
 
     private static void resetHeader(final HttpRequest request) {
-        for (HeaderIterator it = request.headerIterator(); it.hasNext();) {
-            Header header = it.nextHeader();
+        for (final HeaderIterator it = request.headerIterator(); it.hasNext();) {
+            final Header header = it.nextHeader();
             if (!(header instanceof DefaultHeader)) {
                 it.remove();
             }
diff --git a/httpcore-ab/src/main/java/org/apache/http/benchmark/CommandLineUtils.java b/httpcore-ab/src/main/java/org/apache/http/benchmark/CommandLineUtils.java
index 235e32a..ccd053d 100644
--- a/httpcore-ab/src/main/java/org/apache/http/benchmark/CommandLineUtils.java
+++ b/httpcore-ab/src/main/java/org/apache/http/benchmark/CommandLineUtils.java
@@ -26,84 +26,84 @@
  */
 package org.apache.http.benchmark;
 
+import java.io.File;
+import java.net.MalformedURLException;
+import java.net.URL;
+
 import org.apache.commons.cli.CommandLine;
 import org.apache.commons.cli.HelpFormatter;
 import org.apache.commons.cli.Option;
 import org.apache.commons.cli.Options;
 
-import java.io.File;
-import java.net.MalformedURLException;
-import java.net.URL;
-
 public class CommandLineUtils {
 
     public static Options getOptions() {
-        Option iopt = new Option("i", false, "Do HEAD requests instead of GET (deprecated)");
+        final Option iopt = new Option("i", false, "Do HEAD requests instead of GET (deprecated)");
         iopt.setRequired(false);
 
-        Option oopt = new Option("o", false, "Use HTTP/S 1.0 instead of 1.1 (default)");
+        final Option oopt = new Option("o", false, "Use HTTP/S 1.0 instead of 1.1 (default)");
         oopt.setRequired(false);
 
-        Option kopt = new Option("k", false, "Enable the HTTP KeepAlive feature, " +
+        final Option kopt = new Option("k", false, "Enable the HTTP KeepAlive feature, " +
             "i.e., perform multiple requests within one HTTP session. " +
             "Default is no KeepAlive");
         kopt.setRequired(false);
 
-        Option uopt = new Option("u", false, "Chunk entity. Default is false");
+        final Option uopt = new Option("u", false, "Chunk entity. Default is false");
         uopt.setRequired(false);
 
-        Option xopt = new Option("x", false, "Use Expect-Continue. Default is false");
+        final Option xopt = new Option("x", false, "Use Expect-Continue. Default is false");
         xopt.setRequired(false);
 
-        Option gopt = new Option("g", false, "Accept GZip. Default is false");
+        final Option gopt = new Option("g", false, "Accept GZip. Default is false");
         gopt.setRequired(false);
 
-        Option nopt = new Option("n", true, "Number of requests to perform for the " +
+        final Option nopt = new Option("n", true, "Number of requests to perform for the " +
             "benchmarking session. The default is to just perform a single " +
             "request which usually leads to non-representative benchmarking " +
             "results");
         nopt.setRequired(false);
         nopt.setArgName("requests");
 
-        Option copt = new Option("c", true, "Concurrency while performing the " +
+        final Option copt = new Option("c", true, "Concurrency while performing the " +
             "benchmarking session. The default is to just use a single thread/client");
         copt.setRequired(false);
         copt.setArgName("concurrency");
 
-        Option popt = new Option("p", true, "File containing data to POST or PUT");
+        final Option popt = new Option("p", true, "File containing data to POST or PUT");
         popt.setRequired(false);
         popt.setArgName("Payload file");
 
-        Option mopt = new Option("m", true, "HTTP Method. Default is POST. " +
+        final Option mopt = new Option("m", true, "HTTP Method. Default is POST. " +
                 "Possible options are GET, POST, PUT, DELETE, HEAD, OPTIONS, TRACE");
         mopt.setRequired(false);
         mopt.setArgName("HTTP method");
 
-        Option Topt = new Option("T", true, "Content-type header to use for POST/PUT data");
+        final Option Topt = new Option("T", true, "Content-type header to use for POST/PUT data");
         Topt.setRequired(false);
         Topt.setArgName("content-type");
 
-        Option topt = new Option("t", true, "Client side socket timeout (in ms) - default 60 Secs");
+        final Option topt = new Option("t", true, "Client side socket timeout (in ms) - default 60 Secs");
         topt.setRequired(false);
         topt.setArgName("socket-Timeout");
 
-        Option Hopt = new Option("H", true, "Add arbitrary header line, " +
+        final Option Hopt = new Option("H", true, "Add arbitrary header line, " +
             "eg. 'Accept-Encoding: gzip' inserted after all normal " +
             "header lines. (repeatable as -H \"h1: v1\",\"h2: v2\" etc)");
         Hopt.setRequired(false);
         Hopt.setArgName("header");
 
-        Option vopt = new Option("v", true, "Set verbosity level - 4 and above " +
+        final Option vopt = new Option("v", true, "Set verbosity level - 4 and above " +
             "prints response content, 3 and above prints " +
             "information on headers, 2 and above prints response codes (404, 200, " +
             "etc.), 1 and above prints warnings and info");
         vopt.setRequired(false);
         vopt.setArgName("verbosity");
 
-        Option hopt = new Option("h", false, "Display usage information");
+        final Option hopt = new Option("h", false, "Display usage information");
         nopt.setRequired(false);
 
-        Options options = new Options();
+        final Options options = new Options();
         options.addOption(iopt);
         options.addOption(mopt);
         options.addOption(uopt);
@@ -122,12 +122,12 @@ public class CommandLineUtils {
         return options;
     }
 
-    public static void parseCommandLine(CommandLine cmd, Config config) {
+    public static void parseCommandLine(final CommandLine cmd, final Config config) {
         if (cmd.hasOption('v')) {
-            String s = cmd.getOptionValue('v');
+            final String s = cmd.getOptionValue('v');
             try {
                 config.setVerbosity(Integer.parseInt(s));
-            } catch (NumberFormatException ex) {
+            } catch (final NumberFormatException ex) {
                 printError("Invalid verbosity level: " + s);
             }
         }
@@ -137,25 +137,25 @@ public class CommandLineUtils {
         }
 
         if (cmd.hasOption('c')) {
-            String s = cmd.getOptionValue('c');
+            final String s = cmd.getOptionValue('c');
             try {
                 config.setThreads(Integer.parseInt(s));
-            } catch (NumberFormatException ex) {
+            } catch (final NumberFormatException ex) {
                 printError("Invalid number for concurrency: " + s);
             }
         }
 
         if (cmd.hasOption('n')) {
-            String s = cmd.getOptionValue('n');
+            final String s = cmd.getOptionValue('n');
             try {
                 config.setRequests(Integer.parseInt(s));
-            } catch (NumberFormatException ex) {
+            } catch (final NumberFormatException ex) {
                 printError("Invalid number of requests: " + s);
             }
         }
 
         if (cmd.hasOption('p')) {
-            File file = new File(cmd.getOptionValue('p'));
+            final File file = new File(cmd.getOptionValue('p'));
             if (!file.exists()) {
                 printError("File not found: " + file);
             }
@@ -171,15 +171,15 @@ public class CommandLineUtils {
         }
 
         if (cmd.hasOption('H')) {
-            String headerStr = cmd.getOptionValue('H');
+            final String headerStr = cmd.getOptionValue('H');
             config.setHeaders(headerStr.split(","));
         }
 
         if (cmd.hasOption('t')) {
-            String t = cmd.getOptionValue('t');
+            final String t = cmd.getOptionValue('t');
             try {
                 config.setSocketTimeout(Integer.parseInt(t));
-            } catch (NumberFormatException ex) {
+            } catch (final NumberFormatException ex) {
                 printError("Invalid socket timeout: " + t);
             }
         }
@@ -206,22 +206,22 @@ public class CommandLineUtils {
             config.setUseAcceptGZip(true);
         }
 
-        String[] cmdargs = cmd.getArgs();
+        final String[] cmdargs = cmd.getArgs();
         if (cmdargs.length > 0) {
             try {
                 config.setUrl(new URL(cmdargs[0]));
-            } catch (MalformedURLException e) {
+            } catch (final MalformedURLException e) {
                 printError("Invalid request URL : " + cmdargs[0]);
             }
         }
     }
 
     static void showUsage(final Options options) {
-        HelpFormatter formatter = new HelpFormatter();
+        final HelpFormatter formatter = new HelpFormatter();
         formatter.printHelp("HttpBenchmark [options] [http://]hostname[:port]/path?query", options);
     }
 
-    static void printError(String msg) {
+    static void printError(final String msg) {
         System.err.println(msg);
         showUsage(getOptions());
         System.exit(-1);
diff --git a/httpcore-ab/src/main/java/org/apache/http/benchmark/Config.java b/httpcore-ab/src/main/java/org/apache/http/benchmark/Config.java
index 5d7407c..b28a1fc 100644
--- a/httpcore-ab/src/main/java/org/apache/http/benchmark/Config.java
+++ b/httpcore-ab/src/main/java/org/apache/http/benchmark/Config.java
@@ -75,7 +75,7 @@ public class Config {
         return url;
     }
 
-    public void setUrl(URL url) {
+    public void setUrl(final URL url) {
         this.url = url;
     }
 
@@ -83,7 +83,7 @@ public class Config {
         return requests;
     }
 
-    public void setRequests(int requests) {
+    public void setRequests(final int requests) {
         this.requests = requests;
     }
 
@@ -91,7 +91,7 @@ public class Config {
         return threads;
     }
 
-    public void setThreads(int threads) {
+    public void setThreads(final int threads) {
         this.threads = threads;
     }
 
@@ -99,7 +99,7 @@ public class Config {
         return keepAlive;
     }
 
-    public void setKeepAlive(boolean keepAlive) {
+    public void setKeepAlive(final boolean keepAlive) {
         this.keepAlive = keepAlive;
     }
 
@@ -107,7 +107,7 @@ public class Config {
         return verbosity;
     }
 
-    public void setVerbosity(int verbosity) {
+    public void setVerbosity(final int verbosity) {
         this.verbosity = verbosity;
     }
 
@@ -115,7 +115,7 @@ public class Config {
         return headInsteadOfGet;
     }
 
-    public void setHeadInsteadOfGet(boolean headInsteadOfGet) {
+    public void setHeadInsteadOfGet(final boolean headInsteadOfGet) {
         this.headInsteadOfGet = headInsteadOfGet;
         this.method = "HEAD";
     }
@@ -124,7 +124,7 @@ public class Config {
         return useHttp1_0;
     }
 
-    public void setUseHttp1_0(boolean useHttp1_0) {
+    public void setUseHttp1_0(final boolean useHttp1_0) {
         this.useHttp1_0 = useHttp1_0;
     }
 
@@ -132,7 +132,7 @@ public class Config {
         return payloadFile;
     }
 
-    public void setPayloadFile(File payloadFile) {
+    public void setPayloadFile(final File payloadFile) {
         this.payloadFile = payloadFile;
     }
 
@@ -140,7 +140,7 @@ public class Config {
         return contentType;
     }
 
-    public void setContentType(String contentType) {
+    public void setContentType(final String contentType) {
         this.contentType = contentType;
     }
 
@@ -148,7 +148,7 @@ public class Config {
         return headers;
     }
 
-    public void setHeaders(String[] headers) {
+    public void setHeaders(final String[] headers) {
         this.headers = headers;
     }
 
@@ -156,23 +156,23 @@ public class Config {
         return socketTimeout;
     }
 
-    public void setSocketTimeout(int socketTimeout) {
+    public void setSocketTimeout(final int socketTimeout) {
         this.socketTimeout = socketTimeout;
     }
 
-    public void setMethod(String method) {
+    public void setMethod(final String method) {
         this.method = method;
     }
 
-    public void setUseChunking(boolean useChunking) {
+    public void setUseChunking(final boolean useChunking) {
         this.useChunking = useChunking;
     }
 
-    public void setUseExpectContinue(boolean useExpectContinue) {
+    public void setUseExpectContinue(final boolean useExpectContinue) {
         this.useExpectContinue = useExpectContinue;
     }
 
-    public void setUseAcceptGZip(boolean useAcceptGZip) {
+    public void setUseAcceptGZip(final boolean useAcceptGZip) {
         this.useAcceptGZip = useAcceptGZip;
     }
 
@@ -220,31 +220,60 @@ public class Config {
         return identityStorePassword;
     }
 
-    public void setPayloadText(String payloadText) {
+    public void setPayloadText(final String payloadText) {
         this.payloadText = payloadText;
     }
 
-    public void setSoapAction(String soapAction) {
+    public void setSoapAction(final String soapAction) {
         this.soapAction = soapAction;
     }
 
-    public void setDisableSSLVerification(boolean disableSSLVerification) {
+    public void setDisableSSLVerification(final boolean disableSSLVerification) {
         this.disableSSLVerification = disableSSLVerification;
     }
 
-    public void setTrustStorePath(String trustStorePath) {
+    public void setTrustStorePath(final String trustStorePath) {
         this.trustStorePath = trustStorePath;
     }
 
-    public void setIdentityStorePath(String identityStorePath) {
+    public void setIdentityStorePath(final String identityStorePath) {
         this.identityStorePath = identityStorePath;
     }
 
-    public void setTrustStorePassword(String trustStorePassword) {
+    public void setTrustStorePassword(final String trustStorePassword) {
         this.trustStorePassword = trustStorePassword;
     }
 
-    public void setIdentityStorePassword(String identityStorePassword) {
+    public void setIdentityStorePassword(final String identityStorePassword) {
         this.identityStorePassword = identityStorePassword;
     }
+
+    public Config copy() {
+        final Config copy = new Config();
+        copy.url = this.url;
+        copy.requests = this.requests;
+        copy.threads = this.threads;
+        copy.keepAlive = this.keepAlive;
+        copy.verbosity = this.verbosity;
+        copy.headInsteadOfGet = this.headInsteadOfGet;
+        copy.useHttp1_0 = this.useHttp1_0;
+        copy.contentType = this.contentType;
+        copy.headers = this.headers;
+        copy.socketTimeout = this.socketTimeout;
+        copy.method = this.method;
+        copy.useChunking = this.useChunking;
+        copy.useExpectContinue = this.useExpectContinue;
+        copy.useAcceptGZip = this.useAcceptGZip;
+        copy.payloadFile = this.payloadFile;
+        copy.payloadText = this.payloadText;
+        copy.soapAction = this.soapAction;
+
+        copy.disableSSLVerification = this.disableSSLVerification;
+        copy.trustStorePath = this.trustStorePath;
+        copy.identityStorePath = this.identityStorePath;
+        copy.trustStorePassword = this.trustStorePassword;
+        copy.identityStorePassword = this.identityStorePassword;
+        return copy;
+    }
+
 }
diff --git a/httpcore-ab/src/main/java/org/apache/http/benchmark/CountingInputStream.java b/httpcore-ab/src/main/java/org/apache/http/benchmark/CountingInputStream.java
index 2c1d3ff..a234d92 100644
--- a/httpcore-ab/src/main/java/org/apache/http/benchmark/CountingInputStream.java
+++ b/httpcore-ab/src/main/java/org/apache/http/benchmark/CountingInputStream.java
@@ -33,7 +33,7 @@ import java.io.InputStream;
 class CountingInputStream extends FilterInputStream {
 
     private final Stats stats;
-    
+
     CountingInputStream(final InputStream instream, final Stats stats) {
         super(instream);
         this.stats = stats;
@@ -41,7 +41,7 @@ class CountingInputStream extends FilterInputStream {
 
     @Override
     public int read() throws IOException {
-        int b = this.in.read();
+        final int b = this.in.read();
         if (b != -1) {
             this.stats.incTotalBytesRecv(1);
         }
@@ -49,8 +49,8 @@ class CountingInputStream extends FilterInputStream {
     }
 
     @Override
-    public int read(byte[] b) throws IOException {
-        int bytesRead = this.in.read(b);
+    public int read(final byte[] b) throws IOException {
+        final int bytesRead = this.in.read(b);
         if (bytesRead > 0) {
             this.stats.incTotalBytesRecv(bytesRead);
         }
@@ -58,8 +58,8 @@ class CountingInputStream extends FilterInputStream {
     }
 
     @Override
-    public int read(byte[] b, int off, int len) throws IOException {
-        int bytesRead = this.in.read(b, off, len);
+    public int read(final byte[] b, final int off, final int len) throws IOException {
+        final int bytesRead = this.in.read(b, off, len);
         if (bytesRead > 0) {
             this.stats.incTotalBytesRecv(bytesRead);
         }
@@ -67,12 +67,12 @@ class CountingInputStream extends FilterInputStream {
     }
 
     @Override
-    public long skip(long n) throws IOException {
-        long bytesRead = this.in.skip(n);
+    public long skip(final long n) throws IOException {
+        final long bytesRead = this.in.skip(n);
         if (bytesRead > 0) {
             this.stats.incTotalBytesRecv(bytesRead);
         }
         return bytesRead;
     }
-    
+
 }
diff --git a/httpcore-ab/src/main/java/org/apache/http/benchmark/CountingOutputStream.java b/httpcore-ab/src/main/java/org/apache/http/benchmark/CountingOutputStream.java
index afe648d..6544a59 100644
--- a/httpcore-ab/src/main/java/org/apache/http/benchmark/CountingOutputStream.java
+++ b/httpcore-ab/src/main/java/org/apache/http/benchmark/CountingOutputStream.java
@@ -33,28 +33,28 @@ import java.io.OutputStream;
 class CountingOutputStream extends FilterOutputStream {
 
     private final Stats stats;
-    
+
     CountingOutputStream(final OutputStream outstream, final Stats stats) {
         super(outstream);
         this.stats = stats;
     }
 
     @Override
-    public void write(int b) throws IOException {
+    public void write(final int b) throws IOException {
         this.out.write(b);
         this.stats.incTotalBytesSent(1);
     }
 
     @Override
-    public void write(byte[] b) throws IOException {
+    public void write(final byte[] b) throws IOException {
         this.out.write(b);
         this.stats.incTotalBytesSent(b.length);
     }
 
     @Override
-    public void write(byte[] b, int off, int len) throws IOException {
+    public void write(final byte[] b, final int off, final int len) throws IOException {
         this.out.write(b, off, len);
         this.stats.incTotalBytesSent(len);
     }
-    
+
 }
diff --git a/httpcore-ab/src/main/java/org/apache/http/benchmark/HttpBenchmark.java b/httpcore-ab/src/main/java/org/apache/http/benchmark/HttpBenchmark.java
index 1587052..b4e1295 100644
--- a/httpcore-ab/src/main/java/org/apache/http/benchmark/HttpBenchmark.java
+++ b/httpcore-ab/src/main/java/org/apache/http/benchmark/HttpBenchmark.java
@@ -29,25 +29,6 @@ package org.apache.http.benchmark;
 import java.io.FileInputStream;
 import java.io.IOException;
 import java.net.URL;
-
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.CommandLineParser;
-import org.apache.commons.cli.Options;
-import org.apache.commons.cli.PosixParser;
-import org.apache.http.Header;
-import org.apache.http.HttpHost;
-import org.apache.http.HttpRequest;
-import org.apache.http.HttpVersion;
-import org.apache.http.entity.ContentType;
-import org.apache.http.entity.FileEntity;
-import org.apache.http.message.BasicHttpEntityEnclosingRequest;
-import org.apache.http.message.BasicHttpRequest;
-import org.apache.http.params.BasicHttpParams;
-import org.apache.http.params.HttpConnectionParams;
-import org.apache.http.params.HttpParams;
-import org.apache.http.params.HttpProtocolParams;
-import org.apache.http.protocol.HTTP;
-
 import java.security.KeyStore;
 import java.util.concurrent.LinkedBlockingQueue;
 import java.util.concurrent.ThreadFactory;
@@ -62,8 +43,20 @@ import javax.net.ssl.TrustManager;
 import javax.net.ssl.TrustManagerFactory;
 import javax.net.ssl.X509TrustManager;
 
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.CommandLineParser;
+import org.apache.commons.cli.Options;
+import org.apache.commons.cli.PosixParser;
+import org.apache.http.Header;
 import org.apache.http.HttpEntity;
+import org.apache.http.HttpHost;
+import org.apache.http.HttpRequest;
+import org.apache.http.entity.ContentType;
+import org.apache.http.entity.FileEntity;
 import org.apache.http.entity.StringEntity;
+import org.apache.http.message.BasicHttpEntityEnclosingRequest;
+import org.apache.http.message.BasicHttpRequest;
+import org.apache.http.protocol.HTTP;
 
 /**
  * Main program of the HTTP benchmark.
@@ -75,18 +68,18 @@ public class HttpBenchmark {
 
     private final Config config;
 
-    public static void main(String[] args) throws Exception {
+    public static void main(final String[] args) throws Exception {
 
-        Options options = CommandLineUtils.getOptions();
-        CommandLineParser parser = new PosixParser();
-        CommandLine cmd = parser.parse(options, args);
+        final Options options = CommandLineUtils.getOptions();
+        final CommandLineParser parser = new PosixParser();
+        final CommandLine cmd = parser.parse(options, args);
 
         if (args.length == 0 || cmd.hasOption('h') || cmd.getArgs().length != 1) {
             CommandLineUtils.showUsage(options);
             System.exit(1);
         }
 
-        Config config = new Config();
+        final Config config = new Config();
         CommandLineUtils.parseCommandLine(cmd, config);
 
         if (config.getUrl() == null) {
@@ -94,7 +87,7 @@ public class HttpBenchmark {
             System.exit(1);
         }
 
-        HttpBenchmark httpBenchmark = new HttpBenchmark(config);
+        final HttpBenchmark httpBenchmark = new HttpBenchmark(config);
         httpBenchmark.execute();
     }
 
@@ -104,37 +97,29 @@ public class HttpBenchmark {
     }
 
     private HttpRequest createRequest() {
-        HttpParams params = new BasicHttpParams();
-        params.setParameter(HttpProtocolParams.PROTOCOL_VERSION,
-                config.isUseHttp1_0() ? HttpVersion.HTTP_1_0 : HttpVersion.HTTP_1_1)
-            .setParameter(HttpProtocolParams.USER_AGENT, "HttpCore-AB/1.1")
-            .setBooleanParameter(HttpProtocolParams.USE_EXPECT_CONTINUE, config.isUseExpectContinue())
-            .setBooleanParameter(HttpConnectionParams.STALE_CONNECTION_CHECK, false)
-            .setIntParameter(HttpConnectionParams.SO_TIMEOUT, config.getSocketTimeout());
-
-        URL url = config.getUrl();
+        final URL url = config.getUrl();
         HttpEntity entity = null;
 
         // Prepare requests for each thread
         if (config.getPayloadFile() != null) {
-            FileEntity fe = new FileEntity(config.getPayloadFile());
+            final FileEntity fe = new FileEntity(config.getPayloadFile());
             fe.setContentType(config.getContentType());
             fe.setChunked(config.isUseChunking());
             entity = fe;
         } else if (config.getPayloadText() != null) {
-            StringEntity se = new StringEntity(config.getPayloadText(), 
+            final StringEntity se = new StringEntity(config.getPayloadText(),
                     ContentType.parse(config.getContentType()));
             se.setChunked(config.isUseChunking());
             entity = se;
         }
-        HttpRequest request;
+        final HttpRequest request;
         if ("POST".equals(config.getMethod())) {
-            BasicHttpEntityEnclosingRequest httppost =
+            final BasicHttpEntityEnclosingRequest httppost =
                     new BasicHttpEntityEnclosingRequest("POST", url.getPath());
             httppost.setEntity(entity);
             request = httppost;
         } else if ("PUT".equals(config.getMethod())) {
-            BasicHttpEntityEnclosingRequest httpput =
+            final BasicHttpEntityEnclosingRequest httpput =
                     new BasicHttpEntityEnclosingRequest("PUT", url.getPath());
             httpput.setEntity(entity);
             request = httpput;
@@ -152,13 +137,12 @@ public class HttpBenchmark {
             request.addHeader(new DefaultHeader(HTTP.CONN_DIRECTIVE, HTTP.CONN_CLOSE));
         }
 
-        String[] headers = config.getHeaders();
+        final String[] headers = config.getHeaders();
         if (headers != null) {
-            for (int i = 0; i < headers.length; i++) {
-                String s = headers[i];
-                int pos = s.indexOf(':');
+            for (final String s : headers) {
+                final int pos = s.indexOf(':');
                 if (pos != -1) {
-                    Header header = new DefaultHeader(s.substring(0, pos).trim(), s.substring(pos + 1));
+                    final Header header = new DefaultHeader(s.substring(0, pos).trim(), s.substring(pos + 1));
                     request.addHeader(header);
                 }
             }
@@ -175,16 +159,22 @@ public class HttpBenchmark {
     }
 
     public String execute() throws Exception {
+        final Results results = doExecute();
+        ResultProcessor.printResults(results);
+        return "";
+    }
+
+    public Results doExecute() throws Exception {
 
-        URL url = config.getUrl();
-        HttpHost host = new HttpHost(url.getHost(), url.getPort(), url.getProtocol());
+        final URL url = config.getUrl();
+        final HttpHost host = new HttpHost(url.getHost(), url.getPort(), url.getProtocol());
 
-        ThreadPoolExecutor workerPool = new ThreadPoolExecutor(
+        final ThreadPoolExecutor workerPool = new ThreadPoolExecutor(
                 config.getThreads(), config.getThreads(), 5, TimeUnit.SECONDS,
             new LinkedBlockingQueue<Runnable>(),
             new ThreadFactory() {
 
-                public Thread newThread(Runnable r) {
+                public Thread newThread(final Runnable r) {
                     return new Thread(r, "ClientPool");
                 }
 
@@ -204,58 +194,56 @@ public class HttpBenchmark {
                         }
 
                         public void checkClientTrusted(
-                            java.security.cert.X509Certificate[] certs, String authType) {
+                            final java.security.cert.X509Certificate[] certs, final String authType) {
                         }
 
                         public void checkServerTrusted(
-                            java.security.cert.X509Certificate[] certs, String authType) {
+                            final java.security.cert.X509Certificate[] certs, final String authType) {
                         }
                     }
                 };
             } else if (config.getTrustStorePath() != null) {
-                KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
-                FileInputStream instream = new FileInputStream(config.getTrustStorePath());
+                final KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
+                final FileInputStream instream = new FileInputStream(config.getTrustStorePath());
                 try {
-                    trustStore.load(instream, config.getTrustStorePath() != null ? 
+                    trustStore.load(instream, config.getTrustStorePath() != null ?
                             config.getTrustStorePath().toCharArray() : null);
                 } finally {
-                    try { instream.close(); } catch (IOException ignore) {}
+                    try { instream.close(); } catch (final IOException ignore) {}
                 }
-                TrustManagerFactory tmfactory = TrustManagerFactory.getInstance(
+                final TrustManagerFactory tmfactory = TrustManagerFactory.getInstance(
                         TrustManagerFactory.getDefaultAlgorithm());
                 tmfactory.init(trustStore);
                 trustManagers = tmfactory.getTrustManagers();
             }
             KeyManager[] keyManagers = null;
             if (config.getIdentityStorePath() != null) {
-                KeyStore identityStore = KeyStore.getInstance(KeyStore.getDefaultType());
-                FileInputStream instream = new FileInputStream(config.getIdentityStorePath());
+                final KeyStore identityStore = KeyStore.getInstance(KeyStore.getDefaultType());
+                final FileInputStream instream = new FileInputStream(config.getIdentityStorePath());
                 try {
                     identityStore.load(instream, config.getIdentityStorePassword() != null ?
                             config.getIdentityStorePassword().toCharArray() : null);
                 } finally {
-                    try { instream.close(); } catch (IOException ignore) {}
+                    try { instream.close(); } catch (final IOException ignore) {}
                 }
-                KeyManagerFactory kmf = KeyManagerFactory.getInstance(
+                final KeyManagerFactory kmf = KeyManagerFactory.getInstance(
                     KeyManagerFactory.getDefaultAlgorithm());
                 kmf.init(identityStore, config.getIdentityStorePassword() != null ?
                         config.getIdentityStorePassword().toCharArray() : null);
                 keyManagers = kmf.getKeyManagers();
             }
-            SSLContext sc = SSLContext.getInstance("SSL");
+            final SSLContext sc = SSLContext.getInstance("SSL");
             sc.init(keyManagers, trustManagers, null);
             socketFactory = sc.getSocketFactory();
         }
-        
-        BenchmarkWorker[] workers = new BenchmarkWorker[config.getThreads()];
+
+        final BenchmarkWorker[] workers = new BenchmarkWorker[config.getThreads()];
         for (int i = 0; i < workers.length; i++) {
             workers[i] = new BenchmarkWorker(
                     createRequest(),
                     host,
-                    config.getRequests(),
-                    config.isKeepAlive(),
-                    config.getVerbosity(),
-                    socketFactory);
+                    socketFactory,
+                    config);
             workerPool.execute(workers[i]);
         }
 
@@ -263,12 +251,12 @@ public class HttpBenchmark {
             Thread.yield();
             try {
                 Thread.sleep(1000);
-            } catch (InterruptedException ignore) {
+            } catch (final InterruptedException ignore) {
             }
         }
 
         workerPool.shutdown();
-        return ResultProcessor.printResults(workers, host, config.getUrl().toString());
+        return ResultProcessor.collectResults(workers, host, config.getUrl().toString());
     }
 
 }
diff --git a/httpcore-ab/src/main/java/org/apache/http/benchmark/ResultProcessor.java b/httpcore-ab/src/main/java/org/apache/http/benchmark/ResultProcessor.java
index 6413f32..e4bebd3 100644
--- a/httpcore-ab/src/main/java/org/apache/http/benchmark/ResultProcessor.java
+++ b/httpcore-ab/src/main/java/org/apache/http/benchmark/ResultProcessor.java
@@ -26,10 +26,10 @@
  */
 package org.apache.http.benchmark;
 
-import org.apache.http.HttpHost;
-
 import java.text.NumberFormat;
 
+import org.apache.http.HttpHost;
+
 public class ResultProcessor {
 
     static NumberFormat nf2 = NumberFormat.getInstance();
@@ -45,9 +45,8 @@ public class ResultProcessor {
         nf6.setMinimumFractionDigits(6);
     }
 
-    static String printResults(BenchmarkWorker[] workers, HttpHost host, String uri) {
-
-        double totalTimeNano = 0;
+    static Results collectResults(final BenchmarkWorker[] workers, final HttpHost host, final String uri) {
+        long totalTimeNano = 0;
         long successCount    = 0;
         long failureCount    = 0;
         long writeErrors     = 0;
@@ -55,10 +54,10 @@ public class ResultProcessor {
         long totalBytesRcvd  = 0;
         long totalBytesSent  = 0;
 
-        Stats stats = workers[0].getStats();
+        final Stats stats = workers[0].getStats();
 
-        for (int i = 0; i < workers.length; i++) {
-            Stats s = workers[i].getStats();
+        for (final BenchmarkWorker worker : workers) {
+            final Stats s = worker.getStats();
             totalTimeNano  += s.getDuration();
             successCount   += s.getSuccessCount();
             failureCount   += s.getFailureCount();
@@ -68,44 +67,56 @@ public class ResultProcessor {
             totalBytesSent += s.getTotalBytesSent();
         }
 
-        int threads = workers.length;
-        double totalTimeMs  = (totalTimeNano / threads) / 1000000; // convert nano secs to milli secs
-        double timePerReqMs = totalTimeMs / successCount;
-        double totalTimeSec = totalTimeMs / 1000;
-        double reqsPerSec   = successCount / totalTimeSec;
-        long totalBytes     = totalBytesRcvd + (totalBytesSent > 0 ? totalBytesSent : 0);
+        final Results results = new Results();
+        results.serverName = stats.getServerName();
+        results.hostName = host.getHostName();
+        results.hostPort = host.getPort() > 0 ? host.getPort() :
+            host.getSchemeName().equalsIgnoreCase("https") ? 443 : 80;
+        results.documentPath = uri;
+        results.contentLength = stats.getContentLength();
+        results.concurrencyLevel = workers.length;
+        results.totalTimeNano = totalTimeNano;
+        results.successCount = successCount;
+        results.failureCount = failureCount;
+        results.writeErrors = writeErrors;
+        results.keepAliveCount = keepAliveCount;
+        results.totalBytesRcvd = totalBytesRcvd;
+        results.totalBytesSent = totalBytesSent;
+        results.totalBytes = totalBytesRcvd + (totalBytesSent > 0 ? totalBytesSent : 0);
+        return results;
+    }
 
-        StringBuilder sb = new StringBuilder(1024);
+    static void printResults(final Results results) {
+        final int threads = results.getConcurrencyLevel();
+        final double totalTimeMs  = (results.getTotalTimeNano() / threads) / 1000000; // convert nano secs to milli secs
+        final double timePerReqMs = totalTimeMs / results.getSuccessCount();
+        final double totalTimeSec = totalTimeMs / 1000;
+        final double reqsPerSec   = results.getSuccessCount() / totalTimeSec;
 
-        printAndAppend(sb,"\nServer Software:\t\t" + stats.getServerName());
-        printAndAppend(sb, "Server Hostname:\t\t" + host.getHostName());
-        printAndAppend(sb, "Server Port:\t\t\t" +
-            (host.getPort() > 0 ? Integer.valueOf(host.getPort()) : uri.startsWith("https") ? "443" : "80") + "\n");
-        printAndAppend(sb, "Document Path:\t\t\t" + uri);
-        printAndAppend(sb, "Document Length:\t\t" + stats.getContentLength() + " bytes\n");
-        printAndAppend(sb, "Concurrency Level:\t\t" + workers.length);
-        printAndAppend(sb, "Time taken for tests:\t\t" + nf6.format(totalTimeSec) + " seconds");
-        printAndAppend(sb, "Complete requests:\t\t" + successCount);
-        printAndAppend(sb, "Failed requests:\t\t" + failureCount);
-        printAndAppend(sb, "Write errors:\t\t\t" + writeErrors);
-        printAndAppend(sb, "Kept alive:\t\t\t" + keepAliveCount);
-        printAndAppend(sb, "Total transferred:\t\t" + totalBytes + " bytes");
-        printAndAppend(sb, "Requests per second:\t\t" + nf2.format(reqsPerSec) + " [#/sec] (mean)");
-        printAndAppend(sb, "Time per request:\t\t" + nf3.format(timePerReqMs * workers.length) + " [ms] (mean)");
-        printAndAppend(sb, "Time per request:\t\t" + nf3.format(timePerReqMs) +
+        System.out.println("\nServer Software:\t\t" + results.getServerName());
+        System.out.println( "Server Hostname:\t\t" + results.getHostName());
+        System.out.println( "Server Port:\t\t\t" + Integer.valueOf(results.getHostPort()));
+        System.out.println( "Document Path:\t\t\t" + results.getDocumentPath());
+        System.out.println( "Document Length:\t\t" + results.getContentLength() + " bytes\n");
+        System.out.println( "Concurrency Level:\t\t" + results.getConcurrencyLevel());
+        System.out.println( "Time taken for tests:\t\t" + nf6.format(totalTimeSec) + " seconds");
+        System.out.println( "Complete requests:\t\t" + results.getSuccessCount());
+        System.out.println( "Failed requests:\t\t" + results.getFailureCount());
+        System.out.println( "Write errors:\t\t\t" + results.getWriteErrors());
+        System.out.println( "Kept alive:\t\t\t" + results.getKeepAliveCount());
+        System.out.println( "Total transferred:\t\t" + results.getTotalBytes() + " bytes");
+        System.out.println( "Requests per second:\t\t" + nf2.format(reqsPerSec) + " [#/sec] (mean)");
+        System.out.println( "Time per request:\t\t" + nf3.format(timePerReqMs
+                * results.getConcurrencyLevel()) + " [ms] (mean)");
+        System.out.println( "Time per request:\t\t" + nf3.format(timePerReqMs) +
             " [ms] (mean, across all concurrent requests)");
-        printAndAppend(sb, "Transfer rate:\t\t\t" +
-            nf2.format(totalBytesRcvd/1000/totalTimeSec) + " [Kbytes/sec] received");
-        printAndAppend(sb, "\t\t\t\t" +
-            (totalBytesSent > 0 ? nf2.format(totalBytesSent/1000/totalTimeSec) : Integer.valueOf(-1)) + " kb/s sent");
-        printAndAppend(sb, "\t\t\t\t" +
-            nf2.format(totalBytes/1000/totalTimeSec) + " kb/s total");
-
-        return sb.toString();
+        System.out.println( "Transfer rate:\t\t\t" +
+            nf2.format(results.getTotalBytesRcvd() / 1000 / totalTimeSec) + " [Kbytes/sec] received");
+        System.out.println( "\t\t\t\t" +
+            (results.getTotalBytesSent() > 0 ? nf2.format(results.getTotalBytesSent()
+                    / 1000 / totalTimeSec) : Integer.valueOf(-1)) + " kb/s sent");
+        System.out.println( "\t\t\t\t" +
+            nf2.format(results.getTotalBytes() / 1000 / totalTimeSec) + " kb/s total");
     }
 
-    private static void printAndAppend(StringBuilder sb, String s) {
-        System.out.println(s);
-        sb.append(s).append("\r\n");
-    }
 }
diff --git a/httpcore-ab/src/main/java/org/apache/http/benchmark/Results.java b/httpcore-ab/src/main/java/org/apache/http/benchmark/Results.java
new file mode 100644
index 0000000..ad4c627
--- /dev/null
+++ b/httpcore-ab/src/main/java/org/apache/http/benchmark/Results.java
@@ -0,0 +1,133 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+package org.apache.http.benchmark;
+
+/**
+ * Benchmark results
+ *
+ * @since 4.3
+ */
+public final class Results {
+
+    String serverName;
+    String hostName;
+    int hostPort;
+    String documentPath;
+    long contentLength;
+    int concurrencyLevel;
+    long totalTimeNano;
+    long successCount;
+    long failureCount;
+    long writeErrors;
+    long keepAliveCount;
+    long totalBytesRcvd;
+    long totalBytesSent;
+    long totalBytes;
+
+    Results() {
+        super();
+        this.contentLength = -1;
+    }
+
+    public String getServerName() {
+        return serverName;
+    }
+
+    public String getHostName() {
+        return hostName;
+    }
+
+    public int getHostPort() {
+        return hostPort;
+    }
+
+    public String getDocumentPath() {
+        return documentPath;
+    }
+
+    public long getContentLength() {
+        return contentLength;
+    }
+
+    public int getConcurrencyLevel() {
+        return concurrencyLevel;
+    }
+
+    public long getTotalTimeNano() {
+        return totalTimeNano;
+    }
+
+    public long getSuccessCount() {
+        return successCount;
+    }
+
+    public long getFailureCount() {
+        return failureCount;
+    }
+
+    public long getWriteErrors() {
+        return writeErrors;
+    }
+
+    public long getKeepAliveCount() {
+        return keepAliveCount;
+    }
+
+    public long getTotalBytesRcvd() {
+        return totalBytesRcvd;
+    }
+
+    public long getTotalBytesSent() {
+        return totalBytesSent;
+    }
+
+    public long getTotalBytes() {
+        return totalBytes;
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder builder = new StringBuilder();
+        builder.append("[serverName=").append(serverName)
+                .append(", hostName=").append(hostName)
+                .append(", hostPort=").append(hostPort)
+                .append(", documentPath=").append(documentPath)
+                .append(", contentLength=").append(contentLength)
+                .append(", concurrencyLevel=").append(concurrencyLevel)
+                .append(", totalTimeNano=").append(totalTimeNano)
+                .append(", successCount=").append(successCount)
+                .append(", failureCount=").append(failureCount)
+                .append(", writeErrors=").append(writeErrors)
+                .append(", keepAliveCount=").append(keepAliveCount)
+                .append(", totalBytesRcvd=").append(totalBytesRcvd)
+                .append(", totalBytesSent=").append(totalBytesSent)
+                .append(", totalBytes=").append(totalBytes)
+                .append("]");
+        return builder.toString();
+    }
+
+}
diff --git a/httpcore-ab/src/main/java/org/apache/http/benchmark/Stats.java b/httpcore-ab/src/main/java/org/apache/http/benchmark/Stats.java
index e32d91f..0228eb0 100644
--- a/httpcore-ab/src/main/java/org/apache/http/benchmark/Stats.java
+++ b/httpcore-ab/src/main/java/org/apache/http/benchmark/Stats.java
@@ -112,7 +112,7 @@ public class Stats {
         return this.totalBytesRecv;
     }
 
-    public void incTotalBytesRecv(long n) {
+    public void incTotalBytesRecv(final long n) {
         this.totalBytesRecv += n;
     }
 
@@ -120,7 +120,7 @@ public class Stats {
         return this.totalBytesSent;
     }
 
-    public void incTotalBytesSent(long n) {
+    public void incTotalBytesSent(final long n) {
         this.totalBytesSent += n;
     }
 
@@ -128,7 +128,7 @@ public class Stats {
         return this.contentLength;
     }
 
-    public void setContentLength(long contentLength) {
+    public void setContentLength(final long contentLength) {
         this.contentLength = contentLength;
     }
 
diff --git a/httpcore/src/test/java/org/apache/http/testserver/HttpServer.java b/httpcore-ab/src/test/java/org/apache/http/benchmark/HttpServer.java
similarity index 64%
copy from httpcore/src/test/java/org/apache/http/testserver/HttpServer.java
copy to httpcore-ab/src/test/java/org/apache/http/benchmark/HttpServer.java
index e5f1e31..6042b5a 100644
--- a/httpcore/src/test/java/org/apache/http/testserver/HttpServer.java
+++ b/httpcore-ab/src/test/java/org/apache/http/benchmark/HttpServer.java
@@ -25,7 +25,7 @@
  *
  */
 
-package org.apache.http.testserver;
+package org.apache.http.benchmark;
 
 import java.io.IOException;
 import java.io.InterruptedIOException;
@@ -34,64 +34,44 @@ import java.net.ServerSocket;
 import java.net.Socket;
 
 import org.apache.http.ConnectionClosedException;
-import org.apache.http.ConnectionReuseStrategy;
 import org.apache.http.HttpException;
-import org.apache.http.HttpResponseFactory;
 import org.apache.http.HttpResponseInterceptor;
 import org.apache.http.HttpServerConnection;
+import org.apache.http.impl.DefaultBHttpServerConnection;
 import org.apache.http.impl.DefaultConnectionReuseStrategy;
 import org.apache.http.impl.DefaultHttpResponseFactory;
-import org.apache.http.impl.DefaultHttpServerConnection;
-import org.apache.http.params.CoreConnectionPNames;
-import org.apache.http.params.HttpParams;
-import org.apache.http.params.CoreProtocolPNames;
-import org.apache.http.params.SyncBasicHttpParams;
-import org.apache.http.protocol.HttpContext;
 import org.apache.http.protocol.BasicHttpContext;
-import org.apache.http.protocol.HttpExpectationVerifier;
+import org.apache.http.protocol.HttpContext;
 import org.apache.http.protocol.HttpProcessor;
 import org.apache.http.protocol.HttpRequestHandler;
-import org.apache.http.protocol.HttpRequestHandlerRegistry;
 import org.apache.http.protocol.HttpService;
 import org.apache.http.protocol.ImmutableHttpProcessor;
 import org.apache.http.protocol.ResponseConnControl;
 import org.apache.http.protocol.ResponseContent;
 import org.apache.http.protocol.ResponseDate;
 import org.apache.http.protocol.ResponseServer;
+import org.apache.http.protocol.UriHttpRequestHandlerMapper;
+import org.apache.http.util.Asserts;
 
 public class HttpServer {
 
-    private final HttpParams params;
     private final HttpProcessor httpproc;
-    private final ConnectionReuseStrategy connStrategy;
-    private final HttpResponseFactory responseFactory;
-    private final HttpRequestHandlerRegistry reqistry;
+    private final UriHttpRequestHandlerMapper reqistry;
     private final ServerSocket serversocket;
 
-    private HttpExpectationVerifier expectationVerifier;
-
     private Thread listener;
     private volatile boolean shutdown;
 
     public HttpServer() throws IOException {
         super();
-        this.params = new SyncBasicHttpParams();
-        this.params
-            .setIntParameter(CoreConnectionPNames.SO_TIMEOUT, 5000)
-            .setIntParameter(CoreConnectionPNames.SOCKET_BUFFER_SIZE, 8 * 1024)
-            .setBooleanParameter(CoreConnectionPNames.STALE_CONNECTION_CHECK, false)
-            .setBooleanParameter(CoreConnectionPNames.TCP_NODELAY, true)
-            .setParameter(CoreProtocolPNames.ORIGIN_SERVER, "TEST-SERVER/1.1");
         this.httpproc = new ImmutableHttpProcessor(
                 new HttpResponseInterceptor[] {
                         new ResponseDate(),
-                        new ResponseServer(),
+                        new ResponseServer("TEST-SERVER/1.1"),
                         new ResponseContent(),
                         new ResponseConnControl()
                 });
-        this.connStrategy = new DefaultConnectionReuseStrategy();
-        this.responseFactory = new DefaultHttpResponseFactory();
-        this.reqistry = new HttpRequestHandlerRegistry();
+        this.reqistry = new UriHttpRequestHandlerMapper();
         this.serversocket = new ServerSocket(0);
     }
 
@@ -101,14 +81,10 @@ public class HttpServer {
         this.reqistry.register(pattern, handler);
     }
 
-    public void setExpectationVerifier(final HttpExpectationVerifier expectationVerifier) {
-        this.expectationVerifier = expectationVerifier;
-    }
-
     private HttpServerConnection acceptConnection() throws IOException {
-        Socket socket = this.serversocket.accept();
-        DefaultHttpServerConnection conn = new DefaultHttpServerConnection();
-        conn.bind(socket, this.params);
+        final Socket socket = this.serversocket.accept();
+        final DefaultBHttpServerConnection conn = new DefaultBHttpServerConnection(8 * 1024);
+        conn.bind(socket);
         return conn;
     }
 
@@ -121,31 +97,28 @@ public class HttpServer {
     }
 
     public void start() {
-        if (this.listener != null) {
-            throw new IllegalStateException("Listener already running");
-        }
+        Asserts.check(this.listener == null, "Listener already running");
         this.listener = new Thread(new Runnable() {
 
             public void run() {
                 while (!shutdown && !Thread.interrupted()) {
                     try {
                         // Set up HTTP connection
-                        HttpServerConnection conn = acceptConnection();
+                        final HttpServerConnection conn = acceptConnection();
                         // Set up the HTTP service
-                        HttpService httpService = new HttpService(
+                        final HttpService httpService = new HttpService(
                                 httpproc,
-                                connStrategy,
-                                responseFactory,
+                                DefaultConnectionReuseStrategy.INSTANCE,
+                                DefaultHttpResponseFactory.INSTANCE,
                                 reqistry,
-                                expectationVerifier,
-                                params);
+                                null);
                         // Start worker thread
-                        Thread t = new WorkerThread(httpService, conn);
+                        final Thread t = new WorkerThread(httpService, conn);
                         t.setDaemon(true);
                         t.start();
-                    } catch (InterruptedIOException ex) {
+                    } catch (final InterruptedIOException ex) {
                         break;
-                    } catch (IOException e) {
+                    } catch (final IOException e) {
                         break;
                     }
                 }
@@ -162,11 +135,11 @@ public class HttpServer {
         this.shutdown = true;
         try {
             this.serversocket.close();
-        } catch (IOException ignore) {}
+        } catch (final IOException ignore) {}
         this.listener.interrupt();
         try {
             this.listener.join(1000);
-        } catch (InterruptedException ignore) {}
+        } catch (final InterruptedException ignore) {}
     }
 
     static class WorkerThread extends Thread {
@@ -184,20 +157,20 @@ public class HttpServer {
 
         @Override
         public void run() {
-            HttpContext context = new BasicHttpContext(null);
+            final HttpContext context = new BasicHttpContext(null);
             try {
                 while (!Thread.interrupted() && this.conn.isOpen()) {
                     this.httpservice.handleRequest(this.conn, context);
                 }
-            } catch (ConnectionClosedException ex) {
-            } catch (IOException ex) {
+            } catch (final ConnectionClosedException ex) {
+            } catch (final IOException ex) {
                 System.err.println("I/O error: " + ex.getMessage());
-            } catch (HttpException ex) {
+            } catch (final HttpException ex) {
                 System.err.println("Unrecoverable HTTP protocol violation: " + ex.getMessage());
             } finally {
                 try {
                     this.conn.shutdown();
-                } catch (IOException ignore) {}
+                } catch (final IOException ignore) {}
             }
         }
 
diff --git a/httpcore-ab/src/test/java/org/apache/http/benchmark/SmokeTest.java b/httpcore-ab/src/test/java/org/apache/http/benchmark/SmokeTest.java
new file mode 100644
index 0000000..4e6ebca
--- /dev/null
+++ b/httpcore-ab/src/test/java/org/apache/http/benchmark/SmokeTest.java
@@ -0,0 +1,90 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+package org.apache.http.benchmark;
+
+import java.io.IOException;
+import java.net.URL;
+
+import org.apache.http.HttpException;
+import org.apache.http.HttpRequest;
+import org.apache.http.HttpResponse;
+import org.apache.http.HttpStatus;
+import org.apache.http.entity.ContentType;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.protocol.HttpContext;
+import org.apache.http.protocol.HttpRequestHandler;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+public class SmokeTest {
+
+    private HttpServer server;
+
+    @Before
+    public void setup() throws Exception {
+        server = new HttpServer();
+        server.registerHandler("/", new HttpRequestHandler() {
+            public void handle(
+                    final HttpRequest request,
+                    final HttpResponse response,
+                    final HttpContext context) throws HttpException, IOException {
+                response.setStatusCode(HttpStatus.SC_OK);
+                response.setEntity(new StringEntity("0123456789ABCDEF", ContentType.TEXT_PLAIN));
+            }
+        });
+        server.start();
+    }
+
+    @After
+    public void shutdown() throws Exception {
+        server.shutdown();
+    }
+
+    @Test
+    public void testBasics() throws Exception {
+        final Config config = new Config();
+        config.setKeepAlive(true);
+        config.setMethod("GET");
+        config.setUrl(new URL("http://localhost:" + server.getPort() + "/"));
+        config.setThreads(3);
+        config.setRequests(100);
+        final HttpBenchmark httpBenchmark = new HttpBenchmark(config);
+        final Results results = httpBenchmark.doExecute();
+        Assert.assertNotNull(results);
+        Assert.assertEquals(16, results.getContentLength());
+        Assert.assertEquals(3, results.getConcurrencyLevel());
+        Assert.assertEquals(300, results.getKeepAliveCount());
+        Assert.assertEquals(300, results.getSuccessCount());
+        Assert.assertEquals(0, results.getFailureCount());
+        Assert.assertEquals(0, results.getWriteErrors());
+        Assert.assertEquals(300 * 16, results.getTotalBytes());
+        Assert.assertEquals(300 * 16, results.getTotalBytesRcvd());
+    }
+
+}
diff --git a/httpcore-benchmark/pom.xml b/httpcore-benchmark/pom.xml
deleted file mode 100644
index 444d679..0000000
--- a/httpcore-benchmark/pom.xml
+++ /dev/null
@@ -1,129 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-   ====================================================================
-   Licensed to the Apache Software Foundation (ASF) under one
-   or more contributor license agreements.  See the NOTICE file
-   distributed with this work for additional information
-   regarding copyright ownership.  The ASF licenses this file
-   to you 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.
-   ====================================================================
-
-   This software consists of voluntary contributions made by many
-   individuals on behalf of the Apache Software Foundation.  For more
-   information on the Apache Software Foundation, please see
-   <http://www.apache.org />.
- -->
-
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-  <parent>
-    <groupId>org.apache.httpcomponents</groupId>
-    <artifactId>httpcomponents-core</artifactId>
-    <version>4.2.4</version>
-  </parent>
-  <artifactId>httpcore-benchmark</artifactId>
-  <name>HttpCore Benchmarks</name>
-  <description>
-   HttpComponents HttpCore - Benchmarks
-  </description>
-  <url>http://hc.apache.org/httpcomponents-core</url>
-  <packaging>jar</packaging>  
-
-  <dependencies>
-    <dependency>
-      <groupId>org.apache.httpcomponents</groupId>
-      <artifactId>httpcore</artifactId>
-      <version>${project.version}</version>
-      <scope>compile</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.httpcomponents</groupId>
-      <artifactId>httpcore-nio</artifactId>
-      <version>${project.version}</version>
-      <scope>compile</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.httpcomponents</groupId>
-      <artifactId>httpcore-ab</artifactId>
-      <version>${project.version}</version>
-      <scope>compile</scope>
-    </dependency>
-    <dependency>
-      <groupId>commons-cli</groupId>
-      <artifactId>commons-cli</artifactId>
-      <version>1.2</version>
-      <scope>compile</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.eclipse.jetty</groupId>
-      <artifactId>jetty-server</artifactId>
-      <version>7.0.1.v20091125</version>
-      <scope>compile</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.slf4j</groupId>
-      <artifactId>slf4j-api</artifactId>
-      <version>1.5.10</version>
-      <scope>compile</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.slf4j</groupId>
-      <artifactId>slf4j-nop</artifactId>
-      <version>1.5.10</version>
-      <scope>compile</scope>
-    </dependency>
-  </dependencies>
-
-  <properties>
-    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
-    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
-    <maven.compile.source>1.5</maven.compile.source>
-    <maven.compile.target>1.5</maven.compile.target>
-    <maven.compile.optimize>true</maven.compile.optimize>
-    <maven.compile.deprecation>true</maven.compile.deprecation>
-  </properties>
-
-  <build>
-    <plugins>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-compiler-plugin</artifactId>
-        <configuration>
-          <source>${maven.compile.source}</source>
-          <target>${maven.compile.target}</target>
-          <optimize>${maven.compile.optimize}</optimize>
-          <showDeprecations>${maven.compile.deprecation}</showDeprecations>
-        </configuration>
-      </plugin>
-      <plugin>
-        <groupId>org.codehaus.mojo</groupId>
-        <artifactId>exec-maven-plugin</artifactId>
-        <version>1.1.1</version>
-        <executions>
-          <execution>
-            <id>test-run</id>
-            <phase>test</phase>
-            <goals>
-              <goal>java</goal>
-            </goals>
-            <configuration>
-              <mainClass>org.apache.http.benchmark.Benchmark</mainClass>        
-            </configuration>
-          </execution>
-        </executions>
-      </plugin>
-    </plugins>
-  </build>
-
-</project>
diff --git a/httpcore-benchmark/src/main/java/org/apache/http/benchmark/Benchmark.java b/httpcore-benchmark/src/main/java/org/apache/http/benchmark/Benchmark.java
deleted file mode 100644
index 1f042ae..0000000
--- a/httpcore-benchmark/src/main/java/org/apache/http/benchmark/Benchmark.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * ====================================================================
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- *
- */
-package org.apache.http.benchmark;
-
-import java.net.URL;
-
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.CommandLineParser;
-import org.apache.commons.cli.HelpFormatter;
-import org.apache.commons.cli.Options;
-import org.apache.commons.cli.PosixParser;
-import org.apache.http.benchmark.httpcore.HttpCoreNIOServer;
-import org.apache.http.benchmark.httpcore.HttpCoreServer;
-import org.apache.http.benchmark.jetty.JettyNIOServer;
-import org.apache.http.benchmark.jetty.JettyServer;
-import org.apache.http.benchmark.CommandLineUtils;
-import org.apache.http.benchmark.Config;
-import org.apache.http.benchmark.HttpBenchmark;
-
-public class Benchmark {
-
-    private static final int PORT = 8989;
-
-    public static void main(String[] args) throws Exception {
-
-        Config config = new Config();
-        if (args.length > 0) {
-            Options options = CommandLineUtils.getOptions();
-            CommandLineParser parser = new PosixParser();
-            CommandLine cmd = parser.parse(options, args);
-            if (cmd.hasOption('h')) {
-                HelpFormatter formatter = new HelpFormatter();
-                formatter.printHelp("Benchmark [options]", options);
-                System.exit(1);
-            }
-            CommandLineUtils.parseCommandLine(cmd, config);
-        } else {
-            config.setKeepAlive(true);
-            config.setRequests(20000);
-            config.setThreads(25);
-        }
-
-        URL target = new URL("http", "localhost", PORT, "/rnd?c=2048");
-        config.setUrl(target);
-
-        Benchmark benchmark = new Benchmark();
-        benchmark.run(new JettyServer(PORT), config);
-        benchmark.run(new HttpCoreServer(PORT), config);
-        benchmark.run(new JettyNIOServer(PORT), config);
-        benchmark.run(new HttpCoreNIOServer(PORT), config);
-    }
-
-    public Benchmark() {
-        super();
-    }
-
-    public void run(final HttpServer server, final Config config) throws Exception {
-        server.start();
-        try {
-            System.out.println("---------------------------------------------------------------");
-            System.out.println(server.getName() + "; version: " + server.getVersion());
-            System.out.println("---------------------------------------------------------------");
-
-            HttpBenchmark ab = new HttpBenchmark(config);
-            ab.execute();
-            System.out.println("---------------------------------------------------------------");
-        } finally {
-            server.shutdown();
-        }
-    }
-
-}
diff --git a/httpcore-benchmark/src/main/java/org/apache/http/benchmark/httpcore/HttpCoreNIOServer.java b/httpcore-benchmark/src/main/java/org/apache/http/benchmark/httpcore/HttpCoreNIOServer.java
deleted file mode 100644
index fae2af3..0000000
--- a/httpcore-benchmark/src/main/java/org/apache/http/benchmark/httpcore/HttpCoreNIOServer.java
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * ====================================================================
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- *
- */
-package org.apache.http.benchmark.httpcore;
-
-import java.io.IOException;
-import java.net.InetSocketAddress;
-
-import org.apache.http.HttpResponseInterceptor;
-import org.apache.http.benchmark.HttpServer;
-import org.apache.http.impl.DefaultConnectionReuseStrategy;
-import org.apache.http.impl.DefaultHttpResponseFactory;
-import org.apache.http.impl.nio.DefaultServerIOEventDispatch;
-import org.apache.http.impl.nio.reactor.DefaultListeningIOReactor;
-import org.apache.http.nio.protocol.AsyncNHttpServiceHandler;
-import org.apache.http.nio.protocol.NHttpRequestHandlerRegistry;
-import org.apache.http.nio.reactor.IOEventDispatch;
-import org.apache.http.nio.reactor.ListeningIOReactor;
-import org.apache.http.params.CoreConnectionPNames;
-import org.apache.http.params.CoreProtocolPNames;
-import org.apache.http.params.HttpParams;
-import org.apache.http.params.SyncBasicHttpParams;
-import org.apache.http.protocol.HttpProcessor;
-import org.apache.http.protocol.ImmutableHttpProcessor;
-import org.apache.http.protocol.ResponseConnControl;
-import org.apache.http.protocol.ResponseContent;
-import org.apache.http.protocol.ResponseDate;
-import org.apache.http.protocol.ResponseServer;
-import org.apache.http.util.VersionInfo;
-
-public class HttpCoreNIOServer implements HttpServer {
-
-    private final int port;
-    private final NHttpListener listener;
-
-    public HttpCoreNIOServer(int port) throws IOException {
-        if (port <= 0) {
-            throw new IllegalArgumentException("Server port may not be negative or null");
-        }
-        this.port = port;
-
-        HttpParams params = new SyncBasicHttpParams();
-        params
-            .setIntParameter(CoreConnectionPNames.SO_TIMEOUT, 10000)
-            .setIntParameter(CoreConnectionPNames.SOCKET_BUFFER_SIZE, 12 * 1024)
-            .setBooleanParameter(CoreConnectionPNames.TCP_NODELAY, true)
-            .setParameter(CoreProtocolPNames.ORIGIN_SERVER, "HttpCore-NIO-Test/1.1");
-
-        HttpProcessor httpproc = new ImmutableHttpProcessor(new HttpResponseInterceptor[] {
-                new ResponseDate(),
-                new ResponseServer(),
-                new ResponseContent(),
-                new ResponseConnControl()
-        });
-
-        AsyncNHttpServiceHandler handler = new AsyncNHttpServiceHandler(
-                httpproc,
-                new DefaultHttpResponseFactory(),
-                new DefaultConnectionReuseStrategy(),
-                params);
-
-        NHttpRequestHandlerRegistry reqistry = new NHttpRequestHandlerRegistry();
-        reqistry.register("/rnd", new NRandomDataHandler());
-        handler.setHandlerResolver(reqistry);
-
-        ListeningIOReactor ioreactor = new DefaultListeningIOReactor(2, params);
-        IOEventDispatch ioEventDispatch = new DefaultServerIOEventDispatch(handler, params);
-        this.listener = new NHttpListener(ioreactor, ioEventDispatch);
-    }
-
-    public String getName() {
-        return "HttpCore (NIO)";
-    }
-
-    public String getVersion() {
-        VersionInfo vinfo = VersionInfo.loadVersionInfo("org.apache.http",
-                Thread.currentThread().getContextClassLoader());
-        return vinfo.getRelease();
-    }
-
-    public void start() throws Exception {
-        this.listener.start();
-        this.listener.listen(new InetSocketAddress(this.port));
-    }
-
-    public void shutdown() {
-        this.listener.terminate();
-        try {
-            this.listener.awaitTermination(1000);
-        } catch (InterruptedException ex) {
-        }
-        Exception ex = this.listener.getException();
-        if (ex != null) {
-            System.out.println("Error: " + ex.getMessage());
-        }
-    }
-
-    public static void main(String[] args) throws Exception {
-        if (args.length != 1) {
-            System.out.println("Usage: <port>");
-            System.exit(1);
-        }
-        int port = Integer.parseInt(args[0]);
-        final HttpCoreNIOServer server = new HttpCoreNIOServer(port);
-        System.out.println("Listening on port: " + port);
-        server.start();
-
-        Runtime.getRuntime().addShutdownHook(new Thread() {
-
-            @Override
-            public void run() {
-                server.shutdown();
-            }
-
-        });
-    }
-
-}
diff --git a/httpcore-benchmark/src/main/java/org/apache/http/benchmark/httpcore/HttpCoreServer.java b/httpcore-benchmark/src/main/java/org/apache/http/benchmark/httpcore/HttpCoreServer.java
deleted file mode 100644
index 013e971..0000000
--- a/httpcore-benchmark/src/main/java/org/apache/http/benchmark/httpcore/HttpCoreServer.java
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * ====================================================================
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- *
- */
-
-package org.apache.http.benchmark.httpcore;
-
-import java.io.IOException;
-import java.net.ServerSocket;
-import java.util.Queue;
-import java.util.concurrent.ConcurrentLinkedQueue;
-
-import org.apache.http.HttpResponseInterceptor;
-import org.apache.http.benchmark.HttpServer;
-import org.apache.http.impl.DefaultConnectionReuseStrategy;
-import org.apache.http.impl.DefaultHttpResponseFactory;
-import org.apache.http.params.CoreConnectionPNames;
-import org.apache.http.params.CoreProtocolPNames;
-import org.apache.http.params.HttpParams;
-import org.apache.http.params.SyncBasicHttpParams;
-import org.apache.http.protocol.HttpProcessor;
-import org.apache.http.protocol.HttpRequestHandlerRegistry;
-import org.apache.http.protocol.HttpService;
-import org.apache.http.protocol.ImmutableHttpProcessor;
-import org.apache.http.protocol.ResponseConnControl;
-import org.apache.http.protocol.ResponseContent;
-import org.apache.http.protocol.ResponseDate;
-import org.apache.http.protocol.ResponseServer;
-import org.apache.http.util.VersionInfo;
-
-public class HttpCoreServer implements HttpServer {
-
-    private final Queue<HttpWorker> workers;
-    private final HttpListener listener;
-
-    public HttpCoreServer(int port) throws IOException {
-        super();
-        if (port <= 0) {
-            throw new IllegalArgumentException("Server port may not be negative or null");
-        }
-
-        HttpParams params = new SyncBasicHttpParams();
-        params
-            .setIntParameter(CoreConnectionPNames.SO_TIMEOUT, 10000)
-            .setIntParameter(CoreConnectionPNames.SOCKET_BUFFER_SIZE, 12 * 1024)
-            .setIntParameter(CoreConnectionPNames.MIN_CHUNK_LIMIT, 1024)
-            .setBooleanParameter(CoreConnectionPNames.TCP_NODELAY, true)
-            .setParameter(CoreProtocolPNames.ORIGIN_SERVER, "HttpCore-Test/1.1");
-
-        HttpProcessor httpproc = new ImmutableHttpProcessor(new HttpResponseInterceptor[] {
-                new ResponseDate(),
-                new ResponseServer(),
-                new ResponseContent(),
-                new ResponseConnControl()
-        });
-
-        HttpRequestHandlerRegistry reqistry = new HttpRequestHandlerRegistry();
-        reqistry.register("/rnd", new RandomDataHandler());
-
-        HttpService httpservice = new HttpService(
-                httpproc,
-                new DefaultConnectionReuseStrategy(),
-                new DefaultHttpResponseFactory(),
-                reqistry,
-                params);
-
-        this.workers = new ConcurrentLinkedQueue<HttpWorker>();
-        this.listener = new HttpListener(
-                new ServerSocket(port),
-                httpservice,
-                new StdHttpWorkerCallback(this.workers));
-    }
-
-    public String getName() {
-        return "HttpCore (blocking I/O)";
-    }
-
-    public String getVersion() {
-        VersionInfo vinfo = VersionInfo.loadVersionInfo("org.apache.http",
-                Thread.currentThread().getContextClassLoader());
-        return vinfo.getRelease();
-    }
-
-    public void start() {
-        this.listener.start();
-    }
-
-    public void shutdown() {
-        this.listener.terminate();
-        try {
-            this.listener.awaitTermination(1000);
-        } catch (InterruptedException ex) {
-        }
-        Exception ex = this.listener.getException();
-        if (ex != null) {
-            System.out.println("Error: " + ex.getMessage());
-        }
-        while (!this.workers.isEmpty()) {
-            HttpWorker worker = this.workers.remove();
-            worker.terminate();
-            try {
-                worker.awaitTermination(1000);
-            } catch (InterruptedException iex) {
-            }
-            ex = worker.getException();
-            if (ex != null) {
-                System.out.println("Error: " + ex.getMessage());
-            }
-        }
-    }
-
-    public static void main(String[] args) throws Exception {
-        if (args.length != 1) {
-            System.out.println("Usage: <port>");
-            System.exit(1);
-        }
-        int port = Integer.parseInt(args[0]);
-        final HttpCoreServer server = new HttpCoreServer(port);
-        System.out.println("Listening on port: " + port);
-        server.start();
-
-        Runtime.getRuntime().addShutdownHook(new Thread() {
-
-            @Override
-            public void run() {
-                server.shutdown();
-            }
-
-        });
-    }
-
-}
diff --git a/httpcore-benchmark/src/main/java/org/apache/http/benchmark/httpcore/HttpListener.java b/httpcore-benchmark/src/main/java/org/apache/http/benchmark/httpcore/HttpListener.java
deleted file mode 100644
index 6fcc88a..0000000
--- a/httpcore-benchmark/src/main/java/org/apache/http/benchmark/httpcore/HttpListener.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * ====================================================================
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- *
- */
-
-package org.apache.http.benchmark.httpcore;
-
-import java.io.IOException;
-import java.io.InterruptedIOException;
-import java.net.ServerSocket;
-import java.net.Socket;
-
-import org.apache.http.impl.DefaultHttpServerConnection;
-import org.apache.http.protocol.HttpService;
-
-class HttpListener extends Thread {
-
-    private final ServerSocket serversocket;
-    private final HttpService httpservice;
-    private final HttpWorkerCallback workercallback;
-
-    private volatile boolean shutdown;
-    private volatile Exception exception;
-
-    public HttpListener(
-            final ServerSocket serversocket,
-            final HttpService httpservice,
-            final HttpWorkerCallback workercallback) {
-        super();
-        this.serversocket = serversocket;
-        this.httpservice = httpservice;
-        this.workercallback = workercallback;
-    }
-
-    public boolean isShutdown() {
-        return this.shutdown;
-    }
-
-    public Exception getException() {
-        return this.exception;
-    }
-
-    @Override
-    public void run() {
-        while (!Thread.interrupted() && !this.shutdown) {
-            try {
-                // Set up HTTP connection
-                Socket socket = this.serversocket.accept();
-                DefaultHttpServerConnection conn = new DefaultHttpServerConnection();
-                conn.bind(socket, this.httpservice.getParams());
-
-                // Start worker thread
-                HttpWorker t = new HttpWorker(this.httpservice, conn, this.workercallback);
-                t.start();
-            } catch (InterruptedIOException ex) {
-                terminate();
-            } catch (IOException ex) {
-                this.exception = ex;
-                terminate();
-            }
-        }
-    }
-
-    public void terminate() {
-        if (this.shutdown) {
-            return;
-        }
-        this.shutdown = true;
-        try {
-            this.serversocket.close();
-        } catch (IOException ex) {
-            if (this.exception != null) {
-                this.exception = ex;
-            }
-        }
-    }
-
-    public void awaitTermination(long millis) throws InterruptedException {
-        this.join(millis);
-    }
-
-}
\ No newline at end of file
diff --git a/httpcore-benchmark/src/main/java/org/apache/http/benchmark/httpcore/HttpWorker.java b/httpcore-benchmark/src/main/java/org/apache/http/benchmark/httpcore/HttpWorker.java
deleted file mode 100644
index c9ddd72..0000000
--- a/httpcore-benchmark/src/main/java/org/apache/http/benchmark/httpcore/HttpWorker.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * ====================================================================
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- *
- */
-package org.apache.http.benchmark.httpcore;
-
-import java.io.IOException;
-
-import org.apache.http.HttpServerConnection;
-import org.apache.http.protocol.BasicHttpContext;
-import org.apache.http.protocol.HttpContext;
-import org.apache.http.protocol.HttpService;
-
-class HttpWorker extends Thread {
-
-    private final HttpService httpservice;
-    private final HttpServerConnection conn;
-    private final HttpWorkerCallback workercallback;
-
-    private volatile boolean shutdown;
-    private volatile Exception exception;
-
-    public HttpWorker(
-            final HttpService httpservice,
-            final HttpServerConnection conn,
-            final HttpWorkerCallback workercallback) {
-        super();
-        this.httpservice = httpservice;
-        this.conn = conn;
-        this.workercallback = workercallback;
-    }
-
-    public boolean isShutdown() {
-        return this.shutdown;
-    }
-
-    public Exception getException() {
-        return this.exception;
-    }
-
-    @Override
-    public void run() {
-        this.workercallback.started(this);
-        try {
-            HttpContext context = new BasicHttpContext();
-            while (!Thread.interrupted() && !this.shutdown) {
-                this.httpservice.handleRequest(this.conn, context);
-            }
-        } catch (Exception ex) {
-            this.exception = ex;
-        } finally {
-            terminate();
-            this.workercallback.shutdown(this);
-        }
-    }
-
-    public void terminate() {
-        if (this.shutdown) {
-            return;
-        }
-        this.shutdown = true;
-        try {
-            this.conn.shutdown();
-        } catch (IOException ex) {
-            if (this.exception != null) {
-                this.exception = ex;
-            }
-        }
-    }
-
-    public void awaitTermination(long millis) throws InterruptedException {
-        this.join(millis);
-    }
-
-}
\ No newline at end of file
diff --git a/httpcore-benchmark/src/main/java/org/apache/http/benchmark/httpcore/NHttpListener.java b/httpcore-benchmark/src/main/java/org/apache/http/benchmark/httpcore/NHttpListener.java
deleted file mode 100644
index 2b5c31b..0000000
--- a/httpcore-benchmark/src/main/java/org/apache/http/benchmark/httpcore/NHttpListener.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * ====================================================================
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- *
- */
-package org.apache.http.benchmark.httpcore;
-
-import java.io.IOException;
-import java.net.InetSocketAddress;
-
-import org.apache.http.nio.reactor.IOEventDispatch;
-import org.apache.http.nio.reactor.ListenerEndpoint;
-import org.apache.http.nio.reactor.ListeningIOReactor;
-
-public class NHttpListener extends Thread {
-
-    private final ListeningIOReactor ioreactor;
-    private final IOEventDispatch ioEventDispatch;
-
-    private volatile Exception exception;
-
-    public NHttpListener(
-            final ListeningIOReactor ioreactor,
-            final IOEventDispatch ioEventDispatch) {
-        super();
-        this.ioreactor = ioreactor;
-        this.ioEventDispatch = ioEventDispatch;
-    }
-
-    @Override
-    public void run() {
-        try {
-            this.ioreactor.execute(this.ioEventDispatch);
-        } catch (Exception ex) {
-            this.exception = ex;
-        }
-    }
-
-    public void listen(final InetSocketAddress address) throws InterruptedException {
-        ListenerEndpoint endpoint = this.ioreactor.listen(address);
-        endpoint.waitFor();
-    }
-
-    public void terminate() {
-        try {
-            this.ioreactor.shutdown();
-        } catch (IOException ex) {
-        }
-    }
-
-    public Exception getException() {
-        return this.exception;
-    }
-
-    public void awaitTermination(long millis) throws InterruptedException {
-        this.join(millis);
-    }
-
-}
diff --git a/httpcore-benchmark/src/main/java/org/apache/http/benchmark/httpcore/NRandomDataHandler.java b/httpcore-benchmark/src/main/java/org/apache/http/benchmark/httpcore/NRandomDataHandler.java
deleted file mode 100644
index 2e1c9b1..0000000
--- a/httpcore-benchmark/src/main/java/org/apache/http/benchmark/httpcore/NRandomDataHandler.java
+++ /dev/null
@@ -1,204 +0,0 @@
-/*
- * ====================================================================
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- *
- */
-package org.apache.http.benchmark.httpcore;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.nio.ByteBuffer;
-import java.util.Locale;
-
-import org.apache.http.HttpEntity;
-import org.apache.http.HttpEntityEnclosingRequest;
-import org.apache.http.HttpException;
-import org.apache.http.HttpRequest;
-import org.apache.http.HttpResponse;
-import org.apache.http.HttpStatus;
-import org.apache.http.MethodNotSupportedException;
-import org.apache.http.entity.AbstractHttpEntity;
-import org.apache.http.entity.StringEntity;
-import org.apache.http.nio.ContentEncoder;
-import org.apache.http.nio.IOControl;
-import org.apache.http.nio.entity.BufferingNHttpEntity;
-import org.apache.http.nio.entity.ConsumingNHttpEntity;
-import org.apache.http.nio.entity.ProducingNHttpEntity;
-import org.apache.http.nio.protocol.NHttpRequestHandler;
-import org.apache.http.nio.protocol.NHttpResponseTrigger;
-import org.apache.http.nio.util.HeapByteBufferAllocator;
-import org.apache.http.protocol.HttpContext;
-import org.apache.http.util.EntityUtils;
-
-class NRandomDataHandler implements NHttpRequestHandler  {
-
-    public NRandomDataHandler() {
-        super();
-    }
-
-    public ConsumingNHttpEntity entityRequest(
-            final HttpEntityEnclosingRequest request,
-            final HttpContext context) throws HttpException, IOException {
-        // Use buffering entity for simplicity
-        return new BufferingNHttpEntity(request.getEntity(), new HeapByteBufferAllocator());
-    }
-
-    public void handle(
-            final HttpRequest request,
-            final HttpResponse response,
-            final NHttpResponseTrigger trigger,
-            final HttpContext context) throws HttpException, IOException {
-        String method = request.getRequestLine().getMethod().toUpperCase(Locale.ENGLISH);
-        if (!method.equals("GET") && !method.equals("HEAD") && !method.equals("POST")) {
-            throw new MethodNotSupportedException(method + " method not supported");
-        }
-        if (request instanceof HttpEntityEnclosingRequest) {
-            HttpEntity entity = ((HttpEntityEnclosingRequest) request).getEntity();
-            EntityUtils.consume(entity);
-        }
-        String target = request.getRequestLine().getUri();
-
-        int count = 100;
-
-        int idx = target.indexOf('?');
-        if (idx != -1) {
-            String s = target.substring(idx + 1);
-            if (s.startsWith("c=")) {
-                s = s.substring(2);
-                try {
-                    count = Integer.parseInt(s);
-                } catch (NumberFormatException ex) {
-                    response.setStatusCode(HttpStatus.SC_BAD_REQUEST);
-                    response.setEntity(new StringEntity("Invalid query format: " + s,
-                            "text/plain", "ASCII"));
-                    return;
-                }
-            }
-        }
-        response.setStatusCode(HttpStatus.SC_OK);
-        RandomEntity body = new RandomEntity(count);
-        response.setEntity(body);
-        trigger.submitResponse(response);
-    }
-
-
-
-    public void handle(
-            final HttpRequest request,
-            final HttpResponse response,
-            final HttpContext context) throws HttpException, IOException {
-        String method = request.getRequestLine().getMethod().toUpperCase(Locale.ENGLISH);
-        if (!method.equals("GET") && !method.equals("HEAD") && !method.equals("POST")) {
-            throw new MethodNotSupportedException(method + " method not supported");
-        }
-        if (request instanceof HttpEntityEnclosingRequest) {
-            HttpEntity entity = ((HttpEntityEnclosingRequest) request).getEntity();
-            EntityUtils.consume(entity);
-        }
-        String target = request.getRequestLine().getUri();
-
-        int count = 100;
-
-        int idx = target.indexOf('?');
-        if (idx != -1) {
-            String s = target.substring(idx + 1);
-            if (s.startsWith("c=")) {
-                s = s.substring(2);
-                try {
-                    count = Integer.parseInt(s);
-                } catch (NumberFormatException ex) {
-                    response.setStatusCode(HttpStatus.SC_BAD_REQUEST);
-                    response.setEntity(new StringEntity("Invalid query format: " + s,
-                            "text/plain", "ASCII"));
-                    return;
-                }
-            }
-        }
-        response.setStatusCode(HttpStatus.SC_OK);
-        RandomEntity body = new RandomEntity(count);
-        response.setEntity(body);
-    }
-
-    static class RandomEntity extends AbstractHttpEntity implements ProducingNHttpEntity {
-
-        private final int count;
-        private final ByteBuffer buf;
-
-        private int remaining;
-
-        public RandomEntity(int count) {
-            super();
-            this.count = count;
-            this.remaining = count;
-            this.buf = ByteBuffer.allocate(1024);
-            setContentType("text/plain");
-        }
-
-        public InputStream getContent() throws IOException, IllegalStateException {
-            throw new IllegalStateException("Method not supported");
-        }
-
-        public long getContentLength() {
-            return this.count;
-        }
-
-        public boolean isRepeatable() {
-            return true;
-        }
-
-        public boolean isStreaming() {
-            return false;
-        }
-
-        public void writeTo(final OutputStream outstream) throws IOException {
-            throw new IllegalStateException("Method not supported");
-        }
-
-        public void produceContent(
-                final ContentEncoder encoder, final IOControl ioctrl) throws IOException {
-            int r = Math.abs(this.buf.hashCode());
-            int chunk = Math.min(this.buf.remaining(), this.remaining);
-            if (chunk > 0) {
-                for (int i = 0; i < chunk; i++) {
-                    byte b = (byte) ((r + i) % 96 + 32);
-                    this.buf.put(b);
-                }
-            }
-            this.buf.flip();
-            int bytesWritten = encoder.write(this.buf);
-            this.remaining -= bytesWritten;
-            if (this.remaining == 0 && this.buf.remaining() == 0) {
-                encoder.complete();
-            }
-            this.buf.compact();
-        }
-
-        public void finish() throws IOException {
-            this.remaining = this.count;
-        }
-
-    }
-
-}
\ No newline at end of file
diff --git a/httpcore-benchmark/src/main/java/org/apache/http/benchmark/httpcore/RandomDataHandler.java b/httpcore-benchmark/src/main/java/org/apache/http/benchmark/httpcore/RandomDataHandler.java
deleted file mode 100644
index 155a472..0000000
--- a/httpcore-benchmark/src/main/java/org/apache/http/benchmark/httpcore/RandomDataHandler.java
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * ====================================================================
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- *
- */
-package org.apache.http.benchmark.httpcore;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.util.Locale;
-
-import org.apache.http.HttpEntity;
-import org.apache.http.HttpEntityEnclosingRequest;
-import org.apache.http.HttpException;
-import org.apache.http.HttpRequest;
-import org.apache.http.HttpResponse;
-import org.apache.http.HttpStatus;
-import org.apache.http.MethodNotSupportedException;
-import org.apache.http.entity.AbstractHttpEntity;
-import org.apache.http.entity.StringEntity;
-import org.apache.http.protocol.HttpContext;
-import org.apache.http.protocol.HttpRequestHandler;
-import org.apache.http.util.EntityUtils;
-
-class RandomDataHandler implements HttpRequestHandler  {
-
-    public RandomDataHandler() {
-        super();
-    }
-
-    public void handle(
-            final HttpRequest request,
-            final HttpResponse response,
-            final HttpContext context) throws HttpException, IOException {
-        String method = request.getRequestLine().getMethod().toUpperCase(Locale.ENGLISH);
-        if (!method.equals("GET") && !method.equals("HEAD") && !method.equals("POST")) {
-            throw new MethodNotSupportedException(method + " method not supported");
-        }
-        if (request instanceof HttpEntityEnclosingRequest) {
-            HttpEntity entity = ((HttpEntityEnclosingRequest) request).getEntity();
-            EntityUtils.consume(entity);
-        }
-        String target = request.getRequestLine().getUri();
-
-        int count = 100;
-
-        int idx = target.indexOf('?');
-        if (idx != -1) {
-            String s = target.substring(idx + 1);
-            if (s.startsWith("c=")) {
-                s = s.substring(2);
-                try {
-                    count = Integer.parseInt(s);
-                } catch (NumberFormatException ex) {
-                    response.setStatusCode(HttpStatus.SC_BAD_REQUEST);
-                    response.setEntity(new StringEntity("Invalid query format: " + s,
-                            "text/plain", "ASCII"));
-                    return;
-                }
-            }
-        }
-        response.setStatusCode(HttpStatus.SC_OK);
-        RandomEntity body = new RandomEntity(count);
-        response.setEntity(body);
-    }
-
-    static class RandomEntity extends AbstractHttpEntity {
-
-        private int count;
-        private final byte[] buf;
-
-        public RandomEntity(int count) {
-            super();
-            this.count = count;
-            this.buf = new byte[1024];
-            setContentType("text/plain");
-        }
-
-        public InputStream getContent() throws IOException, IllegalStateException {
-            throw new IllegalStateException("Method not supported");
-        }
-
-        public long getContentLength() {
-            return this.count;
-        }
-
-        public boolean isRepeatable() {
-            return true;
-        }
-
-        public boolean isStreaming() {
-            return false;
-        }
-
-        public void writeTo(final OutputStream outstream) throws IOException {
-            int r = Math.abs(this.buf.hashCode());
-            int remaining = this.count;
-            while (remaining > 0) {
-                int chunk = Math.min(this.buf.length, remaining);
-                for (int i = 0; i < chunk; i++) {
-                    this.buf[i] = (byte) ((r + i) % 96 + 32);
-                }
-                outstream.write(this.buf, 0, chunk);
-                remaining -= chunk;
-            }
-        }
-
-    }
-
-}
\ No newline at end of file
diff --git a/httpcore-benchmark/src/main/java/org/apache/http/benchmark/httpcore/StdHttpWorkerCallback.java b/httpcore-benchmark/src/main/java/org/apache/http/benchmark/httpcore/StdHttpWorkerCallback.java
deleted file mode 100644
index 1feaccb..0000000
--- a/httpcore-benchmark/src/main/java/org/apache/http/benchmark/httpcore/StdHttpWorkerCallback.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * ====================================================================
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- *
- */
-package org.apache.http.benchmark.httpcore;
-
-import java.io.IOException;
-import java.net.SocketTimeoutException;
-import java.util.Queue;
-
-import org.apache.http.ConnectionClosedException;
-import org.apache.http.HttpException;
-
-class StdHttpWorkerCallback implements HttpWorkerCallback {
-
-    private final Queue<HttpWorker> queue;
-
-    public StdHttpWorkerCallback(final Queue<HttpWorker> queue) {
-        super();
-        this.queue = queue;
-    }
-
-    public void started(final HttpWorker worker) {
-        this.queue.add(worker);
-    }
-
-    public void shutdown(final HttpWorker worker) {
-        this.queue.remove(worker);
-        Exception ex = worker.getException();
-        if (ex != null) {
-            if (ex instanceof HttpException) {
-                System.err.println("HTTP protocol error: " + ex.getMessage());
-            } else if (ex instanceof SocketTimeoutException) {
-                // ignore
-            } else if (ex instanceof ConnectionClosedException) {
-                // ignore
-            } else if (ex instanceof IOException) {
-                System.err.println("I/O error: " + ex);
-            } else {
-                System.err.println("Unexpected error: " + ex.getMessage());
-            }
-        }
-    }
-
-}
\ No newline at end of file
diff --git a/httpcore-benchmark/src/main/java/org/apache/http/benchmark/jetty/JettyNIOServer.java b/httpcore-benchmark/src/main/java/org/apache/http/benchmark/jetty/JettyNIOServer.java
deleted file mode 100644
index d339f1f..0000000
--- a/httpcore-benchmark/src/main/java/org/apache/http/benchmark/jetty/JettyNIOServer.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * ====================================================================
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- *
- */
-
-package org.apache.http.benchmark.jetty;
-
-import org.apache.http.benchmark.HttpServer;
-import org.eclipse.jetty.server.Server;
-import org.eclipse.jetty.server.nio.SelectChannelConnector;
-import org.eclipse.jetty.util.thread.QueuedThreadPool;
-
-public class JettyNIOServer implements HttpServer {
-
-    private final Server server;
-
-    public JettyNIOServer(int port) {
-        super();
-        if (port <= 0) {
-            throw new IllegalArgumentException("Server port may not be negative or null");
-        }
-
-        SelectChannelConnector connector = new SelectChannelConnector();
-        connector.setPort(port);
-        connector.setRequestBufferSize(12 * 1024);
-        connector.setResponseBufferSize(12 * 1024);
-        connector.setAcceptors(2);
-
-        QueuedThreadPool threadpool = new QueuedThreadPool();
-        threadpool.setMinThreads(25);
-        threadpool.setMaxThreads(200);
-
-        this.server = new Server();
-        this.server.addConnector(connector);
-        this.server.setThreadPool(threadpool);
-        this.server.setHandler(new RandomDataHandler());
-    }
-
-    public String getName() {
-        return "Jetty (NIO)";
-    }
-
-    public String getVersion() {
-        return Server.getVersion();
-    }
-
-    public void start() throws Exception {
-        this.server.start();
-    }
-
-    public void shutdown() {
-        try {
-            this.server.stop();
-        } catch (Exception ex) {
-        }
-        try {
-            this.server.join();
-        } catch (InterruptedException ex) {
-        }
-    }
-
-    public static void main(String[] args) throws Exception {
-        if (args.length != 1) {
-            System.out.println("Usage: <port>");
-            System.exit(1);
-        }
-        int port = Integer.parseInt(args[0]);
-        final JettyNIOServer server = new JettyNIOServer(port);
-        System.out.println("Listening on port: " + port);
-        server.start();
-
-        Runtime.getRuntime().addShutdownHook(new Thread() {
-
-            @Override
-            public void run() {
-                server.shutdown();
-            }
-
-        });
-    }
-
-}
diff --git a/httpcore-benchmark/src/main/java/org/apache/http/benchmark/jetty/JettyServer.java b/httpcore-benchmark/src/main/java/org/apache/http/benchmark/jetty/JettyServer.java
deleted file mode 100644
index 7808cbc..0000000
--- a/httpcore-benchmark/src/main/java/org/apache/http/benchmark/jetty/JettyServer.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * ====================================================================
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- *
- */
-
-package org.apache.http.benchmark.jetty;
-
-import org.apache.http.benchmark.HttpServer;
-import org.eclipse.jetty.server.Server;
-import org.eclipse.jetty.server.bio.SocketConnector;
-import org.eclipse.jetty.util.thread.QueuedThreadPool;
-
-public class JettyServer implements HttpServer {
-
-    private final Server server;
-
-    public JettyServer(int port) {
-        super();
-        if (port <= 0) {
-            throw new IllegalArgumentException("Server port may not be negative or null");
-        }
-
-        SocketConnector connector = new SocketConnector();
-        connector.setPort(port);
-        connector.setRequestBufferSize(12 * 1024);
-        connector.setResponseBufferSize(12 * 1024);
-        connector.setAcceptors(2);
-
-        QueuedThreadPool threadpool = new QueuedThreadPool();
-        threadpool.setMinThreads(25);
-        threadpool.setMaxThreads(200);
-
-        this.server = new Server();
-        this.server.addConnector(connector);
-        this.server.setThreadPool(threadpool);
-        this.server.setHandler(new RandomDataHandler());
-    }
-
-    public String getName() {
-        return "Jetty (blocking I/O)";
-    }
-
-    public String getVersion() {
-        return Server.getVersion();
-    }
-
-    public void start() throws Exception {
-        this.server.start();
-    }
-
-    public void shutdown() {
-        try {
-            this.server.stop();
-        } catch (Exception ex) {
-        }
-        try {
-            this.server.join();
-        } catch (InterruptedException ex) {
-        }
-    }
-
-    public static void main(String[] args) throws Exception {
-        if (args.length != 1) {
-            System.out.println("Usage: <port>");
-            System.exit(1);
-        }
-        int port = Integer.parseInt(args[0]);
-        final JettyServer server = new JettyServer(port);
-        System.out.println("Listening on port: " + port);
-        server.start();
-
-        Runtime.getRuntime().addShutdownHook(new Thread() {
-
-            @Override
-            public void run() {
-                server.shutdown();
-            }
-
-        });
-    }
-
-}
diff --git a/httpcore-benchmark/src/main/java/org/apache/http/benchmark/jetty/RandomDataHandler.java b/httpcore-benchmark/src/main/java/org/apache/http/benchmark/jetty/RandomDataHandler.java
deleted file mode 100644
index 08a69c1..0000000
--- a/httpcore-benchmark/src/main/java/org/apache/http/benchmark/jetty/RandomDataHandler.java
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * ====================================================================
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- *
- */
-package org.apache.http.benchmark.jetty;
-
-import java.io.IOException;
-import java.io.OutputStream;
-import java.io.Writer;
-
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import org.eclipse.jetty.http.HttpStatus;
-import org.eclipse.jetty.server.Request;
-import org.eclipse.jetty.server.handler.AbstractHandler;
-
-class RandomDataHandler extends AbstractHandler {
-
-    public RandomDataHandler() {
-        super();
-    }
-
-    public void handle(
-            final String target,
-            final Request baseRequest,
-            final HttpServletRequest request,
-            final HttpServletResponse response) throws IOException, ServletException {
-        if (target.equals("/rnd")) {
-            rnd(request, response);
-        } else {
-            response.setStatus(HttpStatus.NOT_FOUND_404);
-            Writer writer = response.getWriter();
-            writer.write("Target not found: " + target);
-            writer.flush();
-        }
-    }
-
-    private void rnd(
-            final HttpServletRequest request,
-            final HttpServletResponse response) throws IOException {
-        int count = 100;
-        String s = request.getParameter("c");
-        try {
-            count = Integer.parseInt(s);
-        } catch (NumberFormatException ex) {
-            response.setStatus(500);
-            Writer writer = response.getWriter();
-            writer.write("Invalid query format: " + request.getQueryString());
-            writer.flush();
-            return;
-        }
-
-        response.setStatus(200);
-        response.setContentLength(count);
-
-        OutputStream outstream = response.getOutputStream();
-        byte[] tmp = new byte[1024];
-        int r = Math.abs(tmp.hashCode());
-        int remaining = count;
-        while (remaining > 0) {
-            int chunk = Math.min(tmp.length, remaining);
-            for (int i = 0; i < chunk; i++) {
-                tmp[i] = (byte) ((r + i) % 96 + 32);
-            }
-            outstream.write(tmp, 0, chunk);
-            remaining -= chunk;
-        }
-        outstream.flush();
-    }
-
-}
\ No newline at end of file
diff --git a/httpcore-contrib/docs/translated-tutorial/httpcore-tutorial-simplified-chinese.pdf b/httpcore-contrib/docs/translated-tutorial/httpcore-tutorial-simplified-chinese.pdf
deleted file mode 100644
index 3c03ef5..0000000
Binary files a/httpcore-contrib/docs/translated-tutorial/httpcore-tutorial-simplified-chinese.pdf and /dev/null differ
diff --git a/httpcore-contrib/pom.xml b/httpcore-contrib/pom.xml
deleted file mode 100644
index 7233b4e..0000000
--- a/httpcore-contrib/pom.xml
+++ /dev/null
@@ -1,87 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-   ====================================================================
-   Licensed to the Apache Software Foundation (ASF) under one
-   or more contributor license agreements.  See the NOTICE file
-   distributed with this work for additional information
-   regarding copyright ownership.  The ASF licenses this file
-   to you 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.
-   ====================================================================
-
-   This software consists of voluntary contributions made by many
-   individuals on behalf of the Apache Software Foundation.  For more
-   information on the Apache Software Foundation, please see
-   <http://www.apache.org />.
- -->
-
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-  <parent>
-    <groupId>org.apache.httpcomponents</groupId>
-    <artifactId>httpcomponents-core</artifactId>
-    <version>4.2.4</version>
-  </parent>
-  <artifactId>httpcore-contrib</artifactId>
-  <name>HttpCore Contrib</name>
-  <description>
-   HttpComponents HttpCore - Contributed Components (distributed as source only)
-  </description>
-  <url>http://hc.apache.org/httpcomponents-core-ga</url>
-  <packaging>jar</packaging>
-
-  <dependencies>
-    <dependency>
-      <groupId>org.apache.httpcomponents</groupId>
-      <artifactId>httpcore</artifactId>
-      <version>${project.version}</version>
-      <scope>compile</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.httpcomponents</groupId>
-      <artifactId>httpcore-nio</artifactId>
-      <version>${project.version}</version>
-      <scope>compile</scope>
-    </dependency>
-    <dependency>
-      <groupId>commons-logging</groupId>
-      <artifactId>commons-logging</artifactId>
-      <scope>compile</scope>
-    </dependency>
-  </dependencies>
-
-  <properties>
-    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
-    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
-    <maven.compile.source>1.5</maven.compile.source>
-    <maven.compile.target>1.5</maven.compile.target>
-    <maven.compile.optimize>true</maven.compile.optimize>
-    <maven.compile.deprecation>true</maven.compile.deprecation>
-  </properties>
-
-  <build>
-    <plugins>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-compiler-plugin</artifactId>
-        <configuration>
-          <source>${maven.compile.source}</source>
-          <target>${maven.compile.target}</target>
-          <optimize>${maven.compile.optimize}</optimize>
-          <showDeprecations>${maven.compile.deprecation}</showDeprecations>
-        </configuration>
-      </plugin>
-    </plugins>
-  </build>
-
-</project>
diff --git a/httpcore-contrib/src/main/java/org/apache/http/contrib/compress/GzipCompressingEntity.java b/httpcore-contrib/src/main/java/org/apache/http/contrib/compress/GzipCompressingEntity.java
deleted file mode 100644
index fe7d5e7..0000000
--- a/httpcore-contrib/src/main/java/org/apache/http/contrib/compress/GzipCompressingEntity.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * ====================================================================
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- *
- */
-
-package org.apache.http.contrib.compress;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.util.zip.GZIPOutputStream;
-
-import org.apache.http.Header;
-import org.apache.http.HttpEntity;
-import org.apache.http.entity.HttpEntityWrapper;
-import org.apache.http.message.BasicHeader;
-import org.apache.http.protocol.HTTP;
-
-/**
- * Wrapping entity that compresses content when {@link #writeTo writing}.
- *
- *
- * @since 4.0
- */
-public class GzipCompressingEntity extends HttpEntityWrapper {
-
-    private static final String GZIP_CODEC = "gzip";
-
-    public GzipCompressingEntity(final HttpEntity entity) {
-        super(entity);
-    }
-
-    @Override
-    public Header getContentEncoding() {
-        return new BasicHeader(HTTP.CONTENT_ENCODING, GZIP_CODEC);
-    }
-
-    @Override
-    public long getContentLength() {
-        return -1;
-    }
-
-    @Override
-    public boolean isChunked() {
-        // force content chunking
-        return true;
-    }
-
-    @Override
-    public void writeTo(final OutputStream outstream) throws IOException {
-        if (outstream == null) {
-            throw new IllegalArgumentException("Output stream may not be null");
-        }
-        GZIPOutputStream gzip = new GZIPOutputStream(outstream);
-        InputStream in = wrappedEntity.getContent();
-        byte[] tmp = new byte[2048];
-        int l;
-        while ((l = in.read(tmp)) != -1) {
-            gzip.write(tmp, 0, l);
-        }
-        gzip.close();
-    }
-
-} // class GzipCompressingEntity
diff --git a/httpcore-contrib/src/main/java/org/apache/http/contrib/compress/GzipDecompressingEntity.java b/httpcore-contrib/src/main/java/org/apache/http/contrib/compress/GzipDecompressingEntity.java
deleted file mode 100644
index 7b4123d..0000000
--- a/httpcore-contrib/src/main/java/org/apache/http/contrib/compress/GzipDecompressingEntity.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * ====================================================================
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- *
- */
-
-package org.apache.http.contrib.compress;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.zip.GZIPInputStream;
-
-import org.apache.http.HttpEntity;
-import org.apache.http.entity.HttpEntityWrapper;
-
-/**
- * Wrapping entity that decompresses {@link #getContent content}.
- *
- *
- * @since 4.0
- */
-public class GzipDecompressingEntity extends HttpEntityWrapper {
-
-    public GzipDecompressingEntity(final HttpEntity entity) {
-        super(entity);
-    }
-
-    @Override
-    public InputStream getContent()
-        throws IOException, IllegalStateException {
-
-          // the wrapped entity's getContent() decides about repeatability
-        InputStream wrappedin = wrappedEntity.getContent();
-
-        return new GZIPInputStream(wrappedin);
-    }
-
-    @Override
-    public long getContentLength() {
-        // length of ungzipped content not known in advance
-        return -1;
-    }
-
-} // class GzipDecompressingEntity
diff --git a/httpcore-contrib/src/main/java/org/apache/http/contrib/compress/ResponseGzipCompress.java b/httpcore-contrib/src/main/java/org/apache/http/contrib/compress/ResponseGzipCompress.java
deleted file mode 100644
index f14a47d..0000000
--- a/httpcore-contrib/src/main/java/org/apache/http/contrib/compress/ResponseGzipCompress.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * ====================================================================
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- *
- */
-
-package org.apache.http.contrib.compress;
-
-import java.io.IOException;
-
-import org.apache.http.Header;
-import org.apache.http.HeaderElement;
-import org.apache.http.HttpEntity;
-import org.apache.http.HttpException;
-import org.apache.http.HttpRequest;
-import org.apache.http.HttpResponse;
-import org.apache.http.HttpResponseInterceptor;
-import org.apache.http.protocol.HttpContext;
-import org.apache.http.protocol.ExecutionContext;
-
-/**
- * Server-side interceptor to handle Gzip-encoded responses.
- *
- *
- * @since 4.0
- */
-public class ResponseGzipCompress implements HttpResponseInterceptor {
-
-    private static final String ACCEPT_ENCODING = "Accept-Encoding";
-    private static final String GZIP_CODEC = "gzip";
-
-    public void process(final HttpResponse response, final HttpContext context)
-            throws HttpException, IOException {
-        if (context == null) {
-            throw new IllegalArgumentException("HTTP context may not be null");
-        }
-        HttpEntity entity = response.getEntity();
-        if (entity != null) {
-            HttpRequest request = (HttpRequest) context.getAttribute(ExecutionContext.HTTP_REQUEST);
-            Header aeheader = request.getFirstHeader(ACCEPT_ENCODING);
-            if (aeheader != null) {
-                HeaderElement[] codecs = aeheader.getElements();
-                for (int i = 0; i < codecs.length; i++) {
-                    if (codecs[i].getName().equalsIgnoreCase(GZIP_CODEC)) {
-                        response.setEntity(new GzipCompressingEntity(entity));
-                        return;
-                    }
-                }
-            }
-        }
-    }
-}
diff --git a/httpcore-contrib/src/main/java/org/apache/http/contrib/compress/ResponseGzipUncompress.java b/httpcore-contrib/src/main/java/org/apache/http/contrib/compress/ResponseGzipUncompress.java
deleted file mode 100644
index b31a572..0000000
--- a/httpcore-contrib/src/main/java/org/apache/http/contrib/compress/ResponseGzipUncompress.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * ====================================================================
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- *
- */
-
-package org.apache.http.contrib.compress;
-
-import java.io.IOException;
-
-import org.apache.http.Header;
-import org.apache.http.HeaderElement;
-import org.apache.http.HttpEntity;
-import org.apache.http.HttpException;
-import org.apache.http.HttpResponse;
-import org.apache.http.HttpResponseInterceptor;
-import org.apache.http.protocol.HttpContext;
-
-/**
- * Client-side interceptor to handle Gzip-compressed responses.
- *
- *
- * @since 4.0
- */
-public class ResponseGzipUncompress implements HttpResponseInterceptor {
-
-    private static final String GZIP_CODEC = "gzip";
-
-    public void process(final HttpResponse response, final HttpContext context)
-            throws HttpException, IOException {
-        if (context == null) {
-            throw new IllegalArgumentException("HTTP context may not be null");
-        }
-        HttpEntity entity = response.getEntity();
-        if (entity != null) {
-            Header ceheader = entity.getContentEncoding();
-            if (ceheader != null) {
-                HeaderElement[] codecs = ceheader.getElements();
-                for (int i = 0; i < codecs.length; i++) {
-                    if (codecs[i].getName().equalsIgnoreCase(GZIP_CODEC)) {
-                        response.setEntity(new GzipDecompressingEntity(response.getEntity()));
-                        return;
-                    }
-                }
-            }
-        }
-    }
-
-}
diff --git a/httpcore-contrib/src/main/java/org/apache/http/contrib/logging/LoggingIOSession.java b/httpcore-contrib/src/main/java/org/apache/http/contrib/logging/LoggingIOSession.java
deleted file mode 100644
index 7157fb5..0000000
--- a/httpcore-contrib/src/main/java/org/apache/http/contrib/logging/LoggingIOSession.java
+++ /dev/null
@@ -1,234 +0,0 @@
-/*
- * ====================================================================
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- *
- */
-
-package org.apache.http.contrib.logging;
-
-import java.io.IOException;
-import java.net.SocketAddress;
-import java.nio.ByteBuffer;
-import java.nio.channels.ByteChannel;
-import java.nio.channels.SelectionKey;
-
-import org.apache.commons.logging.Log;
-import org.apache.http.nio.reactor.IOSession;
-import org.apache.http.nio.reactor.SessionBufferStatus;
-
-/**
- * Decorator class intended to transparently extend an {@link IOSession}
- * with basic event logging capabilities using Commons Logging.
- *
- */
-public class LoggingIOSession implements IOSession {
-
-    private final Log log;
-    private final Wire wirelog;
-    private final String id;
-    private final IOSession session;
-    private final ByteChannel channel;
-
-    public LoggingIOSession(final IOSession session, final String id, final Log log, final Log wirelog) {
-        super();
-        if (session == null) {
-            throw new IllegalArgumentException("I/O session may not be null");
-        }
-        this.session = session;
-        this.channel = new LoggingByteChannel();
-        this.id = id;
-        this.log = log;
-        this.wirelog = new Wire(wirelog, this.id);
-    }
-
-    public ByteChannel channel() {
-        return this.channel;
-    }
-
-    public SocketAddress getLocalAddress() {
-        return this.session.getLocalAddress();
-    }
-
-    public SocketAddress getRemoteAddress() {
-        return this.session.getRemoteAddress();
-    }
-
-    public int getEventMask() {
-        return this.session.getEventMask();
-    }
-
-    private static String formatOps(int ops) {
-        StringBuilder buffer = new StringBuilder(6);
-        buffer.append('[');
-        if ((ops & SelectionKey.OP_READ) > 0) {
-            buffer.append('r');
-        }
-        if ((ops & SelectionKey.OP_WRITE) > 0) {
-            buffer.append('w');
-        }
-        if ((ops & SelectionKey.OP_ACCEPT) > 0) {
-            buffer.append('a');
-        }
-        if ((ops & SelectionKey.OP_CONNECT) > 0) {
-            buffer.append('c');
-        }
-        buffer.append(']');
-        return buffer.toString();
-    }
-
-    public void setEventMask(int ops) {
-        this.session.setEventMask(ops);
-        if (this.log.isDebugEnabled()) {
-            this.log.debug(this.id + " " + this.session + ": Event mask set " + formatOps(ops));
-        }
-    }
-
-    public void setEvent(int op) {
-        this.session.setEvent(op);
-        if (this.log.isDebugEnabled()) {
-            this.log.debug(this.id + " " + this.session + ": Event set " + formatOps(op));
-        }
-    }
-
-    public void clearEvent(int op) {
-        this.session.clearEvent(op);
-        if (this.log.isDebugEnabled()) {
-            this.log.debug(this.id + " " + this.session + ": Event cleared " + formatOps(op));
-        }
-    }
-
-    public void close() {
-        if (this.log.isDebugEnabled()) {
-            this.log.debug(this.id + " " + this.session + ": Close");
-        }
-        this.session.close();
-    }
-
-    public int getStatus() {
-        return this.session.getStatus();
-    }
-
-    public boolean isClosed() {
-        return this.session.isClosed();
-    }
-
-    public void shutdown() {
-        if (this.log.isDebugEnabled()) {
-            this.log.debug(this.id + " " + this.session + ": Shutdown");
-        }
-        this.session.shutdown();
-    }
-
-    public int getSocketTimeout() {
-        return this.session.getSocketTimeout();
-    }
-
-    public void setSocketTimeout(int timeout) {
-        if (this.log.isDebugEnabled()) {
-            this.log.debug(this.id + " " + this.session + ": Set timeout " + timeout);
-        }
-        this.session.setSocketTimeout(timeout);
-    }
-
-    public void setBufferStatus(final SessionBufferStatus status) {
-        this.session.setBufferStatus(status);
-    }
-
-    public boolean hasBufferedInput() {
-        return this.session.hasBufferedInput();
-    }
-
-    public boolean hasBufferedOutput() {
-        return this.session.hasBufferedOutput();
-    }
-
-    public Object getAttribute(final String name) {
-        return this.session.getAttribute(name);
-    }
-
-    public void setAttribute(final String name, final Object obj) {
-        if (this.log.isDebugEnabled()) {
-            this.log.debug(this.id + " " + this.session + ": Set attribute " + name);
-        }
-        this.session.setAttribute(name, obj);
-    }
-
-    public Object removeAttribute(final String name) {
-        if (this.log.isDebugEnabled()) {
-            this.log.debug(this.id + " " + this.session + ": Remove attribute " + name);
-        }
-        return this.session.removeAttribute(name);
-    }
-
-    @Override
-    public String toString() {
-        return this.id + " " + this.session.toString();
-    }
-
-    class LoggingByteChannel implements ByteChannel {
-
-        public int read(final ByteBuffer dst) throws IOException {
-            int bytesRead = session.channel().read(dst);
-            if (log.isDebugEnabled()) {
-                log.debug(id + " " + session + ": " + bytesRead + " bytes read");
-            }
-            if (bytesRead > 0 && wirelog.isEnabled()) {
-                ByteBuffer b = dst.duplicate();
-                int p = b.position();
-                b.limit(p);
-                b.position(p - bytesRead);
-                wirelog.input(b);
-            }
-            return bytesRead;
-        }
-
-        public int write(final ByteBuffer src) throws IOException {
-            int byteWritten = session.channel().write(src);
-            if (log.isDebugEnabled()) {
-                log.debug(id + " " + session + ": " + byteWritten + " bytes written");
-            }
-            if (byteWritten > 0 && wirelog.isEnabled()) {
-                ByteBuffer b = src.duplicate();
-                int p = b.position();
-                b.limit(p);
-                b.position(p - byteWritten);
-                wirelog.output(b);
-            }
-            return byteWritten;
-        }
-
-        public void close() throws IOException {
-            if (log.isDebugEnabled()) {
-                log.debug(id + " " + session + ": Channel close");
-            }
-            session.channel().close();
-        }
-
-        public boolean isOpen() {
-            return session.channel().isOpen();
-        }
-
-    }
-
-}
\ No newline at end of file
diff --git a/httpcore-contrib/src/main/java/org/apache/http/contrib/logging/LoggingNHttpClientConnectionFactory.java b/httpcore-contrib/src/main/java/org/apache/http/contrib/logging/LoggingNHttpClientConnectionFactory.java
deleted file mode 100644
index f8356de..0000000
--- a/httpcore-contrib/src/main/java/org/apache/http/contrib/logging/LoggingNHttpClientConnectionFactory.java
+++ /dev/null
@@ -1,62 +0,0 @@
-package org.apache.http.contrib.logging;
-/*
- * ====================================================================
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- *
- */
-
-import org.apache.http.HttpResponseFactory;
-import org.apache.http.annotation.Immutable;
-import org.apache.http.impl.DefaultHttpResponseFactory;
-import org.apache.http.impl.nio.DefaultNHttpClientConnection;
-import org.apache.http.impl.nio.DefaultNHttpClientConnectionFactory;
-import org.apache.http.nio.reactor.IOSession;
-import org.apache.http.nio.util.ByteBufferAllocator;
-import org.apache.http.nio.util.HeapByteBufferAllocator;
-import org.apache.http.params.HttpParams;
-
- at Immutable
-public class LoggingNHttpClientConnectionFactory extends DefaultNHttpClientConnectionFactory {
-
-    public LoggingNHttpClientConnectionFactory(
-            final HttpResponseFactory responseFactory,
-            final ByteBufferAllocator allocator,
-            final HttpParams params) {
-        super(responseFactory, allocator, params);
-    }
-
-    public LoggingNHttpClientConnectionFactory(final HttpParams params) {
-        this(new DefaultHttpResponseFactory(), new HeapByteBufferAllocator(), params);
-    }
-
-    @Override
-    protected DefaultNHttpClientConnection createConnection(
-            final IOSession session,
-            final HttpResponseFactory responseFactory, 
-            final ByteBufferAllocator allocator, 
-            final HttpParams params) {
-        return new LoggingNHttpClientConnection(session, responseFactory, allocator, params);
-    }
-
-}
diff --git a/httpcore-contrib/src/main/java/org/apache/http/contrib/logging/LoggingNHttpClientHandler.java b/httpcore-contrib/src/main/java/org/apache/http/contrib/logging/LoggingNHttpClientHandler.java
deleted file mode 100644
index 6145861..0000000
--- a/httpcore-contrib/src/main/java/org/apache/http/contrib/logging/LoggingNHttpClientHandler.java
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * ====================================================================
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- *
- */
-
-package org.apache.http.contrib.logging;
-
-import java.io.IOException;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.http.HttpException;
-import org.apache.http.HttpResponse;
-import org.apache.http.nio.ContentDecoder;
-import org.apache.http.nio.ContentEncoder;
-import org.apache.http.nio.NHttpClientConnection;
-import org.apache.http.nio.NHttpClientEventHandler;
-
-/**
- * Decorator class intended to transparently extend an {@link NHttpClientHandler}
- * with basic event logging capabilities using Commons Logging.
- *
- */
-public class LoggingNHttpClientHandler implements NHttpClientEventHandler {
-
-    private final Log log;
-    private final NHttpClientEventHandler handler;
-
-    public LoggingNHttpClientHandler(final NHttpClientEventHandler handler) {
-        super();
-        if (handler == null) {
-            throw new IllegalArgumentException("HTTP client handler may not be null");
-        }
-        this.handler = handler;
-        this.log = LogFactory.getLog(handler.getClass());
-    }
-
-    public void connected(
-            final NHttpClientConnection conn,
-            final Object attachment) throws IOException, HttpException {
-        if (this.log.isDebugEnabled()) {
-            this.log.debug(conn + ": Connected (" + attachment + ")");
-        }
-        this.handler.connected(conn, attachment);
-    }
-
-    public void closed(final NHttpClientConnection conn) {
-        if (this.log.isDebugEnabled()) {
-            this.log.debug(conn + ": Closed");
-        }
-        this.handler.closed(conn);
-    }
-
-    public void exception(
-            final NHttpClientConnection conn, final Exception ex) {
-        this.log.error(conn + ": " + ex.getMessage(), ex);
-        this.handler.exception(conn, ex);
-    }
-
-    public void requestReady(
-            final NHttpClientConnection conn) throws IOException, HttpException {
-        if (this.log.isDebugEnabled()) {
-            this.log.debug(conn + ": Request ready");
-        }
-        this.handler.requestReady(conn);
-    }
-
-    public void outputReady(
-            final NHttpClientConnection conn,
-            final ContentEncoder encoder) throws IOException, HttpException {
-        if (this.log.isDebugEnabled()) {
-            this.log.debug(conn + ": Output ready");
-        }
-        this.handler.outputReady(conn, encoder);
-        if (this.log.isDebugEnabled()) {
-            this.log.debug(conn + ": Content encoder " + encoder);
-        }
-    }
-
-    public void responseReceived(
-            final NHttpClientConnection conn) throws IOException, HttpException {
-        HttpResponse response = conn.getHttpResponse();
-        if (this.log.isDebugEnabled()) {
-            this.log.debug(conn + ": " + response.getStatusLine());
-        }
-        this.handler.responseReceived(conn);
-    }
-
-    public void inputReady(
-            final NHttpClientConnection conn,
-            final ContentDecoder decoder) throws IOException, HttpException {
-        if (this.log.isDebugEnabled()) {
-            this.log.debug(conn + ": Input ready");
-        }
-        this.handler.inputReady(conn, decoder);
-        if (this.log.isDebugEnabled()) {
-            this.log.debug(conn + ": Content decoder " + decoder);
-        }
-    }
-
-    public void endOfInput(
-            final NHttpClientConnection conn) throws IOException {
-        if (this.log.isDebugEnabled()) {
-            this.log.debug(conn + ": end of input");
-        }
-        this.handler.endOfInput(conn);
-    }
-
-    public void timeout(
-            final NHttpClientConnection conn) throws IOException, HttpException {
-        if (this.log.isDebugEnabled()) {
-            this.log.debug(conn + ": Timeout");
-        }
-        this.handler.timeout(conn);
-    }
-
-}
diff --git a/httpcore-contrib/src/main/java/org/apache/http/contrib/logging/LoggingNHttpServerConnectionFactory.java b/httpcore-contrib/src/main/java/org/apache/http/contrib/logging/LoggingNHttpServerConnectionFactory.java
deleted file mode 100644
index e5e6e06..0000000
--- a/httpcore-contrib/src/main/java/org/apache/http/contrib/logging/LoggingNHttpServerConnectionFactory.java
+++ /dev/null
@@ -1,62 +0,0 @@
-package org.apache.http.contrib.logging;
-/*
- * ====================================================================
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- *
- */
-
-import org.apache.http.HttpRequestFactory;
-import org.apache.http.annotation.Immutable;
-import org.apache.http.impl.DefaultHttpRequestFactory;
-import org.apache.http.impl.nio.DefaultNHttpServerConnection;
-import org.apache.http.impl.nio.DefaultNHttpServerConnectionFactory;
-import org.apache.http.nio.reactor.IOSession;
-import org.apache.http.nio.util.ByteBufferAllocator;
-import org.apache.http.nio.util.HeapByteBufferAllocator;
-import org.apache.http.params.HttpParams;
-
- at Immutable
-public class LoggingNHttpServerConnectionFactory extends DefaultNHttpServerConnectionFactory {
-
-    public LoggingNHttpServerConnectionFactory(
-            final HttpRequestFactory requestFactory,
-            final ByteBufferAllocator allocator,
-            final HttpParams params) {
-        super(requestFactory, allocator, params);
-    }
-
-    public LoggingNHttpServerConnectionFactory(final HttpParams params) {
-        this(new DefaultHttpRequestFactory(), new HeapByteBufferAllocator(), params);
-    }
-
-    @Override
-    protected DefaultNHttpServerConnection createConnection(
-            final IOSession session,
-            final HttpRequestFactory requestFactory, 
-            final ByteBufferAllocator allocator, 
-            final HttpParams params) {
-        return new LoggingNHttpServerConnection(session, requestFactory, allocator, params);
-    }
-    
-}
diff --git a/httpcore-contrib/src/main/java/org/apache/http/contrib/logging/LoggingNHttpServiceHandler.java b/httpcore-contrib/src/main/java/org/apache/http/contrib/logging/LoggingNHttpServiceHandler.java
deleted file mode 100644
index acfab1a..0000000
--- a/httpcore-contrib/src/main/java/org/apache/http/contrib/logging/LoggingNHttpServiceHandler.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * ====================================================================
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- *
- */
-
-package org.apache.http.contrib.logging;
-
-import java.io.IOException;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.http.HttpException;
-import org.apache.http.HttpRequest;
-import org.apache.http.nio.ContentDecoder;
-import org.apache.http.nio.ContentEncoder;
-import org.apache.http.nio.NHttpServerConnection;
-import org.apache.http.nio.NHttpServerEventHandler;
-
-/**
- * Decorator class intended to transparently extend an {@link NHttpServiceHandler}
- * with basic event logging capabilities using Commons Logging.
- *
- */
-public class LoggingNHttpServiceHandler implements NHttpServerEventHandler {
-
-    private final Log log;
-    private final NHttpServerEventHandler handler;
-
-    public LoggingNHttpServiceHandler(final NHttpServerEventHandler handler) {
-        super();
-        if (handler == null) {
-            throw new IllegalArgumentException("HTTP service handler may not be null");
-        }
-        this.handler = handler;
-        this.log = LogFactory.getLog(handler.getClass());
-    }
-
-    public void connected(
-            final NHttpServerConnection conn) throws IOException, HttpException {
-        if (this.log.isDebugEnabled()) {
-            this.log.debug(conn + ": Connected");
-        }
-        this.handler.connected(conn);
-    }
-
-    public void closed(final NHttpServerConnection conn) {
-        if (this.log.isDebugEnabled()) {
-            this.log.debug(conn + ": Closed");
-        }
-        this.handler.closed(conn);
-    }
-
-    public void exception(
-            final NHttpServerConnection conn, final Exception ex) {
-        this.log.error(conn + ": " + ex.getMessage(), ex);
-        this.handler.exception(conn, ex);
-    }
-
-    public void requestReceived(
-            final NHttpServerConnection conn) throws IOException, HttpException {
-        HttpRequest request = conn.getHttpRequest();
-        if (this.log.isDebugEnabled()) {
-            this.log.debug(conn + ": " + request.getRequestLine());
-        }
-        this.handler.requestReceived(conn);
-    }
-
-    public void outputReady(
-            final NHttpServerConnection conn,
-            final ContentEncoder encoder) throws IOException, HttpException {
-        if (this.log.isDebugEnabled()) {
-            this.log.debug(conn + ": Output ready");
-        }
-        this.handler.outputReady(conn, encoder);
-        if (this.log.isDebugEnabled()) {
-            this.log.debug(conn + ": Content encoder " + encoder);
-        }
-    }
-
-    public void responseReady(
-            final NHttpServerConnection conn) throws IOException, HttpException {
-        if (this.log.isDebugEnabled()) {
-            this.log.debug(conn + ": Response ready");
-        }
-        this.handler.responseReady(conn);
-    }
-
-    public void inputReady(
-            final NHttpServerConnection conn,
-            final ContentDecoder decoder) throws IOException, HttpException {
-        if (this.log.isDebugEnabled()) {
-            this.log.debug(conn + ": Input ready");
-        }
-        this.handler.inputReady(conn, decoder);
-        if (this.log.isDebugEnabled()) {
-            this.log.debug(conn + ": Content decoder " + decoder);
-        }
-    }
-    
-    public void endOfInput(
-            final NHttpServerConnection conn) throws IOException {
-        if (this.log.isDebugEnabled()) {
-            this.log.debug(conn + ": end of input");
-        }
-        this.handler.endOfInput(conn);
-    }
-
-    public void timeout(
-            final NHttpServerConnection conn) throws IOException {
-        if (this.log.isDebugEnabled()) {
-            this.log.debug(conn + ": Timeout");
-        }
-        this.handler.timeout(conn);
-    }
-
-}
diff --git a/httpcore-contrib/src/main/java/org/apache/http/contrib/sip/BasicCompactHeader.java b/httpcore-contrib/src/main/java/org/apache/http/contrib/sip/BasicCompactHeader.java
deleted file mode 100644
index ffa6386..0000000
--- a/httpcore-contrib/src/main/java/org/apache/http/contrib/sip/BasicCompactHeader.java
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * ====================================================================
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- *
- */
-
-package org.apache.http.contrib.sip;
-
-import org.apache.http.message.BasicHeader;
-
-
-/**
- * Represents a SIP (or HTTP) header field with optional compact name.
- *
- *
- */
-public class BasicCompactHeader extends BasicHeader
-    implements CompactHeader {
-
-    private static final long serialVersionUID = -8275767773930430518L;
-
-    /** The compact name, if there is one. */
-    private final String compact;
-
-
-    /**
-     * Constructor with names and value.
-     *
-     * @param fullname          the full header name
-     * @param compactname       the compact header name, or <code>null</code>
-     * @param value             the header value
-     */
-    public BasicCompactHeader(final String fullname,
-                              final String compactname,
-                              final String value) {
-        super(fullname, value);
-
-        if ((compactname != null) &&
-            (compactname.length() >= fullname.length()))  {
-            throw new IllegalArgumentException
-                ("Compact name must be shorter than full name. " +
-                 compactname + " -> " + fullname);
-        }
-
-        this.compact = compactname;
-    }
-
-
-    // non-javadoc, see interface CompactHeader
-    public String getCompactName() {
-        return this.compact;
-    }
-
-
-    /**
-     * Creates a compact header with automatic lookup.
-     *
-     * @param name      the header name, either full or compact
-     * @param value     the header value
-     * @param mapper    the header name mapper, or <code>null</code> for the
-     *                  {@link BasicCompactHeaderMapper#DEFAULT default}
-     */
-    public static
-        BasicCompactHeader newHeader(final String name, final String value,
-                                     CompactHeaderMapper mapper) {
-        if (name == null) {
-            throw new IllegalArgumentException
-                ("The name must not be null.");
-        }
-        // value will be checked by constructor later
-
-        if (mapper == null)
-            mapper = BasicCompactHeaderMapper.DEFAULT;
-
-        final String altname = mapper.getAlternateName(name);
-
-        String fname = name;
-        String cname = altname;
-
-        if ((altname != null) && (name.length() < altname.length())) {
-            // we were called with the compact name
-            fname = altname;
-            cname = name;
-        }
-
-        return new BasicCompactHeader(fname, cname, value);
-    }
-
-
-    // we might want a toString method that includes the short name, if defined
-
-    // default cloning implementation is fine
-}
diff --git a/httpcore-contrib/src/main/java/org/apache/http/contrib/sip/BasicCompactHeaderMapper.java b/httpcore-contrib/src/main/java/org/apache/http/contrib/sip/BasicCompactHeaderMapper.java
deleted file mode 100644
index 5001e28..0000000
--- a/httpcore-contrib/src/main/java/org/apache/http/contrib/sip/BasicCompactHeaderMapper.java
+++ /dev/null
@@ -1,208 +0,0 @@
-/*
- * ====================================================================
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- *
- */
-
-package org.apache.http.contrib.sip;
-
-import java.util.Map;
-import java.util.HashMap;
-import java.util.Collections;
-
-
-
-/**
- * Basic implementation of a {@link CompactHeaderMapper}.
- * Header names are assumed to be case insensitive.
- *
- *
- */
-public class BasicCompactHeaderMapper implements CompactHeaderMapper {
-
-    /**
-     * The map from compact names to full names.
-     * Keys are converted to lower case, values may be mixed case.
-     */
-    protected Map<String,String> mapCompactToFull;
-
-    /**
-     * The map from full names to compact names.
-     * Keys are converted to lower case, values may be mixed case.
-     */
-    protected Map<String,String> mapFullToCompact;
-
-
-    /**
-     * The default mapper.
-     * This mapper is initialized with the compact header names defined at
-     * <a href="http://www.iana.org/assignments/sip-parameters">
-     * http://www.iana.org/assignments/sip-parameters
-     * </a>
-     * on 2008-01-02.
-     */
-    // see below for static initialization
-    public final static CompactHeaderMapper DEFAULT;
-
-
-    /**
-     * Creates a new header mapper with an empty mapping.
-     */
-    public BasicCompactHeaderMapper() {
-        createMaps();
-    }
-
-
-    /**
-     * Initializes the two maps.
-     * The default implementation here creates an empty hash map for
-     * each attribute that is <code>null</code>.
-     * Derived implementations may choose to instantiate other
-     * map implementations, or to populate the maps by default.
-     * In the latter case, it is the responsibility of the dervied class
-     * to guarantee consistent mappings in both directions.
-     */
-    protected void createMaps() {
-        if (mapCompactToFull == null) {
-            mapCompactToFull = new HashMap<String,String>();
-        }
-        if (mapFullToCompact == null) {
-            mapFullToCompact = new HashMap<String,String>();
-        }
-    }
-
-
-    /**
-     * Adds a header name mapping.
-     *
-     * @param compact   the compact name of the header
-     * @param full      the full name of the header
-     */
-    public void addMapping(final String compact, final String full) {
-        if (compact == null) {
-            throw new IllegalArgumentException
-                ("The compact name must not be null.");
-        }
-        if (full == null) {
-            throw new IllegalArgumentException
-                ("The full name must not be null.");
-        }
-        if (compact.length() >= full.length()) {
-            throw new IllegalArgumentException
-                ("The compact name must be shorter than the full name. " +
-                 compact + " -> " + full);
-        }
-
-        mapCompactToFull.put(compact.toLowerCase(), full);
-        mapFullToCompact.put(full.toLowerCase(), compact);
-    }
-
-
-    /**
-     * Switches this mapper to read-only mode.
-     * Subsequent invocations of {@link #addMapping addMapping}
-     * will trigger an exception.
-     * <br/>
-     * The implementation here should be called only once.
-     * It replaces the internal maps with unmodifiable ones.
-     */
-    protected void makeReadOnly() {
-        mapCompactToFull = Collections.unmodifiableMap(mapCompactToFull);
-        mapFullToCompact = Collections.unmodifiableMap(mapFullToCompact);
-    }
-
-
-    // non-javadoc, see interface CompactHeaderMapper
-    public String getCompactName(final String fullname) {
-        if (fullname == null) {
-            throw new IllegalArgumentException
-                ("The full name must not be null.");
-        }
-        return mapFullToCompact.get(fullname.toLowerCase());
-    }
-
-
-    // non-javadoc, see interface CompactHeaderMapper
-    public String getFullName(final String compactname) {
-        if (compactname == null) {
-            throw new IllegalArgumentException
-                ("The compact name must not be null.");
-        }
-        return mapCompactToFull.get(compactname.toLowerCase());
-    }
-
-
-    // non-javadoc, see interface CompactHeaderMapper
-    public String getAlternateName(final String name) {
-        if (name == null) {
-            throw new IllegalArgumentException
-                ("The name must not be null.");
-        }
-
-        final String namelc = name.toLowerCase();
-        String       result = null;
-
-        // to minimize lookups, use a heuristic to determine the direction
-        boolean iscompact = name.length() < 2;
-        if (iscompact) {
-            result = mapCompactToFull.get(namelc);
-        }
-        if (result == null) {
-            result = mapFullToCompact.get(namelc);
-        }
-        if ((result == null) && !iscompact) {
-            result = mapCompactToFull.get(namelc);
-        }
-
-        return result;
-    }
-
-
-    // initializes the default mapper and switches it to read-only mode
-    static {
-        BasicCompactHeaderMapper chm = new BasicCompactHeaderMapper();
-        chm.addMapping("a", "Accept-Contact");
-        chm.addMapping("u", "Allow-Events");
-        chm.addMapping("i", "Call-ID");
-        chm.addMapping("m", "Contact");
-        chm.addMapping("e", "Content-Encoding");
-        chm.addMapping("l", "Content-Length");
-        chm.addMapping("c", "Content-Type");
-        chm.addMapping("o", "Event");
-        chm.addMapping("f", "From");
-        chm.addMapping("y", "Identity");
-        chm.addMapping("n", "Identity-Info");
-        chm.addMapping("r", "Refer-To");
-        chm.addMapping("b", "Referred-By");
-        chm.addMapping("j", "Reject-Contact");
-        chm.addMapping("d", "Request-Disposition");
-        chm.addMapping("x", "Session-Expires");
-        chm.addMapping("s", "Subject");
-        chm.addMapping("k", "Supported");
-        chm.addMapping("t", "To");
-        chm.addMapping("v", "Via");
-        chm.makeReadOnly();
-        DEFAULT = chm;
-    }
-}
diff --git a/httpcore-contrib/src/main/java/org/apache/http/contrib/sip/BasicSipLineParser.java b/httpcore-contrib/src/main/java/org/apache/http/contrib/sip/BasicSipLineParser.java
deleted file mode 100644
index c9b6168..0000000
--- a/httpcore-contrib/src/main/java/org/apache/http/contrib/sip/BasicSipLineParser.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * ====================================================================
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- *
- */
-
-package org.apache.http.contrib.sip;
-
-import org.apache.http.Header;
-import org.apache.http.ParseException;
-import org.apache.http.util.CharArrayBuffer;
-import org.apache.http.message.BasicLineParser;
-
-
-/**
- * Basic parser for lines in the head section of an SIP message.
- *
- *
- */
-public class BasicSipLineParser extends BasicLineParser {
-
-    /** The header name mapper to use, never <code>null</code>. */
-    protected final CompactHeaderMapper mapper;
-
-
-    /**
-     * A default instance of this class, for use as default or fallback.
-     */
-    public final static
-        BasicSipLineParser DEFAULT = new BasicSipLineParser(null);
-
-
-    /**
-     * Creates a new line parser for SIP protocol.
-     *
-     * @param mapper    the header name mapper, or <code>null</code> for the
-     *                  {@link BasicCompactHeaderMapper#DEFAULT default}
-     */
-    public BasicSipLineParser(CompactHeaderMapper mapper) {
-        super(SipVersion.SIP_2_0);
-        this.mapper = (mapper != null) ?
-            mapper : BasicCompactHeaderMapper.DEFAULT;
-    }
-
-
-    // non-javadoc, see interface LineParser
-    @Override
-    public Header parseHeader(CharArrayBuffer buffer)
-        throws ParseException {
-
-        // the actual parser code is in the constructor of BufferedHeader
-        return new BufferedCompactHeader(buffer, mapper);
-    }
-
-}
-
diff --git a/httpcore-contrib/src/main/java/org/apache/http/contrib/sip/BufferedCompactHeader.java b/httpcore-contrib/src/main/java/org/apache/http/contrib/sip/BufferedCompactHeader.java
deleted file mode 100644
index 1686e5b..0000000
--- a/httpcore-contrib/src/main/java/org/apache/http/contrib/sip/BufferedCompactHeader.java
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
- * ====================================================================
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- *
- */
-
-package org.apache.http.contrib.sip;
-
-import org.apache.http.FormattedHeader;
-import org.apache.http.HeaderElement;
-import org.apache.http.ParseException;
-import org.apache.http.util.CharArrayBuffer;
-import org.apache.http.message.ParserCursor;
-import org.apache.http.message.BasicHeaderValueParser;
-
-
-/**
- * Represents a SIP (or HTTP) header field parsed 'on demand'.
- * The name of the header will be parsed and mapped immediately,
- * the value only when accessed
- *
- *
- */
-public class BufferedCompactHeader
-    implements CompactHeader, FormattedHeader, Cloneable {
-
-    /** The full header name. */
-    private final String fullName;
-
-    /** The compact header name, if there is one. */
-    private final String compactName;
-
-    /**
-     * The buffer containing the entire header line.
-     */
-    private final CharArrayBuffer buffer;
-
-    /**
-     * The beginning of the header value in the buffer
-     */
-    private final int valuePos;
-
-
-    /**
-     * Creates a new header from a buffer.
-     * The name of the header will be parsed and mapped immediately,
-     * the value only if it is accessed.
-     *
-     * @param buffer    the buffer containing the header to represent
-     * @param mapper    the header name mapper, or <code>null</code> for the
-     *                  {@link BasicCompactHeaderMapper#DEFAULT default}
-     *
-     * @throws ParseException   in case of a parse error
-     */
-    public BufferedCompactHeader(final CharArrayBuffer buffer,
-                                 CompactHeaderMapper mapper)
-        throws ParseException {
-
-        super();
-        if (buffer == null) {
-            throw new IllegalArgumentException
-                ("Char array buffer may not be null");
-        }
-
-        final int colon = buffer.indexOf(':');
-        if (colon == -1) {
-            throw new ParseException
-                ("Missing colon after header name.\n" + buffer.toString());
-        }
-        final String name = buffer.substringTrimmed(0, colon);
-        if (name.length() == 0) {
-            throw new ParseException
-                ("Missing header name.\n" + buffer.toString());
-        }
-
-        if (mapper == null)
-            mapper = BasicCompactHeaderMapper.DEFAULT;
-        final String altname = mapper.getAlternateName(name);
-
-        String fname = name;
-        String cname = altname;
-
-        if ((altname != null) && (name.length() < altname.length())) {
-            // the header uses the compact name
-            fname = altname;
-            cname = name;
-        }
-
-        this.fullName    = fname;
-        this.compactName = cname;
-        this.buffer      = buffer;
-        this.valuePos    = colon + 1;
-    }
-
-
-    // non-javadoc, see interface Header
-    public String getName() {
-        return this.fullName;
-    }
-
-
-    // non-javadoc, see interface CompactHeader
-    public String getCompactName() {
-        return this.compactName;
-    }
-
-    // non-javadoc, see interface Header
-    public String getValue() {
-        return this.buffer.substringTrimmed(this.valuePos,
-                                            this.buffer.length());
-    }
-
-    // non-javadoc, see interface Header
-    public HeaderElement[] getElements() throws ParseException {
-        ParserCursor cursor = new ParserCursor(0, this.buffer.length());
-        cursor.updatePos(this.valuePos);
-        return BasicHeaderValueParser.DEFAULT
-            .parseElements(this.buffer, cursor);
-    }
-
-    // non-javadoc, see interface BufferedHeader
-    public int getValuePos() {
-        return this.valuePos;
-    }
-
-    // non-javadoc, see interface BufferedHeader
-    public CharArrayBuffer getBuffer() {
-        return this.buffer;
-    }
-
-    @Override
-    public String toString() {
-        return this.buffer.toString();
-    }
-
-    @Override
-    public Object clone() throws CloneNotSupportedException {
-        // buffer is considered immutable
-        // no need to make a copy of it
-        return super.clone();
-    }
-
-}
-
-
diff --git a/httpcore-contrib/src/main/java/org/apache/http/contrib/sip/CompactHeader.java b/httpcore-contrib/src/main/java/org/apache/http/contrib/sip/CompactHeader.java
deleted file mode 100644
index d192ad6..0000000
--- a/httpcore-contrib/src/main/java/org/apache/http/contrib/sip/CompactHeader.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * ====================================================================
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- *
- */
-
-package org.apache.http.contrib.sip;
-
-
-import org.apache.http.Header;
-
-
-/**
- * Represents an SIP (or HTTP) header field with an optional compact name.
- * RFC 3261 (SIP/2.0), section 7.3.3 specifies that some header field
- * names have an abbreviated form which is equivalent to the full name.
- * All compact header names defined for SIP are registered at
- * <a href="http://www.iana.org/assignments/sip-parameters">
- * http://www.iana.org/assignments/sip-parameters
- * </a>.
- * <br/>
- * While all compact names defined so far are single-character names,
- * RFC 3261 does not mandate that. This interface therefore allows for
- * strings as the compact name.
- *
- *
- */
-public interface CompactHeader extends Header {
-
-    /**
-     * Obtains the name of this header in compact form, if there is one.
-     *
-     * @return  the compact name of this header, or
-     *          <code>null</code> if there is none
-     */
-    String getCompactName()
-        ;
-
-}
diff --git a/httpcore-contrib/src/main/java/org/apache/http/contrib/sip/CompactHeaderMapper.java b/httpcore-contrib/src/main/java/org/apache/http/contrib/sip/CompactHeaderMapper.java
deleted file mode 100644
index 88af205..0000000
--- a/httpcore-contrib/src/main/java/org/apache/http/contrib/sip/CompactHeaderMapper.java
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * ====================================================================
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- *
- */
-
-package org.apache.http.contrib.sip;
-
-
-
-/**
- * A mapper between full and compact header names.
- * RFC 3261 (SIP/2.0), section 7.3.3 specifies that some header field
- * names have an abbreviated form which is equivalent to the full name.
- * All compact header names defined for SIP are registered at
- * <a href="http://www.iana.org/assignments/sip-parameters">
- * http://www.iana.org/assignments/sip-parameters
- * </a>.
- * <br/>
- * While all compact names defined so far are single-character names,
- * RFC 3261 does not mandate that. This interface therefore allows for
- * strings as the compact name.
- *
- *
- */
-public interface CompactHeaderMapper {
-
-    /**
-     * Obtains the compact name for the given full name.
-     *
-     * @param fullname  the header name for which to look up the compact form
-     *
-     * @return  the compact form of the argument header name, or
-     *          <code>null</code> if there is none
-     */
-    String getCompactName(String fullname)
-        ;
-
-
-    /**
-     * Obtains the full name for the given compact name.
-     *
-     * @param compactname  the compact name for which to look up the full name
-     *
-     * @return  the full name of the argument compact header name, or
-     *          <code>null</code> if there is none
-     */
-    String getFullName(String compactname)
-        ;
-
-
-    /**
-     * Obtains the alternate name for the given header name.
-     * This performs a lookup in both directions, if necessary.
-     * <br/>
-     * If the returned name is shorter than the argument name,
-     * the argument was a full header name and the result is
-     * the compact name.
-     * If the returned name is longer than the argument name,
-     * the argument was a compact header name and the result
-     * is the full name.
-     * If the returned name has the same length as the argument name,
-     * somebody didn't understand the concept of a <i>compact form</i>
-     * when defining the mapping. You should expect malfunctioning
-     * applications in this case.
-     *
-     * @param name      the header name to map, either a full or compact name
-     *
-     * @return  the alternate header name, or
-     *          <code>null</code> if there is none
-     */
-    String getAlternateName(String name)
-        ;
-}
diff --git a/httpcore-contrib/src/main/java/org/apache/http/contrib/sip/EnglishSipReasonPhraseCatalog.java b/httpcore-contrib/src/main/java/org/apache/http/contrib/sip/EnglishSipReasonPhraseCatalog.java
deleted file mode 100644
index 73ad509..0000000
--- a/httpcore-contrib/src/main/java/org/apache/http/contrib/sip/EnglishSipReasonPhraseCatalog.java
+++ /dev/null
@@ -1,266 +0,0 @@
-/*
- * ====================================================================
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- *
- */
-
-package org.apache.http.contrib.sip;
-
-import java.util.Locale;
-import java.util.Map;
-import java.util.HashMap;
-
-import org.apache.http.ReasonPhraseCatalog;
-
-
-/**
- * English reason phrases for SIP status codes.
- * All status codes defined in {@link SipStatus} are supported.
- * See <a href="http://www.iana.org/assignments/sip-parameters">
- * http://www.iana.org/assignments/sip-parameters
- * </a>
- * for a full list of registered SIP status codes and the defining RFCs.
- *
- *
- */
-public class EnglishSipReasonPhraseCatalog
-    implements ReasonPhraseCatalog {
-
-    // static map with english reason phrases defined below
-
-    /**
-     * The default instance of this catalog.
-     * This catalog is thread safe, so there typically
-     * is no need to create other instances.
-     */
-    public final static EnglishSipReasonPhraseCatalog INSTANCE =
-        new EnglishSipReasonPhraseCatalog();
-
-
-    /**
-     * Restricted default constructor, for derived classes.
-     * If you need an instance of this class, use {@link #INSTANCE INSTANCE}.
-     */
-    protected EnglishSipReasonPhraseCatalog() {
-        // no body
-    }
-
-
-    /**
-     * Obtains the reason phrase for a status code.
-     *
-     * @param status    the status code, in the range 100-699
-     * @param loc       ignored
-     *
-     * @return  the reason phrase, or <code>null</code>
-     */
-    public String getReason(int status, Locale loc) {
-        if ((status < 100) || (status >= 700)) {
-            throw new IllegalArgumentException
-                ("Unknown category for status code " + status + ".");
-        }
-
-        // Unlike HTTP status codes, those for SIP are not compact
-        // in each category. We therefore use a map for lookup.
-
-        return REASON_PHRASES.get(Integer.valueOf(status));
-    }
-
-
-
-    /**
-     * Reason phrases lookup table.
-     * Since this attribute is private and never exposed,
-     * we don't need to turn it into an unmodifiable map.
-     */
-    // see below for static initialization
-    private static final
-        Map<Integer,String> REASON_PHRASES = new HashMap<Integer,String>();
-
-
-
-    /**
-     * Stores the given reason phrase, by status code.
-     * Helper method to initialize the static lookup map.
-     *
-     * @param status    the status code for which to define the phrase
-     * @param reason    the reason phrase for this status code
-     */
-    private static void setReason(int status, String reason) {
-        REASON_PHRASES.put(Integer.valueOf(status), reason);
-    }
-
-
-    // ----------------------------------------------------- Static Initializer
-
-    /** Set up status code to "reason phrase" map. */
-    static {
-
-        // --- 1xx Informational ---
-        setReason(SipStatus.SC_CONTINUE,
-                  "Trying");
-        setReason(SipStatus.SC_RINGING,
-                  "Ringing");
-        setReason(SipStatus.SC_CALL_IS_BEING_FORWARDED,
-                  "Call Is Being Forwarded");
-        setReason(SipStatus.SC_QUEUED,
-                  "Queued");
-        setReason(SipStatus.SC_SESSION_PROGRESS,
-                  "Session Progress");
-
-
-        // --- 2xx Successful ---
-        setReason(SipStatus.SC_OK,
-                  "OK");
-        setReason(SipStatus.SC_ACCEPTED,
-                  "Accepted");
-
-
-        // --- 3xx Redirection ---
-        setReason(SipStatus.SC_MULTIPLE_CHOICES,
-                  "Multiple Choices");
-        setReason(SipStatus.SC_MOVED_PERMANENTLY,
-                  "Moved Permanently");
-        setReason(SipStatus.SC_MOVED_TEMPORARILY,
-                  "Moved Temporarily");
-        setReason(SipStatus.SC_USE_PROXY,
-                  "Use Proxy");
-        setReason(SipStatus.SC_ALTERNATIVE_SERVICE,
-                  "Alternative Service");
-
-
-        // --- 4xx Request Failure ---
-        setReason(SipStatus.SC_BAD_REQUEST,
-                  "Bad Request");
-        setReason(SipStatus.SC_UNAUTHORIZED,
-                  "Unauthorized");
-        setReason(SipStatus.SC_PAYMENT_REQUIRED,
-                  "Payment Required");
-        setReason(SipStatus.SC_FORBIDDEN,
-                  "Forbidden");
-        setReason(SipStatus.SC_NOT_FOUND,
-                  "Not Found");
-        setReason(SipStatus.SC_METHOD_NOT_ALLOWED,
-                  "Method Not Allowed");
-        setReason(SipStatus.SC_NOT_ACCEPTABLE,
-                  "Not Acceptable");
-        setReason(SipStatus.SC_PROXY_AUTHENTICATION_REQUIRED,
-                  "Proxy Authentication Required");
-        setReason(SipStatus.SC_REQUEST_TIMEOUT,
-                  "Request Timeout");
-        setReason(SipStatus.SC_GONE,
-                  "Gone");
-        setReason(SipStatus.SC_CONDITIONAL_REQUEST_FAILED,
-                  "Conditional Request Failed");
-        setReason(SipStatus.SC_REQUEST_ENTITY_TOO_LARGE,
-                  "Request Entity Too Large");
-        setReason(SipStatus.SC_REQUEST_URI_TOO_LONG,
-                  "Request-URI Too Long");
-        setReason(SipStatus.SC_UNSUPPORTED_MEDIA_TYPE,
-                  "Unsupported Media Type");
-        setReason(SipStatus.SC_UNSUPPORTED_URI_SCHEME,
-                  "Unsupported URI Scheme");
-        setReason(SipStatus.SC_UNKNOWN_RESOURCE_PRIORITY,
-                  "Unknown Resource-Priority");
-        setReason(SipStatus.SC_BAD_EXTENSION,
-                  "Bad Extension");
-        setReason(SipStatus.SC_EXTENSION_REQUIRED,
-                  "Extension Required");
-        setReason(SipStatus.SC_SESSION_INTERVAL_TOO_SMALL,
-                  "Session Interval Too Small");
-        setReason(SipStatus.SC_INTERVAL_TOO_BRIEF,
-                  "Interval Too Brief");
-        setReason(SipStatus.SC_USE_IDENTITY_HEADER,
-                  "Use Identity Header");
-        setReason(SipStatus.SC_PROVIDE_REFERRER_IDENTITY,
-                  "Provide Referrer Identity");
-        setReason(SipStatus.SC_ANONYMITY_DISALLOWED,
-                  "Anonymity Disallowed");
-        setReason(SipStatus.SC_BAD_IDENTITY_INFO,
-                  "Bad Identity-Info");
-        setReason(SipStatus.SC_UNSUPPORTED_CERTIFICATE,
-                  "Unsupported Certificate");
-        setReason(SipStatus.SC_INVALID_IDENTITY_HEADER,
-                  "Invalid Identity Header");
-        setReason(SipStatus.SC_TEMPORARILY_UNAVAILABLE,
-                  "Temporarily Unavailable");
-        setReason(SipStatus.SC_CALL_TRANSACTION_DOES_NOT_EXIST,
-                  "Call/Transaction Does Not Exist");
-        setReason(SipStatus.SC_LOOP_DETECTED,
-                  "Loop Detected");
-        setReason(SipStatus.SC_TOO_MANY_HOPS,
-                  "Too Many Hops");
-        setReason(SipStatus.SC_ADDRESS_INCOMPLETE,
-                  "Address Incomplete");
-        setReason(SipStatus.SC_AMBIGUOUS,
-                  "Ambiguous");
-        setReason(SipStatus.SC_BUSY_HERE,
-                  "Busy Here");
-        setReason(SipStatus.SC_REQUEST_TERMINATED,
-                  "Request Terminated");
-        setReason(SipStatus.SC_NOT_ACCEPTABLE_HERE,
-                  "Not Acceptable Here");
-        setReason(SipStatus.SC_BAD_EVENT,
-                  "Bad Event");
-        setReason(SipStatus.SC_REQUEST_PENDING,
-                  "Request Pending");
-        setReason(SipStatus.SC_UNDECIPHERABLE,
-                  "Undecipherable");
-        setReason(SipStatus.SC_SECURITY_AGREEMENT_REQUIRED,
-                  "Security Agreement Required");
-
-
-        // --- 5xx Server Failure ---
-        setReason(SipStatus.SC_SERVER_INTERNAL_ERROR,
-                  "Server Internal Error");
-        setReason(SipStatus.SC_NOT_IMPLEMENTED,
-                  "Not Implemented");
-        setReason(SipStatus.SC_BAD_GATEWAY,
-                  "Bad Gateway");
-        setReason(SipStatus.SC_SERVICE_UNAVAILABLE,
-                  "Service Unavailable");
-        setReason(SipStatus.SC_SERVER_TIMEOUT,
-                  "Server Time-out");
-        setReason(SipStatus.SC_VERSION_NOT_SUPPORTED,
-                  "Version Not Supported");
-        setReason(SipStatus.SC_MESSAGE_TOO_LARGE,
-                  "Message Too Large");
-        setReason(SipStatus.SC_PRECONDITION_FAILURE,
-                  "Precondition Failure");
-
-
-        // --- 6xx Global Failures ---
-        setReason(SipStatus.SC_BUSY_EVERYWHERE,
-                  "Busy Everywhere");
-        setReason(SipStatus.SC_DECLINE,
-                  "Decline");
-        setReason(SipStatus.SC_DOES_NOT_EXIST_ANYWHERE,
-                  "Does Not Exist Anywhere");
-        setReason(SipStatus.SC_NOT_ACCEPTABLE_ANYWHERE,
-                  "Not Acceptable");
-
-    } // static initializer
-
-
-}
diff --git a/httpcore-contrib/src/main/java/org/apache/http/contrib/sip/SipException.java b/httpcore-contrib/src/main/java/org/apache/http/contrib/sip/SipException.java
deleted file mode 100644
index dc9afe0..0000000
--- a/httpcore-contrib/src/main/java/org/apache/http/contrib/sip/SipException.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * ====================================================================
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- *
- */
-
-package org.apache.http.contrib.sip;
-
-
-import org.apache.http.HttpException;
-
-
-/**
- * Signals that an SIP exception has occurred.
- * This is for protocol errors specific to SIP,
- * as opposed to protocol errors shared with HTTP.
- *
- *
- */
-public class SipException extends HttpException {
-
-    private static final long serialVersionUID = 337592534308025800L;
-
-    /**
-     * Creates a new SipException with a <tt>null</tt> detail message.
-     */
-    public SipException() {
-        super();
-    }
-
-    /**
-     * Creates a new SipException with the specified detail message.
-     *
-     * @param message the exception detail message
-     */
-    public SipException(final String message) {
-        super(message);
-    }
-
-    /**
-     * Creates a new SipException with the specified detail message and cause.
-     *
-     * @param message the exception detail message
-     * @param cause   the <tt>Throwable</tt> that caused this exception, or
-     *                <tt>null</tt> if the cause is unavailable, unknown, or
-     *                not a <tt>Throwable</tt>
-     */
-    public SipException(final String message, final Throwable cause) {
-        super(message, cause);
-    }
-
-}
diff --git a/httpcore-contrib/src/main/java/org/apache/http/contrib/sip/SipStatus.java b/httpcore-contrib/src/main/java/org/apache/http/contrib/sip/SipStatus.java
deleted file mode 100644
index 9828b21..0000000
--- a/httpcore-contrib/src/main/java/org/apache/http/contrib/sip/SipStatus.java
+++ /dev/null
@@ -1,267 +0,0 @@
-/*
- * ====================================================================
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- *
- */
-
-package org.apache.http.contrib.sip;
-
-/**
- * Constants enumerating the SIP status codes.
- * All status codes registered at
- * <a href="http://www.iana.org/assignments/sip-parameters">
- * http://www.iana.org/assignments/sip-parameters
- * </a>
- * on 2007-12-30 are listed.
- * The defining RFCs include RFC 3261 (SIP/2.0),
- * RFC 3265 (SIP-Specific Event Notification),
- * RFC 4412 (Communications Resource Priority for SIP),
- * RFC 4474 (Enhancements for Authenticated Identity Management in SIP),
- * and others.
- *
- *
- */
-public interface SipStatus {
-
-    // --- 1xx Informational ---
-
-    /** <tt>100 Trying</tt>. RFC 3261, section 21.1.1. */
-    public static final int SC_CONTINUE = 100;
-
-    /** <tt>180 Ringing</tt>. RFC 3261, section 21.1.2. */
-    public static final int SC_RINGING = 180;
-
-    /** <tt>181 Call Is Being Forwarded</tt>. RFC 3261, section 21.1.3. */
-    public static final int SC_CALL_IS_BEING_FORWARDED = 181;
-
-    /** <tt>182 Queued</tt>. RFC 3261, section 21.1.4. */
-    public static final int SC_QUEUED = 182;
-
-    /** <tt>183 Session Progress</tt>. RFC 3261, section 21.1.5. */
-    public static final int SC_SESSION_PROGRESS = 183;
-
-
-    // --- 2xx Successful ---
-
-    /** <tt>200 OK</tt>. RFC 3261, section 21.2.1. */
-    public static final int SC_OK = 200;
-
-    /** <tt>202 Accepted</tt>. RFC 3265, section 6.4. */
-    public static final int SC_ACCEPTED = 202;
-
-
-    // --- 3xx Redirection ---
-
-    /** <tt>300 Multiple Choices</tt>. RFC 3261, section 21.3.1. */
-    public static final int SC_MULTIPLE_CHOICES = 300;
-
-    /** <tt>301 Moved Permanently</tt>. RFC 3261, section 21.3.2. */
-    public static final int SC_MOVED_PERMANENTLY = 301;
-
-    /** <tt>302 Moved Temporarily</tt>. RFC 3261, section 21.3.3. */
-    public static final int SC_MOVED_TEMPORARILY = 302;
-
-    /** <tt>305 Use Proxy</tt>. RFC 3261, section 21.3.4. */
-    public static final int SC_USE_PROXY = 305;
-
-    /** <tt>380 Alternative Service</tt>. RFC 3261, section 21.3.5. */
-    public static final int SC_ALTERNATIVE_SERVICE = 380;
-
-
-    // --- 4xx Request Failure ---
-
-
-    /** <tt>400 Bad Request</tt>. RFC 3261, section 21.4.1. */
-    public static final int SC_BAD_REQUEST = 400;
-
-    /** <tt>401 Unauthorized</tt>. RFC 3261, section 21.4.2. */
-    public static final int SC_UNAUTHORIZED = 401;
-
-    /** <tt>402 Payment Required</tt>. RFC 3261, section 21.4.3. */
-    public static final int SC_PAYMENT_REQUIRED = 402;
-
-    /** <tt>403 Forbidden</tt>. RFC 3261, section 21.4.4. */
-    public static final int SC_FORBIDDEN = 403;
-
-    /** <tt>404 Not Found</tt>. RFC 3261, section 21.4.5. */
-    public static final int SC_NOT_FOUND = 404;
-
-    /** <tt>405 Method Not Allowed</tt>. RFC 3261, section 21.4.6. */
-    public static final int SC_METHOD_NOT_ALLOWED = 405;
-
-    /** <tt>406 Not Acceptable</tt>. RFC 3261, section 21.4.7. */
-    public static final int SC_NOT_ACCEPTABLE = 406;
-
-    /**
-     * <tt>407 Proxy Authentication Required</tt>.
-     * RFC 3261, section 21.4.8.
-     */
-    public static final int SC_PROXY_AUTHENTICATION_REQUIRED = 407;
-
-    /** <tt>408 Request Timeout</tt>. RFC 3261, section 21.4.9. */
-    public static final int SC_REQUEST_TIMEOUT = 408;
-
-    /** <tt>410 Gone</tt>. RFC 3261, section 21.4.10. */
-    public static final int SC_GONE = 410;
-
-    /** <tt>412 Conditional Request Failed</tt>. RFC 3903, section 11.2.1. */
-    public static final int SC_CONDITIONAL_REQUEST_FAILED = 412;
-
-    /** <tt>413 Request Entity Too Large</tt>. RFC 3261, section 21.4.11. */
-    public static final int SC_REQUEST_ENTITY_TOO_LARGE = 413;
-
-    /** <tt>414 Request-URI Too Long</tt>. RFC 3261, section 21.4.12. */
-    public static final int SC_REQUEST_URI_TOO_LONG = 414;
-
-    /** <tt>415 Unsupported Media Type</tt>. RFC 3261, section 21.4.13. */
-    public static final int SC_UNSUPPORTED_MEDIA_TYPE = 415;
-
-    /** <tt>416 Unsupported URI Scheme</tt>. RFC 3261, section 21.4.14. */
-    public static final int SC_UNSUPPORTED_URI_SCHEME = 416;
-
-    /** <tt>417 Unknown Resource-Priority</tt>. RFC 4412, section 12.4. */
-    public static final int SC_UNKNOWN_RESOURCE_PRIORITY = 417;
-
-    /** <tt>420 Bad Extension</tt>. RFC 3261, section 21.4.15. */
-    public static final int SC_BAD_EXTENSION = 420;
-
-    /** <tt>421 Extension Required</tt>. RFC 3261, section 21.4.16. */
-    public static final int SC_EXTENSION_REQUIRED = 421;
-
-    /** <tt>422 Session Interval Too Small</tt>. RFC 4028, chapter 6. */
-    public static final int SC_SESSION_INTERVAL_TOO_SMALL = 422;
-
-    /** <tt>423 Interval Too Brief</tt>. RFC 3261, section 21.4.17. */
-    public static final int SC_INTERVAL_TOO_BRIEF = 423;
-
-    /** <tt>428 Use Identity Header</tt>. RFC 4474, section 14.2. */
-    public static final int SC_USE_IDENTITY_HEADER = 428;
-
-    /** <tt>429 Provide Referrer Identity</tt>. RFC 3892, chapter 5. */
-    public static final int SC_PROVIDE_REFERRER_IDENTITY = 429;
-
-    /** <tt>433 Anonymity Disallowed</tt>. RFC 5079, chapter 5. */
-    public static final int SC_ANONYMITY_DISALLOWED = 433;
-
-    /** <tt>436 Bad Identity-Info</tt>. RFC 4474, section 14.3. */
-    public static final int SC_BAD_IDENTITY_INFO = 436;
-
-    /** <tt>437 Unsupported Certificate</tt>. RFC 4474, section 14.4. */
-    public static final int SC_UNSUPPORTED_CERTIFICATE = 437;
-
-    /** <tt>438 Invalid Identity Header</tt>. RFC 4474, section 14.5. */
-    public static final int SC_INVALID_IDENTITY_HEADER = 438;
-
-    /** <tt>480 Temporarily Unavailable</tt>. RFC 3261, section 21.4.18. */
-    public static final int SC_TEMPORARILY_UNAVAILABLE = 480;
-
-    /**
-     * <tt>481 Call/Transaction Does Not Exist</tt>.
-     * RFC 3261, section 21.4.19.
-     */
-    public static final int SC_CALL_TRANSACTION_DOES_NOT_EXIST = 481;
-
-    /** <tt>482 Loop Detected</tt>. RFC 3261, section 21.4.20. */
-    public static final int SC_LOOP_DETECTED = 482;
-
-    /** <tt>483 Too Many Hops</tt>. RFC 3261, section 21.4.21. */
-    public static final int SC_TOO_MANY_HOPS = 483;
-
-    /** <tt>484 Address Incomplete</tt>. RFC 3261, section 21.4.22. */
-    public static final int SC_ADDRESS_INCOMPLETE = 484;
-
-    /** <tt>485 Ambiguous</tt>. RFC 3261, section 21.4.23. */
-    public static final int SC_AMBIGUOUS = 485;
-
-    /** <tt>486 Busy Here</tt>. RFC 3261, section 21.4.24. */
-    public static final int SC_BUSY_HERE = 486;
-
-    /** <tt>487 Request Terminated</tt>. RFC 3261, section 21.4.25. */
-    public static final int SC_REQUEST_TERMINATED = 487;
-
-    /** <tt>488 Not Acceptable Here</tt>. RFC 3261, section 21.4.26. */
-    public static final int SC_NOT_ACCEPTABLE_HERE = 488;
-
-    /** <tt>489 Bad Event</tt>. RFC 3265, section 6.4. */
-    public static final int SC_BAD_EVENT = 489;
-
-    /** <tt>491 Request Pending</tt>. RFC 3261, section 21.4.27. */
-    public static final int SC_REQUEST_PENDING = 491;
-
-    /** <tt>493 Undecipherable</tt>. RFC 3261, section 21.4.28. */
-    public static final int SC_UNDECIPHERABLE = 493;
-
-    /** <tt>494 Security Agreement Required</tt>. RFC 3329, section 6.4. */
-    public static final int SC_SECURITY_AGREEMENT_REQUIRED = 494;
-
-
-    // --- 5xx Server Failure ---
-
-    /** <tt>500 Server Internal Error</tt>. RFC 3261, section 21.5.1. */
-    public static final int SC_SERVER_INTERNAL_ERROR = 500;
-
-    /** <tt>501 Not Implemented</tt>. RFC 3261, section 21.5.2. */
-    public static final int SC_NOT_IMPLEMENTED = 501;
-
-    /** <tt>502 Bad Gateway</tt>. RFC 3261, section 21.5.3. */
-    public static final int SC_BAD_GATEWAY = 502;
-
-    /** <tt>503 Service Unavailable</tt>. RFC 3261, section 21.5.4. */
-    public static final int SC_SERVICE_UNAVAILABLE = 503;
-
-    /** <tt>504 Server Time-out</tt>. RFC 3261, section 21.5.5. */
-    public static final int SC_SERVER_TIMEOUT = 504;
-
-    /** <tt>505 Version Not Supported</tt>. RFC 3261, section 21.5.6. */
-    public static final int SC_VERSION_NOT_SUPPORTED = 505;
-
-    /** <tt>513 Message Too Large</tt>. RFC 3261, section 21.5.7. */
-    public static final int SC_MESSAGE_TOO_LARGE = 513;
-
-    /** <tt>580 Precondition Failure</tt>. RFC 3312, chapter 8. */
-    public static final int SC_PRECONDITION_FAILURE = 580;
-
-
-    // --- 6xx Global Failures ---
-
-    /** <tt>600 Busy Everywhere</tt>. RFC 3261, section 21.6.1. */
-    public static final int SC_BUSY_EVERYWHERE = 600;
-
-    /** <tt>603 Decline</tt>. RFC 3261, section 21.6.2. */
-    public static final int SC_DECLINE = 603;
-
-    /** <tt>604 Does Not Exist Anywhere</tt>. RFC 3261, section 21.6.3. */
-    public static final int SC_DOES_NOT_EXIST_ANYWHERE = 604;
-
-    /**
-     * <tt>606 Not Acceptable</tt>. RFC 3261, section 21.6.4.
-     * Status codes 606 and 406 both indicate "Not Acceptable",
-     * but we can only define one constant with that name in this interface.
-     * 406 is specific to an endpoint, while 606 is global and
-     * indicates that the callee will not find the request acceptable
-     * on any endpoint.
-     */
-    public static final int SC_NOT_ACCEPTABLE_ANYWHERE = 606;
-
-}
diff --git a/httpcore-contrib/src/main/java/org/apache/http/contrib/sip/SipVersion.java b/httpcore-contrib/src/main/java/org/apache/http/contrib/sip/SipVersion.java
deleted file mode 100644
index 743300e..0000000
--- a/httpcore-contrib/src/main/java/org/apache/http/contrib/sip/SipVersion.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * ====================================================================
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- *
- */
-
-package org.apache.http.contrib.sip;
-
-import java.io.Serializable;
-
-import org.apache.http.ProtocolVersion;
-
-
-/**
- * Represents an SIP version, as specified in RFC 3261.
- *
- *
- */
-public final class SipVersion extends ProtocolVersion
-    implements Serializable {
-
-    private static final long serialVersionUID = 6112302080954348220L;
-
-    /** The protocol name. */
-    public static final String SIP = "SIP";
-
-    /** SIP protocol version 2.0 */
-    public static final SipVersion SIP_2_0 = new SipVersion(2, 0);
-
-
-    /**
-     * Create a SIP protocol version designator.
-     *
-     * @param major   the major version number of the SIP protocol
-     * @param minor   the minor version number of the SIP protocol
-     *
-     * @throws IllegalArgumentException
-     *         if either major or minor version number is negative
-     */
-    public SipVersion(int major, int minor) {
-        super(SIP, major, minor);
-    }
-
-
-    /**
-     * Obtains a specific SIP version.
-     *
-     * @param major     the major version
-     * @param minor     the minor version
-     *
-     * @return  an instance of {@link SipVersion} with the argument version
-     */
-    @Override
-    public ProtocolVersion forVersion(int major, int minor) {
-
-        if ((major == this.major) && (minor == this.minor)) {
-            return this;
-        }
-
-        if ((major == 2) && (minor == 0)) {
-            return SIP_2_0;
-        }
-
-        // argument checking is done in the constructor
-        return new SipVersion(major, minor);
-    }
-
-}
diff --git a/httpcore-nio/pom.xml b/httpcore-nio/pom.xml
index 71d3276..572e82a 100644
--- a/httpcore-nio/pom.xml
+++ b/httpcore-nio/pom.xml
@@ -30,10 +30,10 @@
   <parent>
     <groupId>org.apache.httpcomponents</groupId>
     <artifactId>httpcomponents-core</artifactId>
-    <version>4.2.4</version>
+    <version>4.3</version>
   </parent>
   <artifactId>httpcore-nio</artifactId>
-  <name>HttpCore NIO</name>
+  <name>Apache HttpCore NIO</name>
   <inceptionYear>2005</inceptionYear>
   <description>
    HttpComponents Core (non-blocking I/O)
@@ -65,15 +65,6 @@
     </dependency>
   </dependencies>
 
-  <properties>
-    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
-    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
-    <maven.compile.source>1.5</maven.compile.source>
-    <maven.compile.target>1.5</maven.compile.target>
-    <maven.compile.optimize>true</maven.compile.optimize>
-    <maven.compile.deprecation>true</maven.compile.deprecation>
-  </properties>
-
   <build>
     <resources>
       <resource>
@@ -86,33 +77,21 @@
     </resources>
     <plugins>
       <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-compiler-plugin</artifactId>
-        <configuration>
-          <source>${maven.compile.source}</source>
-          <target>${maven.compile.target}</target>
-          <optimize>${maven.compile.optimize}</optimize>
-          <showDeprecations>${maven.compile.deprecation}</showDeprecations>
-        </configuration>
-      </plugin>
-      <plugin>
-        <artifactId>maven-surefire-plugin</artifactId>
-      </plugin>
-      <plugin>
-        <groupId>com.atlassian.maven.plugins</groupId>
-        <artifactId>maven-clover2-plugin</artifactId>
-        <configuration>
-          <flushPolicy>threaded</flushPolicy>
-          <flushInterval>100</flushInterval>
-          <targetPercentage>50%</targetPercentage>
-        </configuration>
+        <groupId>org.codehaus.mojo</groupId>
+        <artifactId>build-helper-maven-plugin</artifactId>
+        <version>1.8</version>
         <executions>
           <execution>
-            <id>site</id>
-            <phase>pre-site</phase>
+            <id>add-source</id>
+            <phase>generate-sources</phase>
             <goals>
-              <goal>instrument</goal>
+              <goal>add-source</goal>
             </goals>
+            <configuration>
+              <sources>
+                <source>src/main/java-deprecated</source>
+              </sources>
+            </configuration>
           </execution>
         </executions>
       </plugin>
@@ -128,7 +107,7 @@
         <configuration>
           <!-- reduce console output. Can override with -Dquiet=false -->
           <quiet>true</quiet>
-          <source>1.5</source>
+          <source>${maven.compiler.source}</source>
           <links>
             <link>http://download.oracle.com/javase/1.5.0/docs/api/</link>
             <link>http://hc.apache.org/httpcomponents-core-ga/httpcore/apidocs/</link>
@@ -144,15 +123,6 @@
       </plugin>
 
       <plugin>
-        <groupId>com.atlassian.maven.plugins</groupId>
-        <artifactId>maven-clover2-plugin</artifactId>
-        <version>${clover.version}</version>
-        <configuration>
-          <jdk>1.5</jdk>
-        </configuration>
-      </plugin>
-
-      <plugin>
         <artifactId>maven-jxr-plugin</artifactId>
         <version>${hc.jxr.version}</version>
       </plugin>
diff --git a/httpcore-nio/src/examples/org/apache/http/examples/nio/NHttpClient.java b/httpcore-nio/src/examples/org/apache/http/examples/nio/NHttpClient.java
index d626fa9..ea5cf74 100644
--- a/httpcore-nio/src/examples/org/apache/http/examples/nio/NHttpClient.java
+++ b/httpcore-nio/src/examples/org/apache/http/examples/nio/NHttpClient.java
@@ -31,10 +31,9 @@ import java.io.InterruptedIOException;
 import java.util.concurrent.CountDownLatch;
 
 import org.apache.http.HttpHost;
-import org.apache.http.HttpRequestInterceptor;
 import org.apache.http.HttpResponse;
 import org.apache.http.concurrent.FutureCallback;
-import org.apache.http.impl.DefaultConnectionReuseStrategy;
+import org.apache.http.config.ConnectionConfig;
 import org.apache.http.impl.nio.DefaultHttpClientIODispatch;
 import org.apache.http.impl.nio.pool.BasicNIOConnPool;
 import org.apache.http.impl.nio.reactor.DefaultConnectingIOReactor;
@@ -45,13 +44,9 @@ import org.apache.http.nio.protocol.HttpAsyncRequestExecutor;
 import org.apache.http.nio.protocol.HttpAsyncRequester;
 import org.apache.http.nio.reactor.ConnectingIOReactor;
 import org.apache.http.nio.reactor.IOEventDispatch;
-import org.apache.http.params.CoreConnectionPNames;
-import org.apache.http.params.CoreProtocolPNames;
-import org.apache.http.params.HttpParams;
-import org.apache.http.params.SyncBasicHttpParams;
-import org.apache.http.protocol.BasicHttpContext;
+import org.apache.http.protocol.HttpCoreContext;
 import org.apache.http.protocol.HttpProcessor;
-import org.apache.http.protocol.ImmutableHttpProcessor;
+import org.apache.http.protocol.HttpProcessorBuilder;
 import org.apache.http.protocol.RequestConnControl;
 import org.apache.http.protocol.RequestContent;
 import org.apache.http.protocol.RequestExpectContinue;
@@ -59,34 +54,28 @@ import org.apache.http.protocol.RequestTargetHost;
 import org.apache.http.protocol.RequestUserAgent;
 
 /**
- * Asynchronous HTTP/1.1 client.
+ * Minimal asynchronous HTTP/1.1 client.
  */
 public class NHttpClient {
 
     public static void main(String[] args) throws Exception {
-        // HTTP parameters for the client
-        HttpParams params = new SyncBasicHttpParams();
-        params
-            .setIntParameter(CoreConnectionPNames.SO_TIMEOUT, 3000)
-            .setIntParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 3000)
-            .setIntParameter(CoreConnectionPNames.SOCKET_BUFFER_SIZE, 8 * 1024)
-            .setParameter(CoreProtocolPNames.USER_AGENT, "Test/1.1");
         // Create HTTP protocol processing chain
-        HttpProcessor httpproc = new ImmutableHttpProcessor(new HttpRequestInterceptor[] {
+        HttpProcessor httpproc = HttpProcessorBuilder.create()
                 // Use standard client-side protocol interceptors
-                new RequestContent(),
-                new RequestTargetHost(),
-                new RequestConnControl(),
-                new RequestUserAgent(),
-                new RequestExpectContinue()});
+                .add(new RequestContent())
+                .add(new RequestTargetHost())
+                .add(new RequestConnControl())
+                .add(new RequestUserAgent("Test/1.1"))
+                .add(new RequestExpectContinue(true)).build();
         // Create client-side HTTP protocol handler
         HttpAsyncRequestExecutor protocolHandler = new HttpAsyncRequestExecutor();
         // Create client-side I/O event dispatch
-        final IOEventDispatch ioEventDispatch = new DefaultHttpClientIODispatch(protocolHandler, params);
+        final IOEventDispatch ioEventDispatch = new DefaultHttpClientIODispatch(protocolHandler,
+                ConnectionConfig.DEFAULT);
         // Create client-side I/O reactor
         final ConnectingIOReactor ioReactor = new DefaultConnectingIOReactor();
         // Create HTTP connection pool
-        BasicNIOConnPool pool = new BasicNIOConnPool(ioReactor, params);
+        BasicNIOConnPool pool = new BasicNIOConnPool(ioReactor, ConnectionConfig.DEFAULT);
         // Limit total number of connections to just two
         pool.setDefaultMaxPerRoute(2);
         pool.setMaxTotal(2);
@@ -109,8 +98,7 @@ public class NHttpClient {
         // Start the client thread
         t.start();
         // Create HTTP requester
-        HttpAsyncRequester requester = new HttpAsyncRequester(
-                httpproc, new DefaultConnectionReuseStrategy(), params);
+        HttpAsyncRequester requester = new HttpAsyncRequester(httpproc);
         // Execute HTTP GETs to the following hosts and
         HttpHost[] targets = new HttpHost[] {
                 new HttpHost("www.apache.org", 80, "http"),
@@ -120,11 +108,12 @@ public class NHttpClient {
         final CountDownLatch latch = new CountDownLatch(targets.length);
         for (final HttpHost target: targets) {
             BasicHttpRequest request = new BasicHttpRequest("GET", "/");
+            HttpCoreContext coreContext = HttpCoreContext.create();
             requester.execute(
                     new BasicAsyncRequestProducer(target, request),
                     new BasicAsyncResponseConsumer(),
                     pool,
-                    new BasicHttpContext(),
+                    coreContext,
                     // Handle HTTP response from a callback
                     new FutureCallback<HttpResponse>() {
 
diff --git a/httpcore-nio/src/examples/org/apache/http/examples/nio/NHttpReverseProxy.java b/httpcore-nio/src/examples/org/apache/http/examples/nio/NHttpReverseProxy.java
index 01d3b2c..6d9f292 100644
--- a/httpcore-nio/src/examples/org/apache/http/examples/nio/NHttpReverseProxy.java
+++ b/httpcore-nio/src/examples/org/apache/http/examples/nio/NHttpReverseProxy.java
@@ -44,6 +44,7 @@ import org.apache.http.HttpResponse;
 import org.apache.http.HttpResponseInterceptor;
 import org.apache.http.HttpStatus;
 import org.apache.http.HttpVersion;
+import org.apache.http.config.ConnectionConfig;
 import org.apache.http.entity.ContentType;
 import org.apache.http.impl.DefaultConnectionReuseStrategy;
 import org.apache.http.impl.EnglishReasonPhraseCatalog;
@@ -66,27 +67,23 @@ import org.apache.http.nio.NHttpServerConnection;
 import org.apache.http.nio.entity.NStringEntity;
 import org.apache.http.nio.pool.NIOConnFactory;
 import org.apache.http.nio.protocol.BasicAsyncResponseProducer;
-import org.apache.http.nio.protocol.HttpAsyncRequestExecutor;
+import org.apache.http.nio.protocol.HttpAsyncExchange;
 import org.apache.http.nio.protocol.HttpAsyncRequestConsumer;
-import org.apache.http.nio.protocol.HttpAsyncRequester;
+import org.apache.http.nio.protocol.HttpAsyncRequestExecutor;
 import org.apache.http.nio.protocol.HttpAsyncRequestHandler;
-import org.apache.http.nio.protocol.HttpAsyncRequestHandlerRegistry;
-import org.apache.http.nio.protocol.HttpAsyncRequestHandlerResolver;
+import org.apache.http.nio.protocol.HttpAsyncRequestHandlerMapper;
 import org.apache.http.nio.protocol.HttpAsyncRequestProducer;
+import org.apache.http.nio.protocol.HttpAsyncRequester;
 import org.apache.http.nio.protocol.HttpAsyncResponseConsumer;
 import org.apache.http.nio.protocol.HttpAsyncResponseProducer;
-import org.apache.http.nio.protocol.HttpAsyncExchange;
 import org.apache.http.nio.protocol.HttpAsyncService;
+import org.apache.http.nio.protocol.UriHttpAsyncRequestHandlerMapper;
 import org.apache.http.nio.reactor.ConnectingIOReactor;
 import org.apache.http.nio.reactor.IOEventDispatch;
 import org.apache.http.nio.reactor.ListeningIOReactor;
-import org.apache.http.params.CoreConnectionPNames;
-import org.apache.http.params.CoreProtocolPNames;
-import org.apache.http.params.HttpParams;
-import org.apache.http.params.SyncBasicHttpParams;
 import org.apache.http.pool.PoolStats;
-import org.apache.http.protocol.ExecutionContext;
 import org.apache.http.protocol.HttpContext;
+import org.apache.http.protocol.HttpCoreContext;
 import org.apache.http.protocol.HttpProcessor;
 import org.apache.http.protocol.ImmutableHttpProcessor;
 import org.apache.http.protocol.RequestConnControl;
@@ -123,15 +120,11 @@ public class NHttpReverseProxy {
 
         System.out.println("Reverse proxy to " + targetHost);
 
-        HttpParams params = new SyncBasicHttpParams();
-        params
-            .setIntParameter(CoreConnectionPNames.SO_TIMEOUT, 30000)
-            .setIntParameter(CoreConnectionPNames.SOCKET_BUFFER_SIZE, 8 * 1024)
-            .setParameter(CoreProtocolPNames.ORIGIN_SERVER, "Test/1.1")
-            .setParameter(CoreProtocolPNames.USER_AGENT, "Test/1.1");
-
-        IOReactorConfig config = new IOReactorConfig();
-        config.setIoThreadCount(1);
+        IOReactorConfig config = IOReactorConfig.custom()
+            .setIoThreadCount(1)
+            .setSoTimeout(3000)
+            .setConnectTimeout(3000)
+            .build();
         final ConnectingIOReactor connectingIOReactor = new DefaultConnectingIOReactor(config);
         final ListeningIOReactor listeningIOReactor = new DefaultListeningIOReactor(config);
 
@@ -139,7 +132,7 @@ public class NHttpReverseProxy {
         HttpProcessor inhttpproc = new ImmutableHttpProcessor(
                 new HttpResponseInterceptor[] {
                         new ResponseDate(),
-                        new ResponseServer(),
+                        new ResponseServer("Test/1.1"),
                         new ResponseContent(),
                         new ResponseConnControl()
          });
@@ -150,29 +143,31 @@ public class NHttpReverseProxy {
                         new RequestContent(),
                         new RequestTargetHost(),
                         new RequestConnControl(),
-                        new RequestUserAgent(),
-                        new RequestExpectContinue()
+                        new RequestUserAgent("Test/1.1"),
+                        new RequestExpectContinue(true)
         });
 
         ProxyClientProtocolHandler clientHandler = new ProxyClientProtocolHandler();
         HttpAsyncRequester executor = new HttpAsyncRequester(
-                outhttpproc, new ProxyOutgoingConnectionReuseStrategy(), params);
+                outhttpproc, new ProxyOutgoingConnectionReuseStrategy());
 
-        ProxyConnPool connPool = new ProxyConnPool(connectingIOReactor, params);
+        ProxyConnPool connPool = new ProxyConnPool(connectingIOReactor, ConnectionConfig.DEFAULT);
         connPool.setMaxTotal(100);
         connPool.setDefaultMaxPerRoute(20);
 
-        HttpAsyncRequestHandlerRegistry handlerRegistry = new HttpAsyncRequestHandlerRegistry();
+        UriHttpAsyncRequestHandlerMapper handlerRegistry = new UriHttpAsyncRequestHandlerMapper();
         handlerRegistry.register("*", new ProxyRequestHandler(targetHost, executor, connPool));
 
         ProxyServiceHandler serviceHandler = new ProxyServiceHandler(
-                inhttpproc, new ProxyIncomingConnectionReuseStrategy(), handlerRegistry, params);
+                inhttpproc,
+                new ProxyIncomingConnectionReuseStrategy(),
+                handlerRegistry);
 
         final IOEventDispatch connectingEventDispatch = new DefaultHttpClientIODispatch(
-                clientHandler, params);
+                clientHandler, ConnectionConfig.DEFAULT);
 
         final IOEventDispatch listeningEventDispatch = new DefaultHttpServerIODispatch(
-                serviceHandler, params);
+                serviceHandler, ConnectionConfig.DEFAULT);
 
         Thread t = new Thread(new Runnable() {
 
@@ -767,7 +762,7 @@ public class NHttpReverseProxy {
         @Override
         public boolean keepAlive(final HttpResponse response, final HttpContext context) {
             NHttpConnection conn = (NHttpConnection) context.getAttribute(
-                    ExecutionContext.HTTP_CONNECTION);
+                    HttpCoreContext.HTTP_CONNECTION);
             boolean keepAlive = super.keepAlive(response, context);
             if (keepAlive) {
                 System.out.println("[client->proxy] connection kept alive " + conn);
@@ -782,7 +777,7 @@ public class NHttpReverseProxy {
         @Override
         public boolean keepAlive(final HttpResponse response, final HttpContext context) {
             NHttpConnection conn = (NHttpConnection) context.getAttribute(
-                    ExecutionContext.HTTP_CONNECTION);
+                    HttpCoreContext.HTTP_CONNECTION);
             boolean keepAlive = super.keepAlive(response, context);
             if (keepAlive) {
                 System.out.println("[proxy->origin] connection kept alive " + conn);
@@ -797,9 +792,8 @@ public class NHttpReverseProxy {
         public ProxyServiceHandler(
                 final HttpProcessor httpProcessor,
                 final ConnectionReuseStrategy reuseStrategy,
-                final HttpAsyncRequestHandlerResolver handlerResolver,
-                final HttpParams params) {
-            super(httpProcessor, reuseStrategy, handlerResolver, params);
+                final HttpAsyncRequestHandlerMapper handlerResolver) {
+            super(httpProcessor, reuseStrategy, null, handlerResolver, null);
         }
 
         @Override
@@ -849,15 +843,17 @@ public class NHttpReverseProxy {
 
     static class ProxyConnPool extends BasicNIOConnPool {
 
-        public ProxyConnPool(final ConnectingIOReactor ioreactor, final HttpParams params) {
-            super(ioreactor, params);
+        public ProxyConnPool(
+                final ConnectingIOReactor ioreactor,
+                final ConnectionConfig config) {
+            super(ioreactor, config);
         }
 
         public ProxyConnPool(
                 final ConnectingIOReactor ioreactor,
                 final NIOConnFactory<HttpHost, NHttpClientConnection> connFactory,
-                final HttpParams params) {
-            super(ioreactor, connFactory, params);
+                final int connectTimeout) {
+            super(ioreactor, connFactory, connectTimeout);
         }
 
         @Override
diff --git a/httpcore-nio/src/examples/org/apache/http/examples/nio/NHttpServer.java b/httpcore-nio/src/examples/org/apache/http/examples/nio/NHttpServer.java
index e4047fa..85978e2 100644
--- a/httpcore-nio/src/examples/org/apache/http/examples/nio/NHttpServer.java
+++ b/httpcore-nio/src/examples/org/apache/http/examples/nio/NHttpServer.java
@@ -42,16 +42,16 @@ import javax.net.ssl.SSLContext;
 import org.apache.http.HttpException;
 import org.apache.http.HttpRequest;
 import org.apache.http.HttpResponse;
-import org.apache.http.HttpResponseInterceptor;
 import org.apache.http.HttpStatus;
 import org.apache.http.MethodNotSupportedException;
+import org.apache.http.config.ConnectionConfig;
 import org.apache.http.entity.ContentType;
-import org.apache.http.impl.DefaultConnectionReuseStrategy;
+import org.apache.http.impl.nio.DefaultHttpServerIODispatch;
 import org.apache.http.impl.nio.DefaultNHttpServerConnection;
 import org.apache.http.impl.nio.DefaultNHttpServerConnectionFactory;
-import org.apache.http.impl.nio.DefaultHttpServerIODispatch;
 import org.apache.http.impl.nio.SSLNHttpServerConnectionFactory;
 import org.apache.http.impl.nio.reactor.DefaultListeningIOReactor;
+import org.apache.http.impl.nio.reactor.IOReactorConfig;
 import org.apache.http.nio.NHttpConnection;
 import org.apache.http.nio.NHttpConnectionFactory;
 import org.apache.http.nio.NHttpServerConnection;
@@ -59,21 +59,17 @@ import org.apache.http.nio.entity.NFileEntity;
 import org.apache.http.nio.entity.NStringEntity;
 import org.apache.http.nio.protocol.BasicAsyncRequestConsumer;
 import org.apache.http.nio.protocol.BasicAsyncResponseProducer;
+import org.apache.http.nio.protocol.HttpAsyncExchange;
 import org.apache.http.nio.protocol.HttpAsyncRequestConsumer;
 import org.apache.http.nio.protocol.HttpAsyncRequestHandler;
-import org.apache.http.nio.protocol.HttpAsyncRequestHandlerRegistry;
-import org.apache.http.nio.protocol.HttpAsyncExchange;
 import org.apache.http.nio.protocol.HttpAsyncService;
+import org.apache.http.nio.protocol.UriHttpAsyncRequestHandlerMapper;
 import org.apache.http.nio.reactor.IOEventDispatch;
 import org.apache.http.nio.reactor.ListeningIOReactor;
-import org.apache.http.params.CoreConnectionPNames;
-import org.apache.http.params.CoreProtocolPNames;
-import org.apache.http.params.HttpParams;
-import org.apache.http.params.SyncBasicHttpParams;
-import org.apache.http.protocol.ExecutionContext;
 import org.apache.http.protocol.HttpContext;
+import org.apache.http.protocol.HttpCoreContext;
 import org.apache.http.protocol.HttpProcessor;
-import org.apache.http.protocol.ImmutableHttpProcessor;
+import org.apache.http.protocol.HttpProcessorBuilder;
 import org.apache.http.protocol.ResponseConnControl;
 import org.apache.http.protocol.ResponseContent;
 import org.apache.http.protocol.ResponseDate;
@@ -96,27 +92,19 @@ public class NHttpServer {
         if (args.length >= 2) {
             port = Integer.parseInt(args[1]);
         }
-        // HTTP parameters for the server
-        HttpParams params = new SyncBasicHttpParams();
-        params
-            .setIntParameter(CoreConnectionPNames.SO_TIMEOUT, 5000)
-            .setIntParameter(CoreConnectionPNames.SOCKET_BUFFER_SIZE, 8 * 1024)
-            .setParameter(CoreProtocolPNames.ORIGIN_SERVER, "HttpTest/1.1");
+
         // Create HTTP protocol processing chain
-        HttpProcessor httpproc = new ImmutableHttpProcessor(new HttpResponseInterceptor[] {
-                // Use standard server-side protocol interceptors
-                new ResponseDate(),
-                new ResponseServer(),
-                new ResponseContent(),
-                new ResponseConnControl()
-        });
+        HttpProcessor httpproc = HttpProcessorBuilder.create()
+                .add(new ResponseDate())
+                .add(new ResponseServer("Test/1.1"))
+                .add(new ResponseContent())
+                .add(new ResponseConnControl()).build();
         // Create request handler registry
-        HttpAsyncRequestHandlerRegistry reqistry = new HttpAsyncRequestHandlerRegistry();
+        UriHttpAsyncRequestHandlerMapper reqistry = new UriHttpAsyncRequestHandlerMapper();
         // Register the default handler for all URIs
         reqistry.register("*", new HttpFileHandler(docRoot));
         // Create server-side HTTP protocol handler
-        HttpAsyncService protocolHandler = new HttpAsyncService(
-                httpproc, new DefaultConnectionReuseStrategy(), reqistry, params) {
+        HttpAsyncService protocolHandler = new HttpAsyncService(httpproc, reqistry) {
 
             @Override
             public void connected(final NHttpServerConnection conn) {
@@ -149,14 +137,22 @@ public class NHttpServer {
             KeyManager[] keymanagers = kmfactory.getKeyManagers();
             SSLContext sslcontext = SSLContext.getInstance("TLS");
             sslcontext.init(keymanagers, null, null);
-            connFactory = new SSLNHttpServerConnectionFactory(sslcontext, null, params);
+            connFactory = new SSLNHttpServerConnectionFactory(sslcontext,
+                    null, ConnectionConfig.DEFAULT);
         } else {
-            connFactory = new DefaultNHttpServerConnectionFactory(params);
+            connFactory = new DefaultNHttpServerConnectionFactory(
+                    ConnectionConfig.DEFAULT);
         }
         // Create server-side I/O event dispatch
         IOEventDispatch ioEventDispatch = new DefaultHttpServerIODispatch(protocolHandler, connFactory);
+        // Set I/O reactor defaults
+        IOReactorConfig config = IOReactorConfig.custom()
+            .setIoThreadCount(1)
+            .setSoTimeout(3000)
+            .setConnectTimeout(3000)
+            .build();
         // Create server-side I/O reactor
-        ListeningIOReactor ioReactor = new DefaultListeningIOReactor();
+        ListeningIOReactor ioReactor = new DefaultListeningIOReactor(config);
         try {
             // Listen of the given port
             ioReactor.listen(new InetSocketAddress(port));
@@ -200,6 +196,8 @@ public class NHttpServer {
                 final HttpResponse response,
                 final HttpContext context) throws HttpException, IOException {
 
+            HttpCoreContext coreContext = HttpCoreContext.adapt(context);
+
             String method = request.getRequestLine().getMethod().toUpperCase(Locale.ENGLISH);
             if (!method.equals("GET") && !method.equals("HEAD") && !method.equals("POST")) {
                 throw new MethodNotSupportedException(method + " method not supported");
@@ -227,8 +225,7 @@ public class NHttpServer {
                 System.out.println("Cannot read file " + file.getPath());
 
             } else {
-                NHttpConnection conn = (NHttpConnection) context.getAttribute(
-                        ExecutionContext.HTTP_CONNECTION);
+                NHttpConnection conn = coreContext.getConnection(NHttpConnection.class);
                 response.setStatusCode(HttpStatus.SC_OK);
                 NFileEntity body = new NFileEntity(file, ContentType.create("text/html"));
                 response.setEntity(body);
diff --git a/httpcore-nio/src/main/java/org/apache/http/impl/nio/DefaultClientIOEventDispatch.java b/httpcore-nio/src/main/java-deprecated/org/apache/http/impl/nio/DefaultClientIOEventDispatch.java
similarity index 78%
rename from httpcore-nio/src/main/java/org/apache/http/impl/nio/DefaultClientIOEventDispatch.java
rename to httpcore-nio/src/main/java-deprecated/org/apache/http/impl/nio/DefaultClientIOEventDispatch.java
index 12c35d9..705a2b0 100644
--- a/httpcore-nio/src/main/java/org/apache/http/impl/nio/DefaultClientIOEventDispatch.java
+++ b/httpcore-nio/src/main/java-deprecated/org/apache/http/impl/nio/DefaultClientIOEventDispatch.java
@@ -29,33 +29,22 @@ package org.apache.http.impl.nio;
 
 import java.io.IOException;
 
-import org.apache.http.HttpResponse;
 import org.apache.http.HttpResponseFactory;
 import org.apache.http.annotation.Immutable;
 import org.apache.http.impl.DefaultHttpResponseFactory;
 import org.apache.http.impl.nio.reactor.AbstractIODispatch;
-import org.apache.http.nio.NHttpClientIOTarget;
 import org.apache.http.nio.NHttpClientHandler;
-import org.apache.http.nio.reactor.IOEventDispatch;
+import org.apache.http.nio.NHttpClientIOTarget;
 import org.apache.http.nio.reactor.IOSession;
 import org.apache.http.nio.util.ByteBufferAllocator;
 import org.apache.http.nio.util.HeapByteBufferAllocator;
 import org.apache.http.params.HttpConnectionParams;
 import org.apache.http.params.HttpParams;
+import org.apache.http.util.Args;
 
 /**
- * Default implementation of {@link IOEventDispatch} interface for plain
- * (unencrypted) client-side HTTP connections.
- * <p>
- * The following parameters can be used to customize the behavior of this
- * class:
- * <ul>
- *  <li>{@link org.apache.http.params.CoreProtocolPNames#HTTP_ELEMENT_CHARSET}</li>
- *  <li>{@link org.apache.http.params.CoreConnectionPNames#SO_TIMEOUT}</li>
- *  <li>{@link org.apache.http.params.CoreConnectionPNames#SOCKET_BUFFER_SIZE}</li>
- *  <li>{@link org.apache.http.params.CoreConnectionPNames#MAX_HEADER_COUNT}</li>
- *  <li>{@link org.apache.http.params.CoreConnectionPNames#MAX_LINE_LENGTH}</li>
- * </ul>
+ * Default implementation of {@link org.apache.http.nio.reactor.IOEventDispatch}
+ * interface for plain (unencrypted) client-side HTTP connections.
  *
  * @since 4.0
  *
@@ -80,12 +69,8 @@ public class DefaultClientIOEventDispatch extends AbstractIODispatch<NHttpClient
             final NHttpClientHandler handler,
             final HttpParams params) {
         super();
-        if (handler == null) {
-            throw new IllegalArgumentException("HTTP client handler may not be null");
-        }
-        if (params == null) {
-            throw new IllegalArgumentException("HTTP parameters may not be null");
-        }
+        Args.notNull(handler, "HTTP client handler");
+        Args.notNull(params, "HTTP parameters");
         this.allocator = createByteBufferAllocator();
         this.handler = handler;
         this.params = params;
@@ -101,12 +86,13 @@ public class DefaultClientIOEventDispatch extends AbstractIODispatch<NHttpClient
      * @return byte buffer allocator.
      */
     protected ByteBufferAllocator createByteBufferAllocator() {
-        return new HeapByteBufferAllocator();
+        return HeapByteBufferAllocator.INSTANCE;
     }
 
     /**
      * Creates an instance of {@link DefaultHttpResponseFactory} to be used
-     * by HTTP connections for creating {@link HttpResponse} objects.
+     * by HTTP connections for creating {@link org.apache.http.HttpResponse}
+     * objects.
      * <p>
      * This method can be overridden in a super class in order to provide
      * a different implementation of the {@link HttpResponseFactory} interface.
@@ -114,7 +100,7 @@ public class DefaultClientIOEventDispatch extends AbstractIODispatch<NHttpClient
      * @return HTTP response factory.
      */
     protected HttpResponseFactory createHttpResponseFactory() {
-        return new DefaultHttpResponseFactory();
+        return DefaultHttpResponseFactory.INSTANCE;
     }
 
     /**
@@ -139,10 +125,10 @@ public class DefaultClientIOEventDispatch extends AbstractIODispatch<NHttpClient
 
     @Override
     protected void onConnected(final NHttpClientIOTarget conn) {
-        int timeout = HttpConnectionParams.getSoTimeout(this.params);
+        final int timeout = HttpConnectionParams.getSoTimeout(this.params);
         conn.setSocketTimeout(timeout);
 
-        Object attachment = conn.getContext().getAttribute(IOSession.ATTACHMENT_KEY);
+        final Object attachment = conn.getContext().getAttribute(IOSession.ATTACHMENT_KEY);
         this.handler.connected(conn, attachment);
     }
 
@@ -152,7 +138,7 @@ public class DefaultClientIOEventDispatch extends AbstractIODispatch<NHttpClient
     }
 
     @Override
-    protected void onException(final NHttpClientIOTarget conn, IOException ex) {
+    protected void onException(final NHttpClientIOTarget conn, final IOException ex) {
         this.handler.exception(conn, ex);
     }
 
diff --git a/httpcore-nio/src/main/java/org/apache/http/impl/nio/DefaultServerIOEventDispatch.java b/httpcore-nio/src/main/java-deprecated/org/apache/http/impl/nio/DefaultServerIOEventDispatch.java
similarity index 79%
rename from httpcore-nio/src/main/java/org/apache/http/impl/nio/DefaultServerIOEventDispatch.java
rename to httpcore-nio/src/main/java-deprecated/org/apache/http/impl/nio/DefaultServerIOEventDispatch.java
index d2735c3..885c8b8 100644
--- a/httpcore-nio/src/main/java/org/apache/http/impl/nio/DefaultServerIOEventDispatch.java
+++ b/httpcore-nio/src/main/java-deprecated/org/apache/http/impl/nio/DefaultServerIOEventDispatch.java
@@ -29,33 +29,22 @@ package org.apache.http.impl.nio;
 
 import java.io.IOException;
 
-import org.apache.http.HttpRequest;
 import org.apache.http.HttpRequestFactory;
 import org.apache.http.annotation.Immutable;
 import org.apache.http.impl.DefaultHttpRequestFactory;
 import org.apache.http.impl.nio.reactor.AbstractIODispatch;
 import org.apache.http.nio.NHttpServerIOTarget;
 import org.apache.http.nio.NHttpServiceHandler;
-import org.apache.http.nio.reactor.IOEventDispatch;
 import org.apache.http.nio.reactor.IOSession;
 import org.apache.http.nio.util.ByteBufferAllocator;
 import org.apache.http.nio.util.HeapByteBufferAllocator;
 import org.apache.http.params.HttpConnectionParams;
 import org.apache.http.params.HttpParams;
+import org.apache.http.util.Args;
 
 /**
- * Default implementation of {@link IOEventDispatch} interface for plain
- * (unencrypted) server-side HTTP connections.
- * <p>
- * The following parameters can be used to customize the behavior of this
- * class:
- * <ul>
- *  <li>{@link org.apache.http.params.CoreProtocolPNames#HTTP_ELEMENT_CHARSET}</li>
- *  <li>{@link org.apache.http.params.CoreConnectionPNames#SO_TIMEOUT}</li>
- *  <li>{@link org.apache.http.params.CoreConnectionPNames#SOCKET_BUFFER_SIZE}</li>
- *  <li>{@link org.apache.http.params.CoreConnectionPNames#MAX_HEADER_COUNT}</li>
- *  <li>{@link org.apache.http.params.CoreConnectionPNames#MAX_LINE_LENGTH}</li>
- * </ul>
+ * Default implementation of {@link org.apache.http.nio.reactor.IOEventDispatch}
+ * interface for plain (unencrypted) server-side HTTP connections.
  *
  * @since 4.0
  *
@@ -80,12 +69,8 @@ public class DefaultServerIOEventDispatch extends AbstractIODispatch<NHttpServer
             final NHttpServiceHandler handler,
             final HttpParams params) {
         super();
-        if (handler == null) {
-            throw new IllegalArgumentException("HTTP service handler may not be null");
-        }
-        if (params == null) {
-            throw new IllegalArgumentException("HTTP parameters may not be null");
-        }
+        Args.notNull(handler, "HTTP service handler");
+        Args.notNull(params, "HTTP parameters");
         this.allocator = createByteBufferAllocator();
         this.handler = handler;
         this.params = params;
@@ -101,12 +86,13 @@ public class DefaultServerIOEventDispatch extends AbstractIODispatch<NHttpServer
     * @return byte buffer allocator.
     */
     protected ByteBufferAllocator createByteBufferAllocator() {
-        return new HeapByteBufferAllocator();
+        return HeapByteBufferAllocator.INSTANCE;
     }
 
     /**
      * Creates an instance of {@link DefaultHttpRequestFactory} to be used
-     * by HTTP connections for creating {@link HttpRequest} objects.
+     * by HTTP connections for creating {@link org.apache.http.HttpRequest}
+     * objects.
      * <p>
      * This method can be overridden in a super class in order to provide
      * a different implementation of the {@link HttpRequestFactory} interface.
@@ -114,7 +100,7 @@ public class DefaultServerIOEventDispatch extends AbstractIODispatch<NHttpServer
      * @return HTTP request factory.
      */
     protected HttpRequestFactory createHttpRequestFactory() {
-        return new DefaultHttpRequestFactory();
+        return DefaultHttpRequestFactory.INSTANCE;
     }
 
     /**
@@ -139,7 +125,7 @@ public class DefaultServerIOEventDispatch extends AbstractIODispatch<NHttpServer
 
     @Override
     protected void onConnected(final NHttpServerIOTarget conn) {
-        int timeout = HttpConnectionParams.getSoTimeout(this.params);
+        final int timeout = HttpConnectionParams.getSoTimeout(this.params);
         conn.setSocketTimeout(timeout);
         this.handler.connected(conn);
     }
@@ -150,7 +136,7 @@ public class DefaultServerIOEventDispatch extends AbstractIODispatch<NHttpServer
     }
 
     @Override
-    protected void onException(final NHttpServerIOTarget conn, IOException ex) {
+    protected void onException(final NHttpServerIOTarget conn, final IOException ex) {
         this.handler.exception(conn, ex);
     }
 
diff --git a/httpcore-nio/src/main/java/org/apache/http/impl/nio/SSLClientIOEventDispatch.java b/httpcore-nio/src/main/java-deprecated/org/apache/http/impl/nio/SSLClientIOEventDispatch.java
similarity index 84%
rename from httpcore-nio/src/main/java/org/apache/http/impl/nio/SSLClientIOEventDispatch.java
rename to httpcore-nio/src/main/java-deprecated/org/apache/http/impl/nio/SSLClientIOEventDispatch.java
index 762a8e1..8114053 100644
--- a/httpcore-nio/src/main/java/org/apache/http/impl/nio/SSLClientIOEventDispatch.java
+++ b/httpcore-nio/src/main/java-deprecated/org/apache/http/impl/nio/SSLClientIOEventDispatch.java
@@ -32,7 +32,6 @@ import java.io.IOException;
 import javax.net.ssl.SSLContext;
 import javax.net.ssl.SSLException;
 
-import org.apache.http.HttpResponse;
 import org.apache.http.HttpResponseFactory;
 import org.apache.http.impl.DefaultHttpResponseFactory;
 import org.apache.http.impl.nio.reactor.SSLIOSession;
@@ -46,19 +45,11 @@ import org.apache.http.nio.util.ByteBufferAllocator;
 import org.apache.http.nio.util.HeapByteBufferAllocator;
 import org.apache.http.params.HttpParams;
 import org.apache.http.protocol.ExecutionContext;
+import org.apache.http.util.Args;
 
 /**
  * Default implementation of {@link IOEventDispatch} interface for SSL
  * (encrypted) client-side HTTP connections.
- * <p>
- * The following parameters can be used to customize the behavior of this
- * class:
- * <ul>
- *  <li>{@link org.apache.http.params.CoreProtocolPNames#HTTP_ELEMENT_CHARSET}</li>
- *  <li>{@link org.apache.http.params.CoreConnectionPNames#SOCKET_BUFFER_SIZE}</li>
- *  <li>{@link org.apache.http.params.CoreConnectionPNames#MAX_HEADER_COUNT}</li>
- *  <li>{@link org.apache.http.params.CoreConnectionPNames#MAX_LINE_LENGTH}</li>
- * </ul>
  *
  * @since 4.0
  *
@@ -91,15 +82,9 @@ public class SSLClientIOEventDispatch implements IOEventDispatch {
             final SSLIOSessionHandler sslHandler,
             final HttpParams params) {
         super();
-        if (handler == null) {
-            throw new IllegalArgumentException("HTTP client handler may not be null");
-        }
-        if (sslcontext == null) {
-            throw new IllegalArgumentException("SSL context may not be null");
-        }
-        if (params == null) {
-            throw new IllegalArgumentException("HTTP parameters may not be null");
-        }
+        Args.notNull(handler, "HTTP client handler");
+        Args.notNull(sslcontext, "SSL context");
+        Args.notNull(params, "HTTP parameters");
         this.handler = handler;
         this.params = params;
         this.sslcontext = sslcontext;
@@ -133,12 +118,13 @@ public class SSLClientIOEventDispatch implements IOEventDispatch {
      * @return byte buffer allocator.
      */
     protected ByteBufferAllocator createByteBufferAllocator() {
-        return new HeapByteBufferAllocator();
+        return HeapByteBufferAllocator.INSTANCE;
     }
 
     /**
      * Creates an instance of {@link DefaultHttpResponseFactory} to be used
-     * by HTTP connections for creating {@link HttpResponse} objects.
+     * by HTTP connections for creating {@link org.apache.http.HttpResponse}
+     * objects.
      * <p>
      * This method can be overridden in a super class in order to provide
      * a different implementation of the {@link HttpResponseFactory} interface.
@@ -146,7 +132,7 @@ public class SSLClientIOEventDispatch implements IOEventDispatch {
      * @return HTTP response factory.
      */
     protected HttpResponseFactory createHttpResponseFactory() {
-        return new DefaultHttpResponseFactory();
+        return DefaultHttpResponseFactory.INSTANCE;
     }
 
     /**
@@ -189,30 +175,30 @@ public class SSLClientIOEventDispatch implements IOEventDispatch {
 
     public void connected(final IOSession session) {
 
-        SSLIOSession sslSession = createSSLIOSession(
+        final SSLIOSession sslSession = createSSLIOSession(
                 session,
                 this.sslcontext,
                 this.sslHandler);
 
-        NHttpClientIOTarget conn = createConnection(
+        final NHttpClientIOTarget conn = createConnection(
                 sslSession);
 
         session.setAttribute(ExecutionContext.HTTP_CONNECTION, conn);
         session.setAttribute(SSL_SESSION, sslSession);
 
-        Object attachment = session.getAttribute(IOSession.ATTACHMENT_KEY);
+        final Object attachment = session.getAttribute(IOSession.ATTACHMENT_KEY);
         this.handler.connected(conn, attachment);
 
         try {
             sslSession.bind(SSLMode.CLIENT, this.params);
-        } catch (SSLException ex) {
+        } catch (final SSLException ex) {
             this.handler.exception(conn, ex);
             sslSession.shutdown();
         }
     }
 
     public void disconnected(final IOSession session) {
-        NHttpClientIOTarget conn =
+        final NHttpClientIOTarget conn =
             (NHttpClientIOTarget) session.getAttribute(ExecutionContext.HTTP_CONNECTION);
         if (conn != null) {
             this.handler.closed(conn);
@@ -220,9 +206,9 @@ public class SSLClientIOEventDispatch implements IOEventDispatch {
     }
 
     public void inputReady(final IOSession session) {
-        NHttpClientIOTarget conn =
+        final NHttpClientIOTarget conn =
             (NHttpClientIOTarget) session.getAttribute(ExecutionContext.HTTP_CONNECTION);
-        SSLIOSession sslSession =
+        final SSLIOSession sslSession =
             (SSLIOSession) session.getAttribute(SSL_SESSION);
 
         try {
@@ -230,16 +216,16 @@ public class SSLClientIOEventDispatch implements IOEventDispatch {
                 conn.consumeInput(this.handler);
             }
             sslSession.inboundTransport();
-        } catch (IOException ex) {
+        } catch (final IOException ex) {
             this.handler.exception(conn, ex);
             sslSession.shutdown();
         }
     }
 
     public void outputReady(final IOSession session) {
-        NHttpClientIOTarget conn =
+        final NHttpClientIOTarget conn =
             (NHttpClientIOTarget) session.getAttribute(ExecutionContext.HTTP_CONNECTION);
-        SSLIOSession sslSession =
+        final SSLIOSession sslSession =
             (SSLIOSession) session.getAttribute(SSL_SESSION);
 
         try {
@@ -247,16 +233,16 @@ public class SSLClientIOEventDispatch implements IOEventDispatch {
                 conn.produceOutput(this.handler);
             }
             sslSession.outboundTransport();
-        } catch (IOException ex) {
+        } catch (final IOException ex) {
             this.handler.exception(conn, ex);
             sslSession.shutdown();
         }
     }
 
     public void timeout(final IOSession session) {
-        NHttpClientIOTarget conn =
+        final NHttpClientIOTarget conn =
             (NHttpClientIOTarget) session.getAttribute(ExecutionContext.HTTP_CONNECTION);
-        SSLIOSession sslSession =
+        final SSLIOSession sslSession =
             (SSLIOSession) session.getAttribute(SSL_SESSION);
 
         this.handler.timeout(conn);
diff --git a/httpcore-nio/src/main/java/org/apache/http/impl/nio/SSLServerIOEventDispatch.java b/httpcore-nio/src/main/java-deprecated/org/apache/http/impl/nio/SSLServerIOEventDispatch.java
similarity index 85%
rename from httpcore-nio/src/main/java/org/apache/http/impl/nio/SSLServerIOEventDispatch.java
rename to httpcore-nio/src/main/java-deprecated/org/apache/http/impl/nio/SSLServerIOEventDispatch.java
index 144958c..4e46b29 100644
--- a/httpcore-nio/src/main/java/org/apache/http/impl/nio/SSLServerIOEventDispatch.java
+++ b/httpcore-nio/src/main/java-deprecated/org/apache/http/impl/nio/SSLServerIOEventDispatch.java
@@ -32,7 +32,6 @@ import java.io.IOException;
 import javax.net.ssl.SSLContext;
 import javax.net.ssl.SSLException;
 
-import org.apache.http.HttpRequest;
 import org.apache.http.HttpRequestFactory;
 import org.apache.http.impl.DefaultHttpRequestFactory;
 import org.apache.http.impl.nio.reactor.SSLIOSession;
@@ -46,19 +45,11 @@ import org.apache.http.nio.util.ByteBufferAllocator;
 import org.apache.http.nio.util.HeapByteBufferAllocator;
 import org.apache.http.params.HttpParams;
 import org.apache.http.protocol.ExecutionContext;
+import org.apache.http.util.Args;
 
 /**
  * Default implementation of {@link IOEventDispatch} interface for SSL
  * (encrypted) server-side HTTP connections.
- * <p>
- * The following parameters can be used to customize the behavior of this
- * class:
- * <ul>
- *  <li>{@link org.apache.http.params.CoreProtocolPNames#HTTP_ELEMENT_CHARSET}</li>
- *  <li>{@link org.apache.http.params.CoreConnectionPNames#SOCKET_BUFFER_SIZE}</li>
- *  <li>{@link org.apache.http.params.CoreConnectionPNames#MAX_HEADER_COUNT}</li>
- *  <li>{@link org.apache.http.params.CoreConnectionPNames#MAX_LINE_LENGTH}</li>
- * </ul>
  *
  * @since 4.0
  *
@@ -91,15 +82,9 @@ public class SSLServerIOEventDispatch implements IOEventDispatch {
             final SSLIOSessionHandler sslHandler,
             final HttpParams params) {
         super();
-        if (handler == null) {
-            throw new IllegalArgumentException("HTTP service handler may not be null");
-        }
-        if (sslcontext == null) {
-            throw new IllegalArgumentException("SSL context may not be null");
-        }
-        if (params == null) {
-            throw new IllegalArgumentException("HTTP parameters may not be null");
-        }
+        Args.notNull(handler, "HTTP service handler");
+        Args.notNull(sslcontext, "SSL context");
+        Args.notNull(params, "HTTP parameters");
         this.handler = handler;
         this.params = params;
         this.sslcontext = sslcontext;
@@ -133,12 +118,13 @@ public class SSLServerIOEventDispatch implements IOEventDispatch {
      * @return byte buffer allocator.
      */
     protected ByteBufferAllocator createByteBufferAllocator() {
-        return new HeapByteBufferAllocator();
+        return HeapByteBufferAllocator.INSTANCE;
     }
 
     /**
      * Creates an instance of {@link DefaultHttpRequestFactory} to be used
-     * by HTTP connections for creating {@link HttpRequest} objects.
+     * by HTTP connections for creating {@link org.apache.http.HttpRequest}
+     * objects.
      * <p>
      * This method can be overridden in a super class in order to provide
      * a different implementation of the {@link HttpRequestFactory} interface.
@@ -146,7 +132,7 @@ public class SSLServerIOEventDispatch implements IOEventDispatch {
      * @return HTTP request factory.
      */
     protected HttpRequestFactory createHttpRequestFactory() {
-        return new DefaultHttpRequestFactory();
+        return DefaultHttpRequestFactory.INSTANCE;
     }
 
     /**
@@ -189,12 +175,12 @@ public class SSLServerIOEventDispatch implements IOEventDispatch {
 
     public void connected(final IOSession session) {
 
-        SSLIOSession sslSession = createSSLIOSession(
+        final SSLIOSession sslSession = createSSLIOSession(
                 session,
                 this.sslcontext,
                 this.sslHandler);
 
-        NHttpServerIOTarget conn = createConnection(
+        final NHttpServerIOTarget conn = createConnection(
                 sslSession);
 
         session.setAttribute(ExecutionContext.HTTP_CONNECTION, conn);
@@ -204,14 +190,14 @@ public class SSLServerIOEventDispatch implements IOEventDispatch {
 
         try {
             sslSession.bind(SSLMode.SERVER, this.params);
-        } catch (SSLException ex) {
+        } catch (final SSLException ex) {
             this.handler.exception(conn, ex);
             sslSession.shutdown();
         }
     }
 
     public void disconnected(final IOSession session) {
-        NHttpServerIOTarget conn =
+        final NHttpServerIOTarget conn =
             (NHttpServerIOTarget) session.getAttribute(ExecutionContext.HTTP_CONNECTION);
 
         if (conn != null) {
@@ -220,9 +206,9 @@ public class SSLServerIOEventDispatch implements IOEventDispatch {
     }
 
     public void inputReady(final IOSession session) {
-        NHttpServerIOTarget conn =
+        final NHttpServerIOTarget conn =
             (NHttpServerIOTarget) session.getAttribute(ExecutionContext.HTTP_CONNECTION);
-        SSLIOSession sslSession =
+        final SSLIOSession sslSession =
             (SSLIOSession) session.getAttribute(SSL_SESSION);
 
         try {
@@ -230,16 +216,16 @@ public class SSLServerIOEventDispatch implements IOEventDispatch {
                 conn.consumeInput(this.handler);
             }
             sslSession.inboundTransport();
-        } catch (IOException ex) {
+        } catch (final IOException ex) {
             this.handler.exception(conn, ex);
             sslSession.shutdown();
         }
     }
 
     public void outputReady(final IOSession session) {
-        NHttpServerIOTarget conn =
+        final NHttpServerIOTarget conn =
             (NHttpServerIOTarget) session.getAttribute(ExecutionContext.HTTP_CONNECTION);
-        SSLIOSession sslSession =
+        final SSLIOSession sslSession =
             (SSLIOSession) session.getAttribute(SSL_SESSION);
 
         try {
@@ -247,16 +233,16 @@ public class SSLServerIOEventDispatch implements IOEventDispatch {
                 conn.produceOutput(this.handler);
             }
             sslSession.outboundTransport();
-        } catch (IOException ex) {
+        } catch (final IOException ex) {
             this.handler.exception(conn, ex);
             sslSession.shutdown();
         }
     }
 
     public void timeout(final IOSession session) {
-        NHttpServerIOTarget conn =
+        final NHttpServerIOTarget conn =
             (NHttpServerIOTarget) session.getAttribute(ExecutionContext.HTTP_CONNECTION);
-        SSLIOSession sslSession =
+        final SSLIOSession sslSession =
             (SSLIOSession) session.getAttribute(SSL_SESSION);
 
         this.handler.timeout(conn);
diff --git a/httpcore-nio/src/main/java/org/apache/http/impl/nio/codecs/HttpRequestParser.java b/httpcore-nio/src/main/java-deprecated/org/apache/http/impl/nio/codecs/HttpRequestParser.java
similarity index 85%
rename from httpcore-nio/src/main/java/org/apache/http/impl/nio/codecs/HttpRequestParser.java
rename to httpcore-nio/src/main/java-deprecated/org/apache/http/impl/nio/codecs/HttpRequestParser.java
index 2d04051..a125e2f 100644
--- a/httpcore-nio/src/main/java/org/apache/http/impl/nio/codecs/HttpRequestParser.java
+++ b/httpcore-nio/src/main/java-deprecated/org/apache/http/impl/nio/codecs/HttpRequestParser.java
@@ -29,19 +29,19 @@ package org.apache.http.impl.nio.codecs;
 
 import org.apache.http.HttpException;
 import org.apache.http.HttpMessage;
-import org.apache.http.HttpRequest;
 import org.apache.http.HttpRequestFactory;
-import org.apache.http.RequestLine;
 import org.apache.http.ParseException;
+import org.apache.http.RequestLine;
 import org.apache.http.message.LineParser;
 import org.apache.http.message.ParserCursor;
-import org.apache.http.nio.NHttpMessageParser;
 import org.apache.http.nio.reactor.SessionInputBuffer;
 import org.apache.http.params.HttpParams;
+import org.apache.http.util.Args;
 import org.apache.http.util.CharArrayBuffer;
 
 /**
- * Default {@link NHttpMessageParser} implementation for {@link HttpRequest}s.
+ * Default {@link org.apache.http.nio.NHttpMessageParser} implementation
+ * for {@link org.apache.http.HttpRequest}s.
  * <p>
  * The following parameters can be used to customize the behavior of this
  * class:
@@ -66,17 +66,15 @@ public class HttpRequestParser extends AbstractMessageParser {
             final HttpRequestFactory requestFactory,
             final HttpParams params) {
         super(buffer, parser, params);
-        if (requestFactory == null) {
-            throw new IllegalArgumentException("Request factory may not be null");
-        }
+        Args.notNull(requestFactory, "Request factory");
         this.requestFactory = requestFactory;
     }
 
     @Override
     protected HttpMessage createMessage(final CharArrayBuffer buffer)
             throws HttpException, ParseException {
-        ParserCursor cursor = new ParserCursor(0, buffer.length());
-        RequestLine requestLine = lineParser.parseRequestLine(buffer, cursor);
+        final ParserCursor cursor = new ParserCursor(0, buffer.length());
+        final RequestLine requestLine = lineParser.parseRequestLine(buffer, cursor);
         return this.requestFactory.newHttpRequest(requestLine);
     }
 
diff --git a/httpcore-nio/src/main/java/org/apache/http/impl/nio/codecs/HttpRequestWriter.java b/httpcore-nio/src/main/java-deprecated/org/apache/http/impl/nio/codecs/HttpRequestWriter.java
similarity index 94%
rename from httpcore-nio/src/main/java/org/apache/http/impl/nio/codecs/HttpRequestWriter.java
rename to httpcore-nio/src/main/java-deprecated/org/apache/http/impl/nio/codecs/HttpRequestWriter.java
index 46f4d80..ad93b52 100644
--- a/httpcore-nio/src/main/java/org/apache/http/impl/nio/codecs/HttpRequestWriter.java
+++ b/httpcore-nio/src/main/java-deprecated/org/apache/http/impl/nio/codecs/HttpRequestWriter.java
@@ -32,13 +32,13 @@ import java.io.IOException;
 import org.apache.http.HttpMessage;
 import org.apache.http.HttpRequest;
 import org.apache.http.message.LineFormatter;
-import org.apache.http.nio.NHttpMessageWriter;
 import org.apache.http.nio.reactor.SessionOutputBuffer;
 import org.apache.http.params.HttpParams;
 import org.apache.http.util.CharArrayBuffer;
 
 /**
- * Default {@link NHttpMessageWriter} implementation for {@link HttpRequest}s.
+ * Default {@link org.apache.http.nio.NHttpMessageWriter} implementation
+ * for {@link HttpRequest}s.
  *
  * @since 4.0
  *
diff --git a/httpcore-nio/src/main/java/org/apache/http/impl/nio/codecs/HttpResponseParser.java b/httpcore-nio/src/main/java-deprecated/org/apache/http/impl/nio/codecs/HttpResponseParser.java
similarity index 85%
rename from httpcore-nio/src/main/java/org/apache/http/impl/nio/codecs/HttpResponseParser.java
rename to httpcore-nio/src/main/java-deprecated/org/apache/http/impl/nio/codecs/HttpResponseParser.java
index f673df7..46af248 100644
--- a/httpcore-nio/src/main/java/org/apache/http/impl/nio/codecs/HttpResponseParser.java
+++ b/httpcore-nio/src/main/java-deprecated/org/apache/http/impl/nio/codecs/HttpResponseParser.java
@@ -29,19 +29,19 @@ package org.apache.http.impl.nio.codecs;
 
 import org.apache.http.HttpException;
 import org.apache.http.HttpMessage;
-import org.apache.http.HttpResponse;
 import org.apache.http.HttpResponseFactory;
-import org.apache.http.StatusLine;
 import org.apache.http.ParseException;
+import org.apache.http.StatusLine;
 import org.apache.http.message.LineParser;
 import org.apache.http.message.ParserCursor;
-import org.apache.http.nio.NHttpMessageParser;
 import org.apache.http.nio.reactor.SessionInputBuffer;
 import org.apache.http.params.HttpParams;
+import org.apache.http.util.Args;
 import org.apache.http.util.CharArrayBuffer;
 
 /**
- * Default {@link NHttpMessageParser} implementation for {@link HttpResponse}s.
+ * Default {@link org.apache.http.nio.NHttpMessageParser} implementation
+ * for {@link org.apache.http.HttpResponse}s.
  * <p>
  * The following parameters can be used to customize the behavior of this
  * class:
@@ -66,17 +66,15 @@ public class HttpResponseParser extends AbstractMessageParser {
             final HttpResponseFactory responseFactory,
             final HttpParams params) {
         super(buffer, parser, params);
-        if (responseFactory == null) {
-            throw new IllegalArgumentException("Response factory may not be null");
-        }
+        Args.notNull(responseFactory, "Response factory");
         this.responseFactory = responseFactory;
     }
 
     @Override
     protected HttpMessage createMessage(final CharArrayBuffer buffer)
             throws HttpException, ParseException {
-        ParserCursor cursor = new ParserCursor(0, buffer.length());
-        StatusLine statusline = lineParser.parseStatusLine(buffer, cursor);
+        final ParserCursor cursor = new ParserCursor(0, buffer.length());
+        final StatusLine statusline = lineParser.parseStatusLine(buffer, cursor);
         return this.responseFactory.newHttpResponse(statusline, null);
     }
 
diff --git a/httpcore-nio/src/main/java/org/apache/http/impl/nio/codecs/HttpResponseWriter.java b/httpcore-nio/src/main/java-deprecated/org/apache/http/impl/nio/codecs/HttpResponseWriter.java
similarity index 94%
rename from httpcore-nio/src/main/java/org/apache/http/impl/nio/codecs/HttpResponseWriter.java
rename to httpcore-nio/src/main/java-deprecated/org/apache/http/impl/nio/codecs/HttpResponseWriter.java
index 94b9316..aaa305d 100644
--- a/httpcore-nio/src/main/java/org/apache/http/impl/nio/codecs/HttpResponseWriter.java
+++ b/httpcore-nio/src/main/java-deprecated/org/apache/http/impl/nio/codecs/HttpResponseWriter.java
@@ -32,13 +32,13 @@ import java.io.IOException;
 import org.apache.http.HttpMessage;
 import org.apache.http.HttpResponse;
 import org.apache.http.message.LineFormatter;
-import org.apache.http.nio.NHttpMessageWriter;
 import org.apache.http.nio.reactor.SessionOutputBuffer;
 import org.apache.http.params.HttpParams;
 import org.apache.http.util.CharArrayBuffer;
 
 /**
- * Default {@link NHttpMessageWriter} implementation for {@link HttpResponse}s.
+ * Default {@link org.apache.http.nio.NHttpMessageWriter} implementation
+ * for {@link HttpResponse}s.
  *
  * @since 4.0
  *
diff --git a/httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/SSLIOSession.java b/httpcore-nio/src/main/java-deprecated/org/apache/http/impl/nio/reactor/SSLIOSession.java
similarity index 97%
rename from httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/SSLIOSession.java
rename to httpcore-nio/src/main/java-deprecated/org/apache/http/impl/nio/reactor/SSLIOSession.java
index a8ac898..931e981 100644
--- a/httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/SSLIOSession.java
+++ b/httpcore-nio/src/main/java-deprecated/org/apache/http/impl/nio/reactor/SSLIOSession.java
@@ -66,7 +66,7 @@ public class SSLIOSession extends org.apache.http.nio.reactor.ssl.SSLIOSession {
     public synchronized void bind(
             final SSLMode mode,
             final HttpParams params) throws SSLException {
-        org.apache.http.nio.reactor.ssl.SSLSetupHandler handler = getSSLSetupHandler();
+        final org.apache.http.nio.reactor.ssl.SSLSetupHandler handler = getSSLSetupHandler();
         if (handler instanceof SSLIOSessionHandlerAdaptor) {
             ((SSLIOSessionHandlerAdaptor) handler).setParams(params);
         } else if (handler instanceof SSLSetupHandlerAdaptor) {
diff --git a/httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/SSLIOSessionHandler.java b/httpcore-nio/src/main/java-deprecated/org/apache/http/impl/nio/reactor/SSLIOSessionHandler.java
similarity index 100%
rename from httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/SSLIOSessionHandler.java
rename to httpcore-nio/src/main/java-deprecated/org/apache/http/impl/nio/reactor/SSLIOSessionHandler.java
diff --git a/httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/SSLIOSessionHandlerAdaptor.java b/httpcore-nio/src/main/java-deprecated/org/apache/http/impl/nio/reactor/SSLIOSessionHandlerAdaptor.java
similarity index 100%
rename from httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/SSLIOSessionHandlerAdaptor.java
rename to httpcore-nio/src/main/java-deprecated/org/apache/http/impl/nio/reactor/SSLIOSessionHandlerAdaptor.java
diff --git a/httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/SSLMode.java b/httpcore-nio/src/main/java-deprecated/org/apache/http/impl/nio/reactor/SSLMode.java
similarity index 99%
rename from httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/SSLMode.java
rename to httpcore-nio/src/main/java-deprecated/org/apache/http/impl/nio/reactor/SSLMode.java
index 346f68a..6e372b6 100644
--- a/httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/SSLMode.java
+++ b/httpcore-nio/src/main/java-deprecated/org/apache/http/impl/nio/reactor/SSLMode.java
@@ -29,7 +29,7 @@ package org.apache.http.impl.nio.reactor;
 
 /**
  * @since 4.0
- * 
+ *
  * @deprecated (4.2)
  */
 @Deprecated
diff --git a/httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/SSLSetupHandler.java b/httpcore-nio/src/main/java-deprecated/org/apache/http/impl/nio/reactor/SSLSetupHandler.java
similarity index 100%
rename from httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/SSLSetupHandler.java
rename to httpcore-nio/src/main/java-deprecated/org/apache/http/impl/nio/reactor/SSLSetupHandler.java
diff --git a/httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/SSLSetupHandlerAdaptor.java b/httpcore-nio/src/main/java-deprecated/org/apache/http/impl/nio/reactor/SSLSetupHandlerAdaptor.java
similarity index 100%
rename from httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/SSLSetupHandlerAdaptor.java
rename to httpcore-nio/src/main/java-deprecated/org/apache/http/impl/nio/reactor/SSLSetupHandlerAdaptor.java
diff --git a/httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/SessionHandle.java b/httpcore-nio/src/main/java-deprecated/org/apache/http/impl/nio/reactor/SessionHandle.java
similarity index 90%
rename from httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/SessionHandle.java
rename to httpcore-nio/src/main/java-deprecated/org/apache/http/impl/nio/reactor/SessionHandle.java
index 299b4a9..d1497ef 100644
--- a/httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/SessionHandle.java
+++ b/httpcore-nio/src/main/java-deprecated/org/apache/http/impl/nio/reactor/SessionHandle.java
@@ -28,6 +28,7 @@
 package org.apache.http.impl.nio.reactor;
 
 import org.apache.http.nio.reactor.IOSession;
+import org.apache.http.util.Args;
 
 /**
  * Session handle class used by I/O reactor implementations to keep a reference
@@ -35,7 +36,7 @@ import org.apache.http.nio.reactor.IOSession;
  * operations on that session.
  *
  * @since 4.0
- * 
+ *
  * @deprecated (4.2) use {@link IOSessionImpl}
  */
 @Deprecated
@@ -50,11 +51,9 @@ public class SessionHandle {
 
     public SessionHandle(final IOSession session) {
         super();
-        if (session == null) {
-            throw new IllegalArgumentException("Session may not be null");
-        }
+        Args.notNull(session, "Session");
         this.session = session;
-        long now = System.currentTimeMillis();
+        final long now = System.currentTimeMillis();
         this.startedTime = now;
         this.lastReadTime = now;
         this.lastWriteTime = now;
@@ -82,13 +81,13 @@ public class SessionHandle {
     }
 
     public void resetLastRead() {
-        long now = System.currentTimeMillis();
+        final long now = System.currentTimeMillis();
         this.lastReadTime = now;
         this.lastAccessTime = now;
     }
 
     public void resetLastWrite() {
-        long now = System.currentTimeMillis();
+        final long now = System.currentTimeMillis();
         this.lastWriteTime = now;
         this.lastAccessTime = now;
     }
diff --git a/httpcore-nio/src/main/java/org/apache/http/impl/nio/ssl/SSLClientIOEventDispatch.java b/httpcore-nio/src/main/java-deprecated/org/apache/http/impl/nio/ssl/SSLClientIOEventDispatch.java
similarity index 77%
rename from httpcore-nio/src/main/java/org/apache/http/impl/nio/ssl/SSLClientIOEventDispatch.java
rename to httpcore-nio/src/main/java-deprecated/org/apache/http/impl/nio/ssl/SSLClientIOEventDispatch.java
index 73a8fca..4a00802 100644
--- a/httpcore-nio/src/main/java/org/apache/http/impl/nio/ssl/SSLClientIOEventDispatch.java
+++ b/httpcore-nio/src/main/java-deprecated/org/apache/http/impl/nio/ssl/SSLClientIOEventDispatch.java
@@ -31,34 +31,23 @@ import javax.net.ssl.SSLContext;
 import javax.net.ssl.SSLException;
 
 import org.apache.http.annotation.Immutable;
-import org.apache.http.impl.nio.DefaultHttpClientIODispatch;
 import org.apache.http.impl.nio.DefaultClientIOEventDispatch;
 import org.apache.http.impl.nio.reactor.SSLIOSession;
 import org.apache.http.impl.nio.reactor.SSLSetupHandler;
 import org.apache.http.nio.NHttpClientHandler;
 import org.apache.http.nio.NHttpClientIOTarget;
-import org.apache.http.nio.reactor.IOEventDispatch;
 import org.apache.http.nio.reactor.IOSession;
 import org.apache.http.params.HttpConnectionParams;
 import org.apache.http.params.HttpParams;
+import org.apache.http.util.Args;
 
 /**
- * Default implementation of {@link IOEventDispatch} interface for SSL
- * (encrypted) client-side HTTP connections.
- * <p>
- * The following parameters can be used to customize the behavior of this
- * class:
- * <ul>
- *  <li>{@link org.apache.http.params.CoreProtocolPNames#HTTP_ELEMENT_CHARSET}</li>
- *  <li>{@link org.apache.http.params.CoreConnectionPNames#SO_TIMEOUT}</li>
- *  <li>{@link org.apache.http.params.CoreConnectionPNames#SOCKET_BUFFER_SIZE}</li>
- *  <li>{@link org.apache.http.params.CoreConnectionPNames#MAX_HEADER_COUNT}</li>
- *  <li>{@link org.apache.http.params.CoreConnectionPNames#MAX_LINE_LENGTH}</li>
- * </ul>
+ * Default implementation of {@link org.apache.http.nio.reactor.IOEventDispatch}
+ * interface for SSL (encrypted) client-side HTTP connections.
  *
  * @since 4.1
  *
- * @deprecated (4.2) use {@link DefaultHttpClientIODispatch}
+ * @deprecated (4.2) use {@link org.apache.http.impl.nio.DefaultHttpClientIODispatch}
  */
 @Deprecated
 @Immutable // provided injected dependencies are immutable
@@ -84,12 +73,8 @@ public class SSLClientIOEventDispatch extends DefaultClientIOEventDispatch {
             final SSLSetupHandler sslHandler,
             final HttpParams params) {
         super(handler, params);
-        if (sslcontext == null) {
-            throw new IllegalArgumentException("SSL context may not be null");
-        }
-        if (params == null) {
-            throw new IllegalArgumentException("HTTP parameters may not be null");
-        }
+        Args.notNull(sslcontext, "SSL context");
+        Args.notNull(params, "HTTP parameters");
         this.sslcontext = sslcontext;
         this.sslHandler = sslHandler;
     }
@@ -136,12 +121,12 @@ public class SSLClientIOEventDispatch extends DefaultClientIOEventDispatch {
 
     @Override
     protected NHttpClientIOTarget createConnection(final IOSession session) {
-        SSLIOSession ssliosession = createSSLIOSession(session, this.sslcontext, this.sslHandler);
+        final SSLIOSession ssliosession = createSSLIOSession(session, this.sslcontext, this.sslHandler);
         session.setAttribute(SSLIOSession.SESSION_KEY, ssliosession);
-        NHttpClientIOTarget conn = createSSLConnection(ssliosession);
+        final NHttpClientIOTarget conn = createSSLConnection(ssliosession);
         try {
             ssliosession.initialize();
-        } catch (SSLException ex) {
+        } catch (final SSLException ex) {
             this.handler.exception(conn, ex);
             ssliosession.shutdown();
         }
@@ -150,10 +135,10 @@ public class SSLClientIOEventDispatch extends DefaultClientIOEventDispatch {
 
     @Override
     public void onConnected(final NHttpClientIOTarget conn) {
-        int timeout = HttpConnectionParams.getSoTimeout(this.params);
+        final int timeout = HttpConnectionParams.getSoTimeout(this.params);
         conn.setSocketTimeout(timeout);
 
-        Object attachment = conn.getContext().getAttribute(IOSession.ATTACHMENT_KEY);
+        final Object attachment = conn.getContext().getAttribute(IOSession.ATTACHMENT_KEY);
         this.handler.connected(conn, attachment);
     }
 
diff --git a/httpcore-nio/src/main/java/org/apache/http/impl/nio/ssl/SSLServerIOEventDispatch.java b/httpcore-nio/src/main/java-deprecated/org/apache/http/impl/nio/ssl/SSLServerIOEventDispatch.java
similarity index 78%
rename from httpcore-nio/src/main/java/org/apache/http/impl/nio/ssl/SSLServerIOEventDispatch.java
rename to httpcore-nio/src/main/java-deprecated/org/apache/http/impl/nio/ssl/SSLServerIOEventDispatch.java
index 90c805a..5425801 100644
--- a/httpcore-nio/src/main/java/org/apache/http/impl/nio/ssl/SSLServerIOEventDispatch.java
+++ b/httpcore-nio/src/main/java-deprecated/org/apache/http/impl/nio/ssl/SSLServerIOEventDispatch.java
@@ -31,34 +31,23 @@ import javax.net.ssl.SSLContext;
 import javax.net.ssl.SSLException;
 
 import org.apache.http.annotation.Immutable;
-import org.apache.http.impl.nio.DefaultHttpServerIODispatch;
 import org.apache.http.impl.nio.DefaultServerIOEventDispatch;
 import org.apache.http.impl.nio.reactor.SSLIOSession;
 import org.apache.http.impl.nio.reactor.SSLSetupHandler;
 import org.apache.http.nio.NHttpServerIOTarget;
 import org.apache.http.nio.NHttpServiceHandler;
-import org.apache.http.nio.reactor.IOEventDispatch;
 import org.apache.http.nio.reactor.IOSession;
 import org.apache.http.params.HttpConnectionParams;
 import org.apache.http.params.HttpParams;
+import org.apache.http.util.Args;
 
 /**
- * Default implementation of {@link IOEventDispatch} interface for SSL
- * (encrypted) server-side HTTP connections.
- * <p>
- * The following parameters can be used to customize the behavior of this
- * class:
- * <ul>
- *  <li>{@link org.apache.http.params.CoreProtocolPNames#HTTP_ELEMENT_CHARSET}</li>
- *  <li>{@link org.apache.http.params.CoreConnectionPNames#SO_TIMEOUT}</li>
- *  <li>{@link org.apache.http.params.CoreConnectionPNames#SOCKET_BUFFER_SIZE}</li>
- *  <li>{@link org.apache.http.params.CoreConnectionPNames#MAX_HEADER_COUNT}</li>
- *  <li>{@link org.apache.http.params.CoreConnectionPNames#MAX_LINE_LENGTH}</li>
- * </ul>
+ * Default implementation of {@link org.apache.http.nio.reactor.IOEventDispatch}
+ * interface for SSL (encrypted) server-side HTTP connections.
  *
  * @since 4.1
  *
- * @deprecated (4.2) use {@link DefaultHttpServerIODispatch}
+ * @deprecated (4.2) use {@link org.apache.http.impl.nio.DefaultHttpServerIODispatch}
  */
 @Deprecated
 @Immutable // provided injected dependencies are immutable
@@ -84,12 +73,8 @@ public class SSLServerIOEventDispatch extends DefaultServerIOEventDispatch {
             final SSLSetupHandler sslHandler,
             final HttpParams params) {
         super(handler, params);
-        if (sslcontext == null) {
-            throw new IllegalArgumentException("SSL context may not be null");
-        }
-        if (params == null) {
-            throw new IllegalArgumentException("HTTP parameters may not be null");
-        }
+        Args.notNull(sslcontext, "SSL context");
+        Args.notNull(params, "HTTP parameters");
         this.sslcontext = sslcontext;
         this.sslHandler = sslHandler;
     }
@@ -136,12 +121,12 @@ public class SSLServerIOEventDispatch extends DefaultServerIOEventDispatch {
 
     @Override
     protected NHttpServerIOTarget createConnection(final IOSession session) {
-        SSLIOSession ssliosession = createSSLIOSession(session, this.sslcontext, this.sslHandler);
+        final SSLIOSession ssliosession = createSSLIOSession(session, this.sslcontext, this.sslHandler);
         session.setAttribute(SSLIOSession.SESSION_KEY, ssliosession);
-        NHttpServerIOTarget conn = createSSLConnection(ssliosession);
+        final NHttpServerIOTarget conn = createSSLConnection(ssliosession);
         try {
             ssliosession.initialize();
-        } catch (SSLException ex) {
+        } catch (final SSLException ex) {
             this.handler.exception(conn, ex);
             ssliosession.shutdown();
         }
@@ -150,7 +135,7 @@ public class SSLServerIOEventDispatch extends DefaultServerIOEventDispatch {
 
     @Override
     public void onConnected(final NHttpServerIOTarget conn) {
-        int timeout = HttpConnectionParams.getSoTimeout(this.params);
+        final int timeout = HttpConnectionParams.getSoTimeout(this.params);
         conn.setSocketTimeout(timeout);
         this.handler.connected(conn);
     }
diff --git a/httpcore-nio/src/main/java/org/apache/http/impl/nio/ssl/package.html b/httpcore-nio/src/main/java-deprecated/org/apache/http/impl/nio/ssl/package.html
similarity index 100%
rename from httpcore-nio/src/main/java/org/apache/http/impl/nio/ssl/package.html
rename to httpcore-nio/src/main/java-deprecated/org/apache/http/impl/nio/ssl/package.html
diff --git a/httpcore-nio/src/main/java/org/apache/http/nio/params/NIOReactorParamBean.java b/httpcore-nio/src/main/java-deprecated/org/apache/http/nio/params/NIOReactorParamBean.java
similarity index 88%
rename from httpcore-nio/src/main/java/org/apache/http/nio/params/NIOReactorParamBean.java
rename to httpcore-nio/src/main/java-deprecated/org/apache/http/nio/params/NIOReactorParamBean.java
index d4a1810..de7e66e 100644
--- a/httpcore-nio/src/main/java/org/apache/http/nio/params/NIOReactorParamBean.java
+++ b/httpcore-nio/src/main/java-deprecated/org/apache/http/nio/params/NIOReactorParamBean.java
@@ -27,14 +27,13 @@
 
 package org.apache.http.nio.params;
 
-import org.apache.http.impl.nio.reactor.IOReactorConfig;
 import org.apache.http.params.HttpAbstractParamBean;
 import org.apache.http.params.HttpParams;
 
 /**
  * @since 4.0
  *
- * @deprecated (4.2) use {@link IOReactorConfig}
+ * @deprecated (4.2) use {@link org.apache.http.impl.nio.reactor.IOReactorConfig}
  */
 @Deprecated
 public class NIOReactorParamBean extends HttpAbstractParamBean {
@@ -43,11 +42,11 @@ public class NIOReactorParamBean extends HttpAbstractParamBean {
         super(params);
     }
 
-    public void setContentBufferSize (int contentBufferSize) {
+    public void setContentBufferSize (final int contentBufferSize) {
         NIOReactorParams.setContentBufferSize(params, contentBufferSize);
     }
 
-    public void setSelectInterval (long selectInterval) {
+    public void setSelectInterval (final long selectInterval) {
         NIOReactorParams.setSelectInterval(params, selectInterval);
     }
 
diff --git a/httpcore-nio/src/main/java/org/apache/http/nio/params/NIOReactorParams.java b/httpcore-nio/src/main/java-deprecated/org/apache/http/nio/params/NIOReactorParams.java
similarity index 77%
rename from httpcore-nio/src/main/java/org/apache/http/nio/params/NIOReactorParams.java
rename to httpcore-nio/src/main/java-deprecated/org/apache/http/nio/params/NIOReactorParams.java
index d6b2450..a837c05 100644
--- a/httpcore-nio/src/main/java/org/apache/http/nio/params/NIOReactorParams.java
+++ b/httpcore-nio/src/main/java-deprecated/org/apache/http/nio/params/NIOReactorParams.java
@@ -27,8 +27,8 @@
 
 package org.apache.http.nio.params;
 
-import org.apache.http.impl.nio.reactor.IOReactorConfig;
 import org.apache.http.params.HttpParams;
+import org.apache.http.util.Args;
 
 /**
  * Utility class for accessing I/O reactor parameters in {@link HttpParams}.
@@ -37,7 +37,7 @@ import org.apache.http.params.HttpParams;
  *
  * @see NIOReactorPNames
  *
- * @deprecated (4.2) use {@link IOReactorConfig}
+ * @deprecated (4.2) use {@link org.apache.http.impl.nio.reactor.IOReactorConfig}
  */
 @Deprecated
 public final class NIOReactorParams implements NIOReactorPNames {
@@ -54,9 +54,7 @@ public final class NIOReactorParams implements NIOReactorPNames {
      * @return content buffer size.
      */
     public static int getContentBufferSize(final HttpParams params) {
-        if (params == null) {
-            throw new IllegalArgumentException("HTTP parameters may not be null");
-        }
+        Args.notNull(params, "HTTP parameters");
         return params.getIntParameter(CONTENT_BUFFER_SIZE, 4096);
     }
 
@@ -66,10 +64,8 @@ public final class NIOReactorParams implements NIOReactorPNames {
      * @param params HTTP parameters.
      * @param size content buffer size.
      */
-    public static void setContentBufferSize(final HttpParams params, int size) {
-        if (params == null) {
-            throw new IllegalArgumentException("HTTP parameters may not be null");
-        }
+    public static void setContentBufferSize(final HttpParams params, final int size) {
+        Args.notNull(params, "HTTP parameters");
         params.setIntParameter(CONTENT_BUFFER_SIZE, size);
     }
 
@@ -81,9 +77,7 @@ public final class NIOReactorParams implements NIOReactorPNames {
      * @return I/O select interval in milliseconds.
      */
     public static long getSelectInterval(final HttpParams params) {
-        if (params == null) {
-            throw new IllegalArgumentException("HTTP parameters may not be null");
-        }
+        Args.notNull(params, "HTTP parameters");
         return params.getLongParameter(SELECT_INTERVAL, 1000);
     }
 
@@ -93,10 +87,8 @@ public final class NIOReactorParams implements NIOReactorPNames {
      * @param params HTTP parameters.
      * @param ms I/O select interval in milliseconds.
      */
-    public static void setSelectInterval(final HttpParams params, long ms) {
-        if (params == null) {
-            throw new IllegalArgumentException("HTTP parameters may not be null");
-        }
+    public static void setSelectInterval(final HttpParams params, final long ms) {
+        Args.notNull(params, "HTTP parameters");
         params.setLongParameter(SELECT_INTERVAL, ms);
     }
 
@@ -108,9 +100,7 @@ public final class NIOReactorParams implements NIOReactorPNames {
      * @return shutdown grace period in milliseconds.
      */
     public static long getGracePeriod(final HttpParams params) {
-        if (params == null) {
-            throw new IllegalArgumentException("HTTP parameters may not be null");
-        }
+        Args.notNull(params, "HTTP parameters");
         return params.getLongParameter(GRACE_PERIOD, 500);
     }
 
@@ -120,10 +110,8 @@ public final class NIOReactorParams implements NIOReactorPNames {
      * @param params HTTP parameters.
      * @param ms shutdown grace period in milliseconds.
      */
-    public static void setGracePeriod(final HttpParams params, long ms) {
-        if (params == null) {
-            throw new IllegalArgumentException("HTTP parameters may not be null");
-        }
+    public static void setGracePeriod(final HttpParams params, final long ms) {
+        Args.notNull(params, "HTTP parameters");
         params.setLongParameter(GRACE_PERIOD, ms);
     }
 
@@ -137,9 +125,7 @@ public final class NIOReactorParams implements NIOReactorPNames {
      * @since 4.1
      */
     public static boolean getInterestOpsQueueing(final HttpParams params) {
-        if (params == null) {
-            throw new IllegalArgumentException("HTTP parameters may not be null");
-        }
+        Args.notNull(params, "HTTP parameters");
         return params.getBooleanParameter(INTEREST_OPS_QUEUEING, false);
     }
 
@@ -152,10 +138,8 @@ public final class NIOReactorParams implements NIOReactorPNames {
      * @since 4.1
      */
     public static void setInterestOpsQueueing(
-            final HttpParams params, boolean interestOpsQueueing) {
-        if (params == null) {
-            throw new IllegalArgumentException("HTTP parameters may not be null");
-        }
+            final HttpParams params, final boolean interestOpsQueueing) {
+        Args.notNull(params, "HTTP parameters");
         params.setBooleanParameter(INTEREST_OPS_QUEUEING, interestOpsQueueing);
     }
 
diff --git a/httpcore-nio/src/main/java/org/apache/http/nio/protocol/AsyncNHttpClientHandler.java b/httpcore-nio/src/main/java-deprecated/org/apache/http/nio/protocol/AsyncNHttpClientHandler.java
similarity index 87%
rename from httpcore-nio/src/main/java/org/apache/http/nio/protocol/AsyncNHttpClientHandler.java
rename to httpcore-nio/src/main/java-deprecated/org/apache/http/nio/protocol/AsyncNHttpClientHandler.java
index f79ab79..9ee0a65 100644
--- a/httpcore-nio/src/main/java/org/apache/http/nio/protocol/AsyncNHttpClientHandler.java
+++ b/httpcore-nio/src/main/java-deprecated/org/apache/http/nio/protocol/AsyncNHttpClientHandler.java
@@ -52,6 +52,7 @@ import org.apache.http.params.HttpParams;
 import org.apache.http.protocol.ExecutionContext;
 import org.apache.http.protocol.HttpContext;
 import org.apache.http.protocol.HttpProcessor;
+import org.apache.http.util.Args;
 
 /**
  * Fully asynchronous HTTP client side protocol handler that implements the
@@ -103,10 +104,7 @@ public class AsyncNHttpClientHandler extends NHttpHandlerBase
             final ByteBufferAllocator allocator,
             final HttpParams params) {
         super(httpProcessor, connStrategy, allocator, params);
-        if (execHandler == null) {
-            throw new IllegalArgumentException("HTTP request execution handler may not be null.");
-        }
-        this.execHandler = execHandler;
+        this.execHandler = Args.notNull(execHandler, "HTTP request execution handler");
     }
 
     public AsyncNHttpClientHandler(
@@ -114,16 +112,15 @@ public class AsyncNHttpClientHandler extends NHttpHandlerBase
             final NHttpRequestExecutionHandler execHandler,
             final ConnectionReuseStrategy connStrategy,
             final HttpParams params) {
-        this(httpProcessor, execHandler, connStrategy,
-                new HeapByteBufferAllocator(), params);
+        this(httpProcessor, execHandler, connStrategy, HeapByteBufferAllocator.INSTANCE, params);
     }
 
     public void connected(final NHttpClientConnection conn, final Object attachment) {
-        HttpContext context = conn.getContext();
+        final HttpContext context = conn.getContext();
 
         initialize(conn, attachment);
 
-        ClientConnState connState = new ClientConnState();
+        final ClientConnState connState = new ClientConnState();
         context.setAttribute(CONN_STATE, connState);
 
         if (this.eventListener != null) {
@@ -134,12 +131,12 @@ public class AsyncNHttpClientHandler extends NHttpHandlerBase
     }
 
     public void closed(final NHttpClientConnection conn) {
-        HttpContext context = conn.getContext();
+        final HttpContext context = conn.getContext();
 
-        ClientConnState connState = (ClientConnState) context.getAttribute(CONN_STATE);
+        final ClientConnState connState = (ClientConnState) context.getAttribute(CONN_STATE);
         try {
             connState.reset();
-        } catch (IOException ex) {
+        } catch (final IOException ex) {
             if (this.eventListener != null) {
                 this.eventListener.fatalIOException(ex, conn);
             }
@@ -167,16 +164,16 @@ public class AsyncNHttpClientHandler extends NHttpHandlerBase
     }
 
     public void requestReady(final NHttpClientConnection conn) {
-        HttpContext context = conn.getContext();
+        final HttpContext context = conn.getContext();
 
-        ClientConnState connState = (ClientConnState) context.getAttribute(CONN_STATE);
+        final ClientConnState connState = (ClientConnState) context.getAttribute(CONN_STATE);
         if (connState.getOutputState() != ClientConnState.READY) {
             return;
         }
 
         try {
 
-            HttpRequest request = this.execHandler.submitRequest(context);
+            final HttpRequest request = this.execHandler.submitRequest(context);
             if (request == null) {
                 return;
             }
@@ -216,12 +213,12 @@ public class AsyncNHttpClientHandler extends NHttpHandlerBase
                 connState.setOutputState(ClientConnState.REQUEST_BODY_STREAM);
             }
 
-        } catch (IOException ex) {
+        } catch (final IOException ex) {
             shutdownConnection(conn, ex);
             if (this.eventListener != null) {
                 this.eventListener.fatalIOException(ex, conn);
             }
-        } catch (HttpException ex) {
+        } catch (final HttpException ex) {
             closeConnection(conn, ex);
             if (this.eventListener != null) {
                 this.eventListener.fatalProtocolException(ex, conn);
@@ -230,11 +227,11 @@ public class AsyncNHttpClientHandler extends NHttpHandlerBase
     }
 
     public void inputReady(final NHttpClientConnection conn, final ContentDecoder decoder) {
-        HttpContext context = conn.getContext();
+        final HttpContext context = conn.getContext();
 
-        ClientConnState connState = (ClientConnState) context.getAttribute(CONN_STATE);
+        final ClientConnState connState = (ClientConnState) context.getAttribute(CONN_STATE);
 
-        ConsumingNHttpEntity consumingEntity = connState.getConsumingEntity();
+        final ConsumingNHttpEntity consumingEntity = connState.getConsumingEntity();
 
         try {
             consumingEntity.consumeContent(decoder, conn);
@@ -242,12 +239,12 @@ public class AsyncNHttpClientHandler extends NHttpHandlerBase
                 processResponse(conn, connState);
             }
 
-        } catch (IOException ex) {
+        } catch (final IOException ex) {
             shutdownConnection(conn, ex);
             if (this.eventListener != null) {
                 this.eventListener.fatalIOException(ex, conn);
             }
-        } catch (HttpException ex) {
+        } catch (final HttpException ex) {
             closeConnection(conn, ex);
             if (this.eventListener != null) {
                 this.eventListener.fatalProtocolException(ex, conn);
@@ -256,8 +253,8 @@ public class AsyncNHttpClientHandler extends NHttpHandlerBase
     }
 
     public void outputReady(final NHttpClientConnection conn, final ContentEncoder encoder) {
-        HttpContext context = conn.getContext();
-        ClientConnState connState = (ClientConnState) context.getAttribute(CONN_STATE);
+        final HttpContext context = conn.getContext();
+        final ClientConnState connState = (ClientConnState) context.getAttribute(CONN_STATE);
 
         try {
             if (connState.getOutputState() == ClientConnState.EXPECT_CONTINUE) {
@@ -265,13 +262,13 @@ public class AsyncNHttpClientHandler extends NHttpHandlerBase
                 return;
             }
 
-            ProducingNHttpEntity entity = connState.getProducingEntity();
+            final ProducingNHttpEntity entity = connState.getProducingEntity();
 
             entity.produceContent(encoder, conn);
             if (encoder.isCompleted()) {
                 connState.setOutputState(ClientConnState.REQUEST_BODY_DONE);
             }
-        } catch (IOException ex) {
+        } catch (final IOException ex) {
             shutdownConnection(conn, ex);
             if (this.eventListener != null) {
                 this.eventListener.fatalIOException(ex, conn);
@@ -280,17 +277,17 @@ public class AsyncNHttpClientHandler extends NHttpHandlerBase
     }
 
     public void responseReceived(final NHttpClientConnection conn) {
-        HttpContext context = conn.getContext();
-        ClientConnState connState = (ClientConnState) context.getAttribute(CONN_STATE);
+        final HttpContext context = conn.getContext();
+        final ClientConnState connState = (ClientConnState) context.getAttribute(CONN_STATE);
 
-        HttpResponse response = conn.getHttpResponse();
+        final HttpResponse response = conn.getHttpResponse();
         response.setParams(
                 new DefaultedHttpParams(response.getParams(), this.params));
 
-        HttpRequest request = connState.getRequest();
+        final HttpRequest request = connState.getRequest();
         try {
 
-            int statusCode = response.getStatusLine().getStatusCode();
+            final int statusCode = response.getStatusLine().getStatusCode();
             if (statusCode < HttpStatus.SC_OK) {
                 // 1xx intermediate response
                 if (statusCode == HttpStatus.SC_CONTINUE
@@ -318,7 +315,7 @@ public class AsyncNHttpClientHandler extends NHttpHandlerBase
                 this.httpProcessor.process(response, context);
                 processResponse(conn, connState);
             } else {
-                HttpEntity entity = response.getEntity();
+                final HttpEntity entity = response.getEntity();
                 if (entity != null) {
                     ConsumingNHttpEntity consumingEntity = this.execHandler.responseEntity(
                             response, context);
@@ -332,12 +329,12 @@ public class AsyncNHttpClientHandler extends NHttpHandlerBase
             }
 
 
-        } catch (IOException ex) {
+        } catch (final IOException ex) {
             shutdownConnection(conn, ex);
             if (this.eventListener != null) {
                 this.eventListener.fatalIOException(ex, conn);
             }
-        } catch (HttpException ex) {
+        } catch (final HttpException ex) {
             closeConnection(conn, ex);
             if (this.eventListener != null) {
                 this.eventListener.fatalProtocolException(ex, conn);
@@ -346,8 +343,8 @@ public class AsyncNHttpClientHandler extends NHttpHandlerBase
     }
 
     public void timeout(final NHttpClientConnection conn) {
-        HttpContext context = conn.getContext();
-        ClientConnState connState = (ClientConnState) context.getAttribute(CONN_STATE);
+        final HttpContext context = conn.getContext();
+        final ClientConnState connState = (ClientConnState) context.getAttribute(CONN_STATE);
 
         try {
 
@@ -356,7 +353,7 @@ public class AsyncNHttpClientHandler extends NHttpHandlerBase
                 return;
             }
 
-        } catch (IOException ex) {
+        } catch (final IOException ex) {
             shutdownConnection(conn, ex);
             if (this.eventListener != null) {
                 this.eventListener.fatalIOException(ex, conn);
@@ -369,7 +366,7 @@ public class AsyncNHttpClientHandler extends NHttpHandlerBase
     private void initialize(
             final NHttpClientConnection conn,
             final Object attachment) {
-        HttpContext context = conn.getContext();
+        final HttpContext context = conn.getContext();
 
         context.setAttribute(ExecutionContext.HTTP_CONNECTION, conn);
         this.execHandler.initalizeContext(context, attachment);
@@ -382,7 +379,7 @@ public class AsyncNHttpClientHandler extends NHttpHandlerBase
             final NHttpClientConnection conn,
             final ClientConnState connState) throws IOException {
 
-        int timeout = connState.getTimeout();
+        final int timeout = connState.getTimeout();
         conn.setSocketTimeout(timeout);
 
         conn.requestOutput();
@@ -393,7 +390,7 @@ public class AsyncNHttpClientHandler extends NHttpHandlerBase
             final NHttpClientConnection conn,
             final ClientConnState connState) throws IOException {
 
-        int timeout = connState.getTimeout();
+        final int timeout = connState.getTimeout();
         conn.setSocketTimeout(timeout);
 
         conn.resetOutput();
@@ -411,8 +408,8 @@ public class AsyncNHttpClientHandler extends NHttpHandlerBase
             conn.close();
         }
 
-        HttpContext context = conn.getContext();
-        HttpResponse response = connState.getResponse();
+        final HttpContext context = conn.getContext();
+        final HttpResponse response = connState.getResponse();
         this.execHandler.handleResponse(response, context);
         if (!this.connStrategy.keepAlive(response, context)) {
             conn.close();
@@ -471,7 +468,7 @@ public class AsyncNHttpClientHandler extends NHttpHandlerBase
             return this.outputState;
         }
 
-        public void setOutputState(int outputState) {
+        public void setOutputState(final int outputState) {
             this.outputState = outputState;
         }
 
@@ -495,7 +492,7 @@ public class AsyncNHttpClientHandler extends NHttpHandlerBase
             return this.timeout;
         }
 
-        public void setTimeout(int timeout) {
+        public void setTimeout(final int timeout) {
             this.timeout = timeout;
         }
 
diff --git a/httpcore-nio/src/main/java/org/apache/http/nio/protocol/AsyncNHttpServiceHandler.java b/httpcore-nio/src/main/java-deprecated/org/apache/http/nio/protocol/AsyncNHttpServiceHandler.java
similarity index 84%
rename from httpcore-nio/src/main/java/org/apache/http/nio/protocol/AsyncNHttpServiceHandler.java
rename to httpcore-nio/src/main/java-deprecated/org/apache/http/nio/protocol/AsyncNHttpServiceHandler.java
index 5b002ab..23c7f82 100644
--- a/httpcore-nio/src/main/java/org/apache/http/nio/protocol/AsyncNHttpServiceHandler.java
+++ b/httpcore-nio/src/main/java-deprecated/org/apache/http/nio/protocol/AsyncNHttpServiceHandler.java
@@ -60,6 +60,8 @@ import org.apache.http.protocol.ExecutionContext;
 import org.apache.http.protocol.HttpContext;
 import org.apache.http.protocol.HttpExpectationVerifier;
 import org.apache.http.protocol.HttpProcessor;
+import org.apache.http.util.Args;
+import org.apache.http.util.Asserts;
 import org.apache.http.util.EncodingUtils;
 
 /**
@@ -114,9 +116,7 @@ public class AsyncNHttpServiceHandler extends NHttpHandlerBase
             final ByteBufferAllocator allocator,
             final HttpParams params) {
         super(httpProcessor, connStrategy, allocator, params);
-        if (responseFactory == null) {
-            throw new IllegalArgumentException("Response factory may not be null");
-        }
+        Args.notNull(responseFactory, "Response factory");
         this.responseFactory = responseFactory;
     }
 
@@ -125,8 +125,7 @@ public class AsyncNHttpServiceHandler extends NHttpHandlerBase
             final HttpResponseFactory responseFactory,
             final ConnectionReuseStrategy connStrategy,
             final HttpParams params) {
-        this(httpProcessor, responseFactory, connStrategy,
-                new HeapByteBufferAllocator(), params);
+        this(httpProcessor, responseFactory, connStrategy, HeapByteBufferAllocator.INSTANCE, params);
     }
 
     public void setExpectationVerifier(final HttpExpectationVerifier expectationVerifier) {
@@ -138,9 +137,9 @@ public class AsyncNHttpServiceHandler extends NHttpHandlerBase
     }
 
     public void connected(final NHttpServerConnection conn) {
-        HttpContext context = conn.getContext();
+        final HttpContext context = conn.getContext();
 
-        ServerConnState connState = new ServerConnState();
+        final ServerConnState connState = new ServerConnState();
         context.setAttribute(CONN_STATE, connState);
         context.setAttribute(ExecutionContext.HTTP_CONNECTION, conn);
 
@@ -150,16 +149,16 @@ public class AsyncNHttpServiceHandler extends NHttpHandlerBase
     }
 
     public void requestReceived(final NHttpServerConnection conn) {
-        HttpContext context = conn.getContext();
+        final HttpContext context = conn.getContext();
 
-        ServerConnState connState = (ServerConnState) context.getAttribute(CONN_STATE);
+        final ServerConnState connState = (ServerConnState) context.getAttribute(CONN_STATE);
 
-        HttpRequest request = conn.getHttpRequest();
+        final HttpRequest request = conn.getHttpRequest();
         request.setParams(new DefaultedHttpParams(request.getParams(), this.params));
 
         connState.setRequest(request);
 
-        NHttpRequestHandler requestHandler = getRequestHandler(request);
+        final NHttpRequestHandler requestHandler = getRequestHandler(request);
         connState.setRequestHandler(requestHandler);
 
         ProtocolVersion ver = request.getRequestLine().getProtocolVersion();
@@ -173,7 +172,7 @@ public class AsyncNHttpServiceHandler extends NHttpHandlerBase
         try {
 
             if (request instanceof HttpEntityEnclosingRequest) {
-                HttpEntityEnclosingRequest entityRequest = (HttpEntityEnclosingRequest) request;
+                final HttpEntityEnclosingRequest entityRequest = (HttpEntityEnclosingRequest) request;
                 if (entityRequest.expectContinue()) {
                     response = this.responseFactory.newHttpResponse(
                             ver, HttpStatus.SC_CONTINUE, context);
@@ -183,7 +182,7 @@ public class AsyncNHttpServiceHandler extends NHttpHandlerBase
                     if (this.expectationVerifier != null) {
                         try {
                             this.expectationVerifier.verify(request, response, context);
-                        } catch (HttpException ex) {
+                        } catch (final HttpException ex) {
                             response = this.responseFactory.newHttpResponse(
                                     HttpVersion.HTTP_1_0,
                                     HttpStatus.SC_INTERNAL_SERVER_ERROR,
@@ -223,12 +222,12 @@ public class AsyncNHttpServiceHandler extends NHttpHandlerBase
                 processRequest(conn, request);
             }
 
-        } catch (IOException ex) {
+        } catch (final IOException ex) {
             shutdownConnection(conn, ex);
             if (this.eventListener != null) {
                 this.eventListener.fatalIOException(ex, conn);
             }
-        } catch (HttpException ex) {
+        } catch (final HttpException ex) {
             closeConnection(conn, ex);
             if (this.eventListener != null) {
                 this.eventListener.fatalProtocolException(ex, conn);
@@ -238,12 +237,12 @@ public class AsyncNHttpServiceHandler extends NHttpHandlerBase
     }
 
     public void closed(final NHttpServerConnection conn) {
-        HttpContext context = conn.getContext();
+        final HttpContext context = conn.getContext();
 
-        ServerConnState connState = (ServerConnState) context.getAttribute(CONN_STATE);
+        final ServerConnState connState = (ServerConnState) context.getAttribute(CONN_STATE);
         try {
             connState.reset();
-        } catch (IOException ex) {
+        } catch (final IOException ex) {
             if (this.eventListener != null) {
                 this.eventListener.fatalIOException(ex, conn);
             }
@@ -264,9 +263,9 @@ public class AsyncNHttpServiceHandler extends NHttpHandlerBase
             return;
         }
 
-        HttpContext context = conn.getContext();
+        final HttpContext context = conn.getContext();
         try {
-            HttpResponse response = this.responseFactory.newHttpResponse(
+            final HttpResponse response = this.responseFactory.newHttpResponse(
                     HttpVersion.HTTP_1_0, HttpStatus.SC_INTERNAL_SERVER_ERROR, context);
             response.setParams(
                     new DefaultedHttpParams(response.getParams(), this.params));
@@ -274,12 +273,12 @@ public class AsyncNHttpServiceHandler extends NHttpHandlerBase
             response.setEntity(null);
             sendResponse(conn, null, response);
 
-        } catch (IOException ex) {
+        } catch (final IOException ex) {
             shutdownConnection(conn, ex);
             if (this.eventListener != null) {
                 this.eventListener.fatalIOException(ex, conn);
             }
-        } catch (HttpException ex) {
+        } catch (final HttpException ex) {
             closeConnection(conn, ex);
             if (this.eventListener != null) {
                 this.eventListener.fatalProtocolException(ex, conn);
@@ -300,11 +299,11 @@ public class AsyncNHttpServiceHandler extends NHttpHandlerBase
     }
 
     public void inputReady(final NHttpServerConnection conn, final ContentDecoder decoder) {
-        HttpContext context = conn.getContext();
-        ServerConnState connState = (ServerConnState) context.getAttribute(CONN_STATE);
+        final HttpContext context = conn.getContext();
+        final ServerConnState connState = (ServerConnState) context.getAttribute(CONN_STATE);
 
-        HttpRequest request = connState.getRequest();
-        ConsumingNHttpEntity consumingEntity = connState.getConsumingEntity();
+        final HttpRequest request = connState.getRequest();
+        final ConsumingNHttpEntity consumingEntity = connState.getConsumingEntity();
 
         try {
 
@@ -314,12 +313,12 @@ public class AsyncNHttpServiceHandler extends NHttpHandlerBase
                 processRequest(conn, request);
             }
 
-        } catch (IOException ex) {
+        } catch (final IOException ex) {
             shutdownConnection(conn, ex);
             if (this.eventListener != null) {
                 this.eventListener.fatalIOException(ex, conn);
             }
-        } catch (HttpException ex) {
+        } catch (final HttpException ex) {
             closeConnection(conn, ex);
             if (this.eventListener != null) {
                 this.eventListener.fatalProtocolException(ex, conn);
@@ -328,25 +327,25 @@ public class AsyncNHttpServiceHandler extends NHttpHandlerBase
     }
 
     public void responseReady(final NHttpServerConnection conn) {
-        HttpContext context = conn.getContext();
-        ServerConnState connState = (ServerConnState) context.getAttribute(CONN_STATE);
+        final HttpContext context = conn.getContext();
+        final ServerConnState connState = (ServerConnState) context.getAttribute(CONN_STATE);
 
         if (connState.isHandled()) {
             return;
         }
 
-        HttpRequest request = connState.getRequest();
+        final HttpRequest request = connState.getRequest();
 
         try {
 
-            IOException ioex = connState.getIOException();
+            final IOException ioex = connState.getIOException();
             if (ioex != null) {
                 throw ioex;
             }
 
-            HttpException httpex = connState.getHttpException();
+            final HttpException httpex = connState.getHttpException();
             if (httpex != null) {
-                HttpResponse response = this.responseFactory.newHttpResponse(HttpVersion.HTTP_1_0,
+                final HttpResponse response = this.responseFactory.newHttpResponse(HttpVersion.HTTP_1_0,
                         HttpStatus.SC_INTERNAL_SERVER_ERROR, context);
                 response.setParams(
                         new DefaultedHttpParams(response.getParams(), this.params));
@@ -354,18 +353,18 @@ public class AsyncNHttpServiceHandler extends NHttpHandlerBase
                 connState.setResponse(response);
             }
 
-            HttpResponse response = connState.getResponse();
+            final HttpResponse response = connState.getResponse();
             if (response != null) {
                 connState.setHandled(true);
                 sendResponse(conn, request, response);
             }
 
-        } catch (IOException ex) {
+        } catch (final IOException ex) {
             shutdownConnection(conn, ex);
             if (this.eventListener != null) {
                 this.eventListener.fatalIOException(ex, conn);
             }
-        } catch (HttpException ex) {
+        } catch (final HttpException ex) {
             closeConnection(conn, ex);
             if (this.eventListener != null) {
                 this.eventListener.fatalProtocolException(ex, conn);
@@ -374,13 +373,13 @@ public class AsyncNHttpServiceHandler extends NHttpHandlerBase
     }
 
     public void outputReady(final NHttpServerConnection conn, final ContentEncoder encoder) {
-        HttpContext context = conn.getContext();
-        ServerConnState connState = (ServerConnState) context.getAttribute(CONN_STATE);
+        final HttpContext context = conn.getContext();
+        final ServerConnState connState = (ServerConnState) context.getAttribute(CONN_STATE);
 
-        HttpResponse response = conn.getHttpResponse();
+        final HttpResponse response = conn.getHttpResponse();
 
         try {
-            ProducingNHttpEntity entity = connState.getProducingEntity();
+            final ProducingNHttpEntity entity = connState.getProducingEntity();
             entity.produceContent(encoder, conn);
 
             if (encoder.isCompleted()) {
@@ -395,7 +394,7 @@ public class AsyncNHttpServiceHandler extends NHttpHandlerBase
                 responseComplete(response, context);
             }
 
-        } catch (IOException ex) {
+        } catch (final IOException ex) {
             shutdownConnection(conn, ex);
             if (this.eventListener != null) {
                 this.eventListener.fatalIOException(ex, conn);
@@ -414,8 +413,8 @@ public class AsyncNHttpServiceHandler extends NHttpHandlerBase
         }
         response.setStatusCode(code);
 
-        byte[] msg = EncodingUtils.getAsciiBytes(ex.getMessage());
-        NByteArrayEntity entity = new NByteArrayEntity(msg);
+        final byte[] msg = EncodingUtils.getAsciiBytes(ex.getMessage());
+        final NByteArrayEntity entity = new NByteArrayEntity(msg);
         entity.setContentType("text/plain; charset=US-ASCII");
         response.setEntity(entity);
     }
@@ -427,8 +426,8 @@ public class AsyncNHttpServiceHandler extends NHttpHandlerBase
             final NHttpServerConnection conn,
             final HttpRequest request) throws IOException, HttpException {
 
-        HttpContext context = conn.getContext();
-        ServerConnState connState = (ServerConnState) context.getAttribute(CONN_STATE);
+        final HttpContext context = conn.getContext();
+        final ServerConnState connState = (ServerConnState) context.getAttribute(CONN_STATE);
 
         ProtocolVersion ver = request.getRequestLine().getProtocolVersion();
 
@@ -437,13 +436,13 @@ public class AsyncNHttpServiceHandler extends NHttpHandlerBase
             ver = HttpVersion.HTTP_1_1;
         }
 
-        NHttpResponseTrigger trigger = new ResponseTriggerImpl(connState, conn);
+        final NHttpResponseTrigger trigger = new ResponseTriggerImpl(connState, conn);
         try {
             this.httpProcessor.process(request, context);
 
-            NHttpRequestHandler handler = connState.getRequestHandler();
+            final NHttpRequestHandler handler = connState.getRequestHandler();
             if (handler != null) {
-                HttpResponse response = this.responseFactory.newHttpResponse(
+                final HttpResponse response = this.responseFactory.newHttpResponse(
                         ver, HttpStatus.SC_OK, context);
                 response.setParams(
                         new DefaultedHttpParams(response.getParams(), this.params));
@@ -454,14 +453,14 @@ public class AsyncNHttpServiceHandler extends NHttpHandlerBase
                         trigger,
                         context);
             } else {
-                HttpResponse response = this.responseFactory.newHttpResponse(ver,
+                final HttpResponse response = this.responseFactory.newHttpResponse(ver,
                         HttpStatus.SC_NOT_IMPLEMENTED, context);
                 response.setParams(
                         new DefaultedHttpParams(response.getParams(), this.params));
                 trigger.submitResponse(response);
             }
 
-        } catch (HttpException ex) {
+        } catch (final HttpException ex) {
             trigger.handleException(ex);
         }
     }
@@ -470,8 +469,8 @@ public class AsyncNHttpServiceHandler extends NHttpHandlerBase
             final NHttpServerConnection conn,
             final HttpRequest request,
             final HttpResponse response) throws IOException, HttpException {
-        HttpContext context = conn.getContext();
-        ServerConnState connState = (ServerConnState) context.getAttribute(CONN_STATE);
+        final HttpContext context = conn.getContext();
+        final ServerConnState connState = (ServerConnState) context.getAttribute(CONN_STATE);
 
         // Now that a response is ready, we can cleanup the listener for the request.
         connState.finishInput();
@@ -485,7 +484,7 @@ public class AsyncNHttpServiceHandler extends NHttpHandlerBase
             response.setEntity(null);
         }
 
-        HttpEntity entity = response.getEntity();
+        final HttpEntity entity = response.getEntity();
         if (entity != null) {
             if (entity instanceof ProducingNHttpEntity) {
                 connState.setProducingEntity((ProducingNHttpEntity) entity);
@@ -514,13 +513,13 @@ public class AsyncNHttpServiceHandler extends NHttpHandlerBase
      * response. If there is an entity, it will be called after the entity has
      * completed.
      */
-    protected void responseComplete(HttpResponse response, HttpContext context) {
+    protected void responseComplete(final HttpResponse response, final HttpContext context) {
     }
 
-    private NHttpRequestHandler getRequestHandler(HttpRequest request) {
+    private NHttpRequestHandler getRequestHandler(final HttpRequest request) {
         NHttpRequestHandler handler = null;
          if (this.handlerResolver != null) {
-             String requestURI = request.getRequestLine().getUri();
+             final String requestURI = request.getRequestLine().getUri();
              handler = this.handlerResolver.lookup(requestURI);
          }
 
@@ -639,7 +638,7 @@ public class AsyncNHttpServiceHandler extends NHttpHandlerBase
             return this.handled;
         }
 
-        public void setHandled(boolean handled) {
+        public void setHandled(final boolean handled) {
             this.handled = handled;
         }
 
@@ -659,30 +658,22 @@ public class AsyncNHttpServiceHandler extends NHttpHandlerBase
         }
 
         public void submitResponse(final HttpResponse response) {
-            if (response == null) {
-                throw new IllegalArgumentException("Response may not be null");
-            }
-            if (this.triggered) {
-                throw new IllegalStateException("Response already triggered");
-            }
+            Args.notNull(response, "Response");
+            Asserts.check(!this.triggered, "Response already triggered");
             this.triggered = true;
             this.connState.setResponse(response);
             this.iocontrol.requestOutput();
         }
 
         public void handleException(final HttpException ex) {
-            if (this.triggered) {
-                throw new IllegalStateException("Response already triggered");
-            }
+            Asserts.check(!this.triggered, "Response already triggered");
             this.triggered = true;
             this.connState.setHttpException(ex);
             this.iocontrol.requestOutput();
         }
 
         public void handleException(final IOException ex) {
-            if (this.triggered) {
-                throw new IllegalStateException("Response already triggered");
-            }
+            Asserts.check(!this.triggered, "Response already triggered");
             this.triggered = true;
             this.connState.setIOException(ex);
             this.iocontrol.requestOutput();
diff --git a/httpcore-nio/src/main/java/org/apache/http/nio/protocol/BasicAsyncRequestExecutionHandler.java b/httpcore-nio/src/main/java-deprecated/org/apache/http/nio/protocol/BasicAsyncRequestExecutionHandler.java
similarity index 81%
copy from httpcore-nio/src/main/java/org/apache/http/nio/protocol/BasicAsyncRequestExecutionHandler.java
copy to httpcore-nio/src/main/java-deprecated/org/apache/http/nio/protocol/BasicAsyncRequestExecutionHandler.java
index 751fed1..eaeb87f 100644
--- a/httpcore-nio/src/main/java/org/apache/http/nio/protocol/BasicAsyncRequestExecutionHandler.java
+++ b/httpcore-nio/src/main/java-deprecated/org/apache/http/nio/protocol/BasicAsyncRequestExecutionHandler.java
@@ -40,10 +40,10 @@ import org.apache.http.concurrent.FutureCallback;
 import org.apache.http.nio.ContentDecoder;
 import org.apache.http.nio.ContentEncoder;
 import org.apache.http.nio.IOControl;
-import org.apache.http.params.DefaultedHttpParams;
 import org.apache.http.params.HttpParams;
 import org.apache.http.protocol.HttpContext;
 import org.apache.http.protocol.HttpProcessor;
+import org.apache.http.util.Args;
 
 /**
  * Basic implementation of {@link HttpAsyncRequestExecutionHandler} that executes
@@ -51,7 +51,10 @@ import org.apache.http.protocol.HttpProcessor;
  *
  * @param <T> the result type of request execution.
  * @since 4.2
+ *
+ * @deprecated (4.3) use {@link BasicAsyncClientExchangeHandler}.
  */
+ at Deprecated
 public class BasicAsyncRequestExecutionHandler<T> implements HttpAsyncRequestExecutionHandler<T> {
 
     private final HttpAsyncRequestProducer requestProducer;
@@ -60,7 +63,6 @@ public class BasicAsyncRequestExecutionHandler<T> implements HttpAsyncRequestExe
     private final HttpContext localContext;
     private final HttpProcessor httppocessor;
     private final ConnectionReuseStrategy reuseStrategy;
-    private final HttpParams params;
 
     private volatile boolean requestSent;
 
@@ -73,31 +75,18 @@ public class BasicAsyncRequestExecutionHandler<T> implements HttpAsyncRequestExe
             final ConnectionReuseStrategy reuseStrategy,
             final HttpParams params) {
         super();
-        if (requestProducer == null) {
-            throw new IllegalArgumentException("Request producer may not be null");
-        }
-        if (responseConsumer == null) {
-            throw new IllegalArgumentException("Response consumer may not be null");
-        }
-        if (localContext == null) {
-            throw new IllegalArgumentException("HTTP context may not be null");
-        }
-        if (httppocessor == null) {
-            throw new IllegalArgumentException("HTTP processor may not be null");
-        }
-        if (reuseStrategy == null) {
-            throw new IllegalArgumentException("Connection reuse strategy may not be null");
-        }
-        if (params == null) {
-            throw new IllegalArgumentException("HTTP parameters may not be null");
-        }
+        Args.notNull(requestProducer, "Request producer");
+        Args.notNull(responseConsumer, "Response consumer");
+        Args.notNull(localContext, "HTTP context");
+        Args.notNull(httppocessor, "HTTP processor");
+        Args.notNull(reuseStrategy, "Connection reuse strategy");
+        Args.notNull(params, "HTTP parameters");
         this.requestProducer = requestProducer;
         this.responseConsumer = responseConsumer;
         this.future = new BasicFuture<T>(callback);
         this.localContext = localContext;
         this.httppocessor = httppocessor;
         this.reuseStrategy = reuseStrategy;
-        this.params = params;
     }
 
     public BasicAsyncRequestExecutionHandler(
@@ -117,11 +106,11 @@ public class BasicAsyncRequestExecutionHandler<T> implements HttpAsyncRequestExe
     private void releaseResources() {
         try {
             this.responseConsumer.close();
-        } catch (IOException ex) {
+        } catch (final IOException ex) {
         }
         try {
             this.requestProducer.close();
-        } catch (IOException ex) {
+        } catch (final IOException ex) {
         }
     }
 
@@ -137,9 +126,7 @@ public class BasicAsyncRequestExecutionHandler<T> implements HttpAsyncRequestExe
     }
 
     public HttpRequest generateRequest() throws IOException, HttpException {
-        HttpRequest request = this.requestProducer.generateRequest();
-        request.setParams(new DefaultedHttpParams(request.getParams(), this.params));
-        return request;
+        return this.requestProducer.generateRequest();
     }
 
     public void produceContent(
@@ -160,7 +147,6 @@ public class BasicAsyncRequestExecutionHandler<T> implements HttpAsyncRequestExe
     }
 
     public void responseReceived(final HttpResponse response) throws IOException, HttpException {
-        response.setParams(new DefaultedHttpParams(response.getParams(), this.params));
         this.responseConsumer.responseReceived(response);
     }
 
@@ -186,11 +172,11 @@ public class BasicAsyncRequestExecutionHandler<T> implements HttpAsyncRequestExe
 
     public boolean cancel() {
         try {
-            boolean cancelled = this.responseConsumer.cancel();
+            final boolean cancelled = this.responseConsumer.cancel();
             this.future.cancel();
             releaseResources();
             return cancelled;
-        } catch (RuntimeException ex) {
+        } catch (final RuntimeException ex) {
             failed(ex);
             throw ex;
         }
@@ -199,15 +185,15 @@ public class BasicAsyncRequestExecutionHandler<T> implements HttpAsyncRequestExe
     public void responseCompleted(final HttpContext context) {
         try {
             this.responseConsumer.responseCompleted(context);
-            T result = this.responseConsumer.getResult();
-            Exception ex = this.responseConsumer.getException();
+            final T result = this.responseConsumer.getResult();
+            final Exception ex = this.responseConsumer.getException();
             if (ex == null) {
                 this.future.completed(result);
             } else {
                 this.future.failed(ex);
             }
             releaseResources();
-        } catch (RuntimeException ex) {
+        } catch (final RuntimeException ex) {
             failed(ex);
             throw ex;
         }
diff --git a/httpcore-nio/src/main/java/org/apache/http/nio/protocol/BufferingHttpClientHandler.java b/httpcore-nio/src/main/java-deprecated/org/apache/http/nio/protocol/BufferingHttpClientHandler.java
similarity index 94%
rename from httpcore-nio/src/main/java/org/apache/http/nio/protocol/BufferingHttpClientHandler.java
rename to httpcore-nio/src/main/java-deprecated/org/apache/http/nio/protocol/BufferingHttpClientHandler.java
index 9babace..7e23f89 100644
--- a/httpcore-nio/src/main/java/org/apache/http/nio/protocol/BufferingHttpClientHandler.java
+++ b/httpcore-nio/src/main/java-deprecated/org/apache/http/nio/protocol/BufferingHttpClientHandler.java
@@ -28,11 +28,8 @@
 package org.apache.http.nio.protocol;
 
 import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
 
 import org.apache.http.ConnectionReuseStrategy;
-import org.apache.http.HttpEntity;
 import org.apache.http.HttpException;
 import org.apache.http.HttpRequest;
 import org.apache.http.HttpResponse;
@@ -58,9 +55,9 @@ import org.apache.http.protocol.HttpProcessor;
  * take place the main I/O thread and therefore
  * {@link HttpRequestExecutionHandler} methods should not block indefinitely.
  * <p>
- * When using this protocol handler {@link HttpEntity}'s content can be
- * generated / consumed using standard {@link InputStream}/{@link OutputStream}
- * classes.
+ * When using this protocol handler {@link org.apache.http.HttpEntity}'s content
+ * can be generated / consumed using standard {@link java.io.InputStream}/
+ * {@link java.io.OutputStream} classes.
  * <p>
  * IMPORTANT: This protocol handler should be used only when dealing with HTTP
  * messages that are known to be limited in length.
@@ -95,7 +92,7 @@ public class BufferingHttpClientHandler implements NHttpClientHandler {
             final ConnectionReuseStrategy connStrategy,
             final HttpParams params) {
         this(httpProcessor, execHandler, connStrategy,
-                new HeapByteBufferAllocator(), params);
+                HeapByteBufferAllocator.INSTANCE, params);
     }
 
     public void setEventListener(final EventListener eventListener) {
@@ -163,7 +160,7 @@ public class BufferingHttpClientHandler implements NHttpClientHandler {
                 final HttpContext context) throws IOException {
             return new BufferingNHttpEntity(
                     response.getEntity(),
-                    new HeapByteBufferAllocator());
+                    HeapByteBufferAllocator.INSTANCE);
         }
 
         public void handleResponse(
diff --git a/httpcore-nio/src/main/java/org/apache/http/nio/protocol/BufferingHttpServiceHandler.java b/httpcore-nio/src/main/java-deprecated/org/apache/http/nio/protocol/BufferingHttpServiceHandler.java
similarity index 93%
rename from httpcore-nio/src/main/java/org/apache/http/nio/protocol/BufferingHttpServiceHandler.java
rename to httpcore-nio/src/main/java-deprecated/org/apache/http/nio/protocol/BufferingHttpServiceHandler.java
index 1df41e2..25e95cf 100644
--- a/httpcore-nio/src/main/java/org/apache/http/nio/protocol/BufferingHttpServiceHandler.java
+++ b/httpcore-nio/src/main/java-deprecated/org/apache/http/nio/protocol/BufferingHttpServiceHandler.java
@@ -28,11 +28,8 @@
 package org.apache.http.nio.protocol;
 
 import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
 
 import org.apache.http.ConnectionReuseStrategy;
-import org.apache.http.HttpEntity;
 import org.apache.http.HttpEntityEnclosingRequest;
 import org.apache.http.HttpException;
 import org.apache.http.HttpRequest;
@@ -63,9 +60,9 @@ import org.apache.http.protocol.HttpRequestHandlerResolver;
  * main I/O thread and therefore individual HTTP request handlers should not
  * block indefinitely.
  * <p>
- * When using this protocol handler {@link HttpEntity}'s content can be
- * generated / consumed using standard {@link InputStream}/{@link OutputStream}
- * classes.
+ * When using this protocol handler {@link org.apache.http.HttpEntity}'s content
+ * can be generated / consumed using standard {@link java.io.InputStream}/
+ * {@link java.io.OutputStream} classes.
  * <p>
  * IMPORTANT: This protocol handler should be used only when dealing with HTTP
  * messages that are known to be limited in length.
@@ -104,7 +101,7 @@ public class BufferingHttpServiceHandler implements NHttpServiceHandler {
             final ConnectionReuseStrategy connStrategy,
             final HttpParams params) {
         this(httpProcessor, responseFactory, connStrategy,
-                new HeapByteBufferAllocator(), params);
+                HeapByteBufferAllocator.INSTANCE, params);
     }
 
     public void setEventListener(final EventListener eventListener) {
@@ -151,14 +148,14 @@ public class BufferingHttpServiceHandler implements NHttpServiceHandler {
         this.asyncHandler.exception(conn, ioex);
     }
 
-    public void timeout(NHttpServerConnection conn) {
+    public void timeout(final NHttpServerConnection conn) {
         this.asyncHandler.timeout(conn);
     }
 
     class RequestHandlerResolverAdaptor implements NHttpRequestHandlerResolver {
 
         public NHttpRequestHandler lookup(final String requestURI) {
-            HttpRequestHandler handler = handlerResolver.lookup(requestURI);
+            final HttpRequestHandler handler = handlerResolver.lookup(requestURI);
             if (handler != null) {
                 return new RequestHandlerAdaptor(handler);
             } else {
@@ -182,7 +179,7 @@ public class BufferingHttpServiceHandler implements NHttpServiceHandler {
                 final HttpContext context) throws HttpException, IOException {
             return new BufferingNHttpEntity(
                     request.getEntity(),
-                    new HeapByteBufferAllocator());
+                    HeapByteBufferAllocator.INSTANCE);
         }
 
         @Override
diff --git a/httpcore-nio/src/main/java/org/apache/http/nio/protocol/EventListener.java b/httpcore-nio/src/main/java-deprecated/org/apache/http/nio/protocol/EventListener.java
similarity index 100%
rename from httpcore-nio/src/main/java/org/apache/http/nio/protocol/EventListener.java
rename to httpcore-nio/src/main/java-deprecated/org/apache/http/nio/protocol/EventListener.java
diff --git a/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncRequestExecutionHandler.java b/httpcore-nio/src/main/java-deprecated/org/apache/http/nio/protocol/HttpAsyncRequestExecutionHandler.java
similarity index 97%
rename from httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncRequestExecutionHandler.java
rename to httpcore-nio/src/main/java-deprecated/org/apache/http/nio/protocol/HttpAsyncRequestExecutionHandler.java
index 78c837c..5ea1710 100644
--- a/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncRequestExecutionHandler.java
+++ b/httpcore-nio/src/main/java-deprecated/org/apache/http/nio/protocol/HttpAsyncRequestExecutionHandler.java
@@ -39,7 +39,10 @@ import org.apache.http.protocol.HttpProcessor;
  *
  * @param <T> the result type of request execution.
  * @since 4.2
+ *
+ * @deprecated use {@link HttpAsyncClientExchangeHandler}
  */
+ at Deprecated
 public interface HttpAsyncRequestExecutionHandler<T>
     extends HttpAsyncRequestProducer, HttpAsyncResponseConsumer<T> {
 
diff --git a/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncRequestHandlerRegistry.java b/httpcore-nio/src/main/java-deprecated/org/apache/http/nio/protocol/HttpAsyncRequestHandlerRegistry.java
similarity index 93%
copy from httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncRequestHandlerRegistry.java
copy to httpcore-nio/src/main/java-deprecated/org/apache/http/nio/protocol/HttpAsyncRequestHandlerRegistry.java
index b4f804a..afe803e 100644
--- a/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncRequestHandlerRegistry.java
+++ b/httpcore-nio/src/main/java-deprecated/org/apache/http/nio/protocol/HttpAsyncRequestHandlerRegistry.java
@@ -47,8 +47,10 @@ import org.apache.http.protocol.UriPatternMatcher;
  * will be used to process the request with the specified request URI.
  *
  * @since 4.2
+ * @deprecated (4.3) use {@link UriHttpAsyncRequestHandlerMapper}
  */
 @ThreadSafe
+ at Deprecated
 public class HttpAsyncRequestHandlerRegistry implements HttpAsyncRequestHandlerResolver {
 
     private final UriPatternMatcher<HttpAsyncRequestHandler<?>> matcher;
@@ -58,7 +60,7 @@ public class HttpAsyncRequestHandlerRegistry implements HttpAsyncRequestHandlerR
     }
 
     /**
-     * Registers the given {@link NHttpRequestHandler} as a handler for URIs
+     * Registers the given {@link HttpAsyncRequestHandler} as a handler for URIs
      * matching the given pattern.
      *
      * @param pattern the pattern to register the handler for.
@@ -93,7 +95,7 @@ public class HttpAsyncRequestHandlerRegistry implements HttpAsyncRequestHandlerR
         return matcher.getObjects();
     }
 
-    public HttpAsyncRequestHandler<?> lookup(String requestURI) {
+    public HttpAsyncRequestHandler<?> lookup(final String requestURI) {
         return matcher.lookup(requestURI);
     }
 
diff --git a/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpRequestExecutionHandler.java b/httpcore-nio/src/main/java-deprecated/org/apache/http/nio/protocol/HttpRequestExecutionHandler.java
similarity index 97%
rename from httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpRequestExecutionHandler.java
rename to httpcore-nio/src/main/java-deprecated/org/apache/http/nio/protocol/HttpRequestExecutionHandler.java
index 350a670..31fc78e 100644
--- a/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpRequestExecutionHandler.java
+++ b/httpcore-nio/src/main/java-deprecated/org/apache/http/nio/protocol/HttpRequestExecutionHandler.java
@@ -31,7 +31,6 @@ import java.io.IOException;
 
 import org.apache.http.HttpRequest;
 import org.apache.http.HttpResponse;
-import org.apache.http.nio.reactor.ConnectingIOReactor;
 import org.apache.http.protocol.HttpContext;
 
 /**
@@ -55,7 +54,7 @@ public interface HttpRequestExecutionHandler {
      * made. The attachment may optionally contain some state information
      * required in order to correctly initialize the HTTP context.
      *
-     * @see ConnectingIOReactor#connect
+     * @see org.apache.http.nio.reactor.ConnectingIOReactor#connect
      *
      * @param context the actual HTTP context
      * @param attachment the object passed to the connecting I/O reactor
diff --git a/httpcore-nio/src/main/java/org/apache/http/nio/protocol/NHttpHandlerBase.java b/httpcore-nio/src/main/java-deprecated/org/apache/http/nio/protocol/NHttpHandlerBase.java
similarity index 85%
rename from httpcore-nio/src/main/java/org/apache/http/nio/protocol/NHttpHandlerBase.java
rename to httpcore-nio/src/main/java-deprecated/org/apache/http/nio/protocol/NHttpHandlerBase.java
index 473168a..9cc2fd0 100644
--- a/httpcore-nio/src/main/java/org/apache/http/nio/protocol/NHttpHandlerBase.java
+++ b/httpcore-nio/src/main/java-deprecated/org/apache/http/nio/protocol/NHttpHandlerBase.java
@@ -38,6 +38,7 @@ import org.apache.http.nio.NHttpConnection;
 import org.apache.http.nio.util.ByteBufferAllocator;
 import org.apache.http.params.HttpParams;
 import org.apache.http.protocol.HttpProcessor;
+import org.apache.http.util.Args;
 
 /**
  * @since 4.0
@@ -63,18 +64,10 @@ public abstract class NHttpHandlerBase {
             final ByteBufferAllocator allocator,
             final HttpParams params) {
         super();
-        if (httpProcessor == null) {
-            throw new IllegalArgumentException("HTTP processor may not be null.");
-        }
-        if (connStrategy == null) {
-            throw new IllegalArgumentException("Connection reuse strategy may not be null");
-        }
-        if (allocator == null) {
-            throw new IllegalArgumentException("ByteBuffer allocator may not be null");
-        }
-        if (params == null) {
-            throw new IllegalArgumentException("HTTP parameters may not be null");
-        }
+        Args.notNull(httpProcessor, "HTTP processor");
+        Args.notNull(connStrategy, "Connection reuse strategy");
+        Args.notNull(allocator, "ByteBuffer allocator");
+        Args.notNull(params, "HTTP parameters");
         this.httpProcessor = httpProcessor;
         this.connStrategy = connStrategy;
         this.allocator = allocator;
@@ -93,11 +86,11 @@ public abstract class NHttpHandlerBase {
         try {
             // Try to close it nicely
             conn.close();
-        } catch (IOException ex) {
+        } catch (final IOException ex) {
             try {
                 // Just shut the damn thing down
                 conn.shutdown();
-            } catch (IOException ignore) {
+            } catch (final IOException ignore) {
             }
         }
     }
@@ -105,7 +98,7 @@ public abstract class NHttpHandlerBase {
     protected void shutdownConnection(final NHttpConnection conn, final Throwable cause) {
         try {
             conn.shutdown();
-        } catch (IOException ignore) {
+        } catch (final IOException ignore) {
         }
     }
 
@@ -124,7 +117,7 @@ public abstract class NHttpHandlerBase {
             } else {
                 conn.shutdown();
             }
-        } catch (IOException ignore) {
+        } catch (final IOException ignore) {
         }
     }
 
@@ -135,7 +128,7 @@ public abstract class NHttpHandlerBase {
             return false;
         }
 
-        int status = response.getStatusLine().getStatusCode();
+        final int status = response.getStatusLine().getStatusCode();
         return status >= HttpStatus.SC_OK
             && status != HttpStatus.SC_NO_CONTENT
             && status != HttpStatus.SC_NOT_MODIFIED
diff --git a/httpcore-nio/src/main/java/org/apache/http/nio/protocol/NHttpRequestExecutionHandler.java b/httpcore-nio/src/main/java-deprecated/org/apache/http/nio/protocol/NHttpRequestExecutionHandler.java
similarity index 96%
rename from httpcore-nio/src/main/java/org/apache/http/nio/protocol/NHttpRequestExecutionHandler.java
rename to httpcore-nio/src/main/java-deprecated/org/apache/http/nio/protocol/NHttpRequestExecutionHandler.java
index 1f56897..cf3152e 100644
--- a/httpcore-nio/src/main/java/org/apache/http/nio/protocol/NHttpRequestExecutionHandler.java
+++ b/httpcore-nio/src/main/java-deprecated/org/apache/http/nio/protocol/NHttpRequestExecutionHandler.java
@@ -32,8 +32,6 @@ import java.io.IOException;
 import org.apache.http.HttpRequest;
 import org.apache.http.HttpResponse;
 import org.apache.http.nio.entity.ConsumingNHttpEntity;
-import org.apache.http.nio.entity.ProducingNHttpEntity;
-import org.apache.http.nio.reactor.ConnectingIOReactor;
 import org.apache.http.protocol.HttpContext;
 
 /**
@@ -61,7 +59,7 @@ public interface NHttpRequestExecutionHandler {
      * made. The attachment may optionally contain some state information
      * required in order to correctly initalize the HTTP context.
      *
-     * @see ConnectingIOReactor#connect
+     * @see org.apache.http.nio.reactor.ConnectingIOReactor#connect
      *
      * @param context the actual HTTP context
      * @param attachment the object passed to the connecting I/O reactor
@@ -77,7 +75,7 @@ public interface NHttpRequestExecutionHandler {
      * can be activated at a later point.
      * <p>
      * If the request has an entity, the entity <b>must</b> be an
-     * instance of {@link ProducingNHttpEntity}.
+     * instance of {@link org.apache.http.nio.entity.ProducingNHttpEntity}.
      *
      * @param context the actual HTTP context
      * @return an HTTP request to be sent or <code>null</null> if no
diff --git a/httpcore-nio/src/main/java/org/apache/http/nio/protocol/NHttpRequestHandler.java b/httpcore-nio/src/main/java-deprecated/org/apache/http/nio/protocol/NHttpRequestHandler.java
similarity index 100%
rename from httpcore-nio/src/main/java/org/apache/http/nio/protocol/NHttpRequestHandler.java
rename to httpcore-nio/src/main/java-deprecated/org/apache/http/nio/protocol/NHttpRequestHandler.java
diff --git a/httpcore-nio/src/main/java/org/apache/http/nio/protocol/NHttpRequestHandlerRegistry.java b/httpcore-nio/src/main/java-deprecated/org/apache/http/nio/protocol/NHttpRequestHandlerRegistry.java
similarity index 96%
rename from httpcore-nio/src/main/java/org/apache/http/nio/protocol/NHttpRequestHandlerRegistry.java
rename to httpcore-nio/src/main/java-deprecated/org/apache/http/nio/protocol/NHttpRequestHandlerRegistry.java
index bf84153..0f384de 100644
--- a/httpcore-nio/src/main/java/org/apache/http/nio/protocol/NHttpRequestHandlerRegistry.java
+++ b/httpcore-nio/src/main/java-deprecated/org/apache/http/nio/protocol/NHttpRequestHandlerRegistry.java
@@ -48,7 +48,7 @@ import org.apache.http.protocol.UriPatternMatcher;
  *
  * @since 4.0
  *
- * @deprecated (4.2) use {@link HttpAsyncRequestHandlerRegistry}
+ * @deprecated (4.2) use {@link UriHttpAsyncRequestHandlerMapper}
  */
 @Deprecated
 public class NHttpRequestHandlerRegistry implements NHttpRequestHandlerResolver {
@@ -97,7 +97,7 @@ public class NHttpRequestHandlerRegistry implements NHttpRequestHandlerResolver
         return matcher.getObjects();
     }
 
-    public NHttpRequestHandler lookup(String requestURI) {
+    public NHttpRequestHandler lookup(final String requestURI) {
         return matcher.lookup(requestURI);
     }
 
diff --git a/httpcore-nio/src/main/java/org/apache/http/nio/protocol/NHttpRequestHandlerResolver.java b/httpcore-nio/src/main/java-deprecated/org/apache/http/nio/protocol/NHttpRequestHandlerResolver.java
similarity index 100%
rename from httpcore-nio/src/main/java/org/apache/http/nio/protocol/NHttpRequestHandlerResolver.java
rename to httpcore-nio/src/main/java-deprecated/org/apache/http/nio/protocol/NHttpRequestHandlerResolver.java
diff --git a/httpcore-nio/src/main/java/org/apache/http/nio/protocol/NHttpResponseTrigger.java b/httpcore-nio/src/main/java-deprecated/org/apache/http/nio/protocol/NHttpResponseTrigger.java
similarity index 100%
rename from httpcore-nio/src/main/java/org/apache/http/nio/protocol/NHttpResponseTrigger.java
rename to httpcore-nio/src/main/java-deprecated/org/apache/http/nio/protocol/NHttpResponseTrigger.java
diff --git a/httpcore-nio/src/main/java/org/apache/http/nio/protocol/NullNHttpEntity.java b/httpcore-nio/src/main/java-deprecated/org/apache/http/nio/protocol/NullNHttpEntity.java
similarity index 93%
rename from httpcore-nio/src/main/java/org/apache/http/nio/protocol/NullNHttpEntity.java
rename to httpcore-nio/src/main/java-deprecated/org/apache/http/nio/protocol/NullNHttpEntity.java
index b961eed..10abc0a 100644
--- a/httpcore-nio/src/main/java/org/apache/http/nio/protocol/NullNHttpEntity.java
+++ b/httpcore-nio/src/main/java-deprecated/org/apache/http/nio/protocol/NullNHttpEntity.java
@@ -62,15 +62,10 @@ class NullNHttpEntity extends HttpEntityWrapper implements ConsumingNHttpEntity
     }
 
     @Override
-    public void writeTo(OutputStream out) throws IOException, UnsupportedOperationException {
+    public void writeTo(final OutputStream out) throws IOException, UnsupportedOperationException {
         throw new UnsupportedOperationException("Does not support blocking methods");
     }
 
-    @Override
-    public void consumeContent() throws IOException {
-        finish();
-    }
-
     public void consumeContent(
             final ContentDecoder decoder,
             final IOControl ioctrl) throws IOException {
diff --git a/httpcore-nio/src/main/java/org/apache/http/nio/protocol/SimpleNHttpRequestHandler.java b/httpcore-nio/src/main/java-deprecated/org/apache/http/nio/protocol/SimpleNHttpRequestHandler.java
similarity index 100%
rename from httpcore-nio/src/main/java/org/apache/http/nio/protocol/SimpleNHttpRequestHandler.java
rename to httpcore-nio/src/main/java-deprecated/org/apache/http/nio/protocol/SimpleNHttpRequestHandler.java
diff --git a/httpcore-nio/src/main/java/org/apache/http/nio/protocol/ThrottlingHttpClientHandler.java b/httpcore-nio/src/main/java-deprecated/org/apache/http/nio/protocol/ThrottlingHttpClientHandler.java
similarity index 86%
rename from httpcore-nio/src/main/java/org/apache/http/nio/protocol/ThrottlingHttpClientHandler.java
rename to httpcore-nio/src/main/java-deprecated/org/apache/http/nio/protocol/ThrottlingHttpClientHandler.java
index d7270fb..bd5786d 100644
--- a/httpcore-nio/src/main/java/org/apache/http/nio/protocol/ThrottlingHttpClientHandler.java
+++ b/httpcore-nio/src/main/java-deprecated/org/apache/http/nio/protocol/ThrottlingHttpClientHandler.java
@@ -54,12 +54,13 @@ import org.apache.http.nio.util.ContentOutputBuffer;
 import org.apache.http.nio.util.DirectByteBufferAllocator;
 import org.apache.http.nio.util.SharedInputBuffer;
 import org.apache.http.nio.util.SharedOutputBuffer;
-import org.apache.http.params.HttpParams;
 import org.apache.http.params.CoreProtocolPNames;
 import org.apache.http.params.DefaultedHttpParams;
+import org.apache.http.params.HttpParams;
 import org.apache.http.protocol.ExecutionContext;
 import org.apache.http.protocol.HttpContext;
 import org.apache.http.protocol.HttpProcessor;
+import org.apache.http.util.Args;
 
 /**
  * Client protocol handler implementation that provide compatibility with
@@ -114,12 +115,8 @@ public class ThrottlingHttpClientHandler extends NHttpHandlerBase
             final Executor executor,
             final HttpParams params) {
         super(httpProcessor, connStrategy, allocator, params);
-        if (execHandler == null) {
-            throw new IllegalArgumentException("HTTP request execution handler may not be null.");
-        }
-        if (executor == null) {
-            throw new IllegalArgumentException("Executor may not be null");
-        }
+        Args.notNull(execHandler, "HTTP request execution handler");
+        Args.notNull(executor, "Executor");
         this.execHandler = execHandler;
         this.executor = executor;
         this.bufsize = this.params.getIntParameter(NIOReactorPNames.CONTENT_BUFFER_SIZE, 20480);
@@ -132,15 +129,15 @@ public class ThrottlingHttpClientHandler extends NHttpHandlerBase
             final Executor executor,
             final HttpParams params) {
         this(httpProcessor, execHandler, connStrategy,
-                new DirectByteBufferAllocator(), executor, params);
+                DirectByteBufferAllocator.INSTANCE, executor, params);
     }
 
     public void connected(final NHttpClientConnection conn, final Object attachment) {
-        HttpContext context = conn.getContext();
+        final HttpContext context = conn.getContext();
 
         initialize(conn, attachment);
 
-        ClientConnState connState = new ClientConnState(this.bufsize, conn, this.allocator);
+        final ClientConnState connState = new ClientConnState(this.bufsize, conn, this.allocator);
         context.setAttribute(CONN_STATE, connState);
 
         if (this.eventListener != null) {
@@ -151,8 +148,8 @@ public class ThrottlingHttpClientHandler extends NHttpHandlerBase
     }
 
     public void closed(final NHttpClientConnection conn) {
-        HttpContext context = conn.getContext();
-        ClientConnState connState = (ClientConnState) context.getAttribute(CONN_STATE);
+        final HttpContext context = conn.getContext();
+        final ClientConnState connState = (ClientConnState) context.getAttribute(CONN_STATE);
 
         if (connState != null) {
             synchronized (connState) {
@@ -183,9 +180,9 @@ public class ThrottlingHttpClientHandler extends NHttpHandlerBase
 
 
     public void requestReady(final NHttpClientConnection conn) {
-        HttpContext context = conn.getContext();
+        final HttpContext context = conn.getContext();
 
-        ClientConnState connState = (ClientConnState) context.getAttribute(CONN_STATE);
+        final ClientConnState connState = (ClientConnState) context.getAttribute(CONN_STATE);
 
         try {
 
@@ -194,7 +191,7 @@ public class ThrottlingHttpClientHandler extends NHttpHandlerBase
                     return;
                 }
 
-                HttpRequest request = this.execHandler.submitRequest(context);
+                final HttpRequest request = this.execHandler.submitRequest(context);
                 if (request == null) {
                     return;
                 }
@@ -229,12 +226,12 @@ public class ThrottlingHttpClientHandler extends NHttpHandlerBase
                 connState.notifyAll();
             }
 
-        } catch (IOException ex) {
+        } catch (final IOException ex) {
             shutdownConnection(conn, ex);
             if (this.eventListener != null) {
                 this.eventListener.fatalIOException(ex, conn);
             }
-        } catch (HttpException ex) {
+        } catch (final HttpException ex) {
             closeConnection(conn, ex);
             if (this.eventListener != null) {
                 this.eventListener.fatalProtocolException(ex, conn);
@@ -243,9 +240,9 @@ public class ThrottlingHttpClientHandler extends NHttpHandlerBase
     }
 
     public void outputReady(final NHttpClientConnection conn, final ContentEncoder encoder) {
-        HttpContext context = conn.getContext();
+        final HttpContext context = conn.getContext();
 
-        ClientConnState connState = (ClientConnState) context.getAttribute(CONN_STATE);
+        final ClientConnState connState = (ClientConnState) context.getAttribute(CONN_STATE);
 
         try {
 
@@ -254,7 +251,7 @@ public class ThrottlingHttpClientHandler extends NHttpHandlerBase
                     conn.suspendOutput();
                     return;
                 }
-                ContentOutputBuffer buffer = connState.getOutbuffer();
+                final ContentOutputBuffer buffer = connState.getOutbuffer();
                 buffer.produceContent(encoder);
                 if (encoder.isCompleted()) {
                     connState.setInputState(ClientConnState.REQUEST_BODY_DONE);
@@ -265,7 +262,7 @@ public class ThrottlingHttpClientHandler extends NHttpHandlerBase
                 connState.notifyAll();
             }
 
-        } catch (IOException ex) {
+        } catch (final IOException ex) {
             shutdownConnection(conn, ex);
             if (this.eventListener != null) {
                 this.eventListener.fatalIOException(ex, conn);
@@ -274,19 +271,19 @@ public class ThrottlingHttpClientHandler extends NHttpHandlerBase
     }
 
     public void responseReceived(final NHttpClientConnection conn) {
-        HttpContext context = conn.getContext();
-        ClientConnState connState = (ClientConnState) context.getAttribute(CONN_STATE);
+        final HttpContext context = conn.getContext();
+        final ClientConnState connState = (ClientConnState) context.getAttribute(CONN_STATE);
 
         try {
 
             synchronized (connState) {
-                HttpResponse response = conn.getHttpResponse();
+                final HttpResponse response = conn.getHttpResponse();
                 response.setParams(
                         new DefaultedHttpParams(response.getParams(), this.params));
 
-                HttpRequest request = connState.getRequest();
+                final HttpRequest request = connState.getRequest();
 
-                int statusCode = response.getStatusLine().getStatusCode();
+                final int statusCode = response.getStatusLine().getStatusCode();
                 if (statusCode < HttpStatus.SC_OK) {
                     // 1xx intermediate response
                     if (statusCode == HttpStatus.SC_CONTINUE
@@ -300,7 +297,7 @@ public class ThrottlingHttpClientHandler extends NHttpHandlerBase
                     connState.setInputState(ClientConnState.RESPONSE_RECEIVED);
 
                     if (connState.getOutputState() == ClientConnState.EXPECT_CONTINUE) {
-                        int timeout = connState.getTimeout();
+                        final int timeout = connState.getTimeout();
                         conn.setSocketTimeout(timeout);
                         conn.resetOutput();
                     }
@@ -331,12 +328,12 @@ public class ThrottlingHttpClientHandler extends NHttpHandlerBase
                 connState.notifyAll();
             }
 
-        } catch (IOException ex) {
+        } catch (final IOException ex) {
             shutdownConnection(conn, ex);
             if (this.eventListener != null) {
                 this.eventListener.fatalIOException(ex, conn);
             }
-        } catch (HttpException ex) {
+        } catch (final HttpException ex) {
             closeConnection(conn, ex);
             if (this.eventListener != null) {
                 this.eventListener.fatalProtocolException(ex, conn);
@@ -345,14 +342,14 @@ public class ThrottlingHttpClientHandler extends NHttpHandlerBase
     }
 
     public void inputReady(final NHttpClientConnection conn, final ContentDecoder decoder) {
-        HttpContext context = conn.getContext();
+        final HttpContext context = conn.getContext();
 
-        ClientConnState connState = (ClientConnState) context.getAttribute(CONN_STATE);
+        final ClientConnState connState = (ClientConnState) context.getAttribute(CONN_STATE);
         try {
 
             synchronized (connState) {
-                HttpResponse response = connState.getResponse();
-                ContentInputBuffer buffer = connState.getInbuffer();
+                final HttpResponse response = connState.getResponse();
+                final ContentInputBuffer buffer = connState.getInbuffer();
 
                 buffer.consumeContent(decoder);
                 if (decoder.isCompleted()) {
@@ -368,7 +365,7 @@ public class ThrottlingHttpClientHandler extends NHttpHandlerBase
                 connState.notifyAll();
             }
 
-        } catch (IOException ex) {
+        } catch (final IOException ex) {
             shutdownConnection(conn, ex);
             if (this.eventListener != null) {
                 this.eventListener.fatalIOException(ex, conn);
@@ -377,8 +374,8 @@ public class ThrottlingHttpClientHandler extends NHttpHandlerBase
     }
 
     public void timeout(final NHttpClientConnection conn) {
-        HttpContext context = conn.getContext();
-        ClientConnState connState = (ClientConnState) context.getAttribute(CONN_STATE);
+        final HttpContext context = conn.getContext();
+        final ClientConnState connState = (ClientConnState) context.getAttribute(CONN_STATE);
 
         try {
 
@@ -392,7 +389,7 @@ public class ThrottlingHttpClientHandler extends NHttpHandlerBase
                 }
             }
 
-        } catch (IOException ex) {
+        } catch (final IOException ex) {
             shutdownConnection(conn, ex);
             if (this.eventListener != null) {
                 this.eventListener.fatalIOException(ex, conn);
@@ -405,7 +402,7 @@ public class ThrottlingHttpClientHandler extends NHttpHandlerBase
     private void initialize(
             final NHttpClientConnection conn,
             final Object attachment) {
-        HttpContext context = conn.getContext();
+        final HttpContext context = conn.getContext();
 
         context.setAttribute(ExecutionContext.HTTP_CONNECTION, conn);
         this.execHandler.initalizeContext(context, attachment);
@@ -415,9 +412,9 @@ public class ThrottlingHttpClientHandler extends NHttpHandlerBase
             final NHttpClientConnection conn,
             final ClientConnState connState) throws IOException {
 
-        HttpRequest request = connState.getRequest();
+        final HttpRequest request = connState.getRequest();
 
-        int timeout = connState.getTimeout();
+        final int timeout = connState.getTimeout();
         conn.setSocketTimeout(timeout);
 
         sendRequestBody(
@@ -433,7 +430,7 @@ public class ThrottlingHttpClientHandler extends NHttpHandlerBase
             final HttpEntityEnclosingRequest request,
             final ClientConnState connState,
             final NHttpClientConnection conn) throws IOException {
-        HttpEntity entity = request.getEntity();
+        final HttpEntity entity = request.getEntity();
         if (entity != null) {
 
             this.executor.execute(new Runnable() {
@@ -446,7 +443,7 @@ public class ThrottlingHttpClientHandler extends NHttpHandlerBase
                         synchronized (connState) {
                             try {
                                 for (;;) {
-                                    int currentState = connState.getOutputState();
+                                    final int currentState = connState.getOutputState();
                                     if (!connState.isWorkerRunning()) {
                                         break;
                                     }
@@ -455,15 +452,15 @@ public class ThrottlingHttpClientHandler extends NHttpHandlerBase
                                     }
                                     connState.wait();
                                 }
-                            } catch (InterruptedException ex) {
+                            } catch (final InterruptedException ex) {
                                 connState.shutdown();
                                 return;
                             }
                             connState.setWorkerRunning(true);
                         }
 
-                        HttpEntity entity = request.getEntity();
-                        OutputStream outstream = new ContentOutputStream(
+                        final HttpEntity entity = request.getEntity();
+                        final OutputStream outstream = new ContentOutputStream(
                                 connState.getOutbuffer());
                         entity.writeTo(outstream);
                         outstream.flush();
@@ -474,7 +471,7 @@ public class ThrottlingHttpClientHandler extends NHttpHandlerBase
                             connState.notifyAll();
                         }
 
-                    } catch (IOException ex) {
+                    } catch (final IOException ex) {
                         shutdownConnection(conn, ex);
                         if (eventListener != null) {
                             eventListener.fatalIOException(ex, conn);
@@ -503,7 +500,7 @@ public class ThrottlingHttpClientHandler extends NHttpHandlerBase
                     synchronized (connState) {
                         try {
                             for (;;) {
-                                int currentState = connState.getOutputState();
+                                final int currentState = connState.getOutputState();
                                 if (!connState.isWorkerRunning()) {
                                     break;
                                 }
@@ -512,7 +509,7 @@ public class ThrottlingHttpClientHandler extends NHttpHandlerBase
                                 }
                                 connState.wait();
                             }
-                        } catch (InterruptedException ex) {
+                        } catch (final InterruptedException ex) {
                             connState.shutdown();
                             return;
                         }
@@ -525,7 +522,7 @@ public class ThrottlingHttpClientHandler extends NHttpHandlerBase
 
                         try {
                             for (;;) {
-                                int currentState = connState.getInputState();
+                                final int currentState = connState.getInputState();
                                 if (currentState == ClientConnState.RESPONSE_DONE) {
                                     break;
                                 }
@@ -534,7 +531,7 @@ public class ThrottlingHttpClientHandler extends NHttpHandlerBase
                                 }
                                 connState.wait();
                             }
-                        } catch (InterruptedException ex) {
+                        } catch (final InterruptedException ex) {
                             connState.shutdown();
                         }
 
@@ -547,7 +544,7 @@ public class ThrottlingHttpClientHandler extends NHttpHandlerBase
                         connState.notifyAll();
                     }
 
-                } catch (IOException ex) {
+                } catch (final IOException ex) {
                     shutdownConnection(conn, ex);
                     if (eventListener != null) {
                         eventListener.fatalIOException(ex, conn);
@@ -586,7 +583,7 @@ public class ThrottlingHttpClientHandler extends NHttpHandlerBase
         private volatile boolean workerRunning;
 
         public ClientConnState(
-                int bufsize,
+                final int bufsize,
                 final IOControl ioControl,
                 final ByteBufferAllocator allocator) {
             super();
@@ -608,7 +605,7 @@ public class ThrottlingHttpClientHandler extends NHttpHandlerBase
             return this.inputState;
         }
 
-        public void setInputState(int inputState) {
+        public void setInputState(final int inputState) {
             this.inputState = inputState;
         }
 
@@ -616,7 +613,7 @@ public class ThrottlingHttpClientHandler extends NHttpHandlerBase
             return this.outputState;
         }
 
-        public void setOutputState(int outputState) {
+        public void setOutputState(final int outputState) {
             this.outputState = outputState;
         }
 
@@ -640,7 +637,7 @@ public class ThrottlingHttpClientHandler extends NHttpHandlerBase
             return this.timeout;
         }
 
-        public void setTimeout(int timeout) {
+        public void setTimeout(final int timeout) {
             this.timeout = timeout;
         }
 
@@ -648,7 +645,7 @@ public class ThrottlingHttpClientHandler extends NHttpHandlerBase
             return this.workerRunning;
         }
 
-        public void setWorkerRunning(boolean b) {
+        public void setWorkerRunning(final boolean b) {
             this.workerRunning = b;
         }
 
diff --git a/httpcore-nio/src/main/java/org/apache/http/nio/protocol/ThrottlingHttpServiceHandler.java b/httpcore-nio/src/main/java-deprecated/org/apache/http/nio/protocol/ThrottlingHttpServiceHandler.java
similarity index 86%
rename from httpcore-nio/src/main/java/org/apache/http/nio/protocol/ThrottlingHttpServiceHandler.java
rename to httpcore-nio/src/main/java-deprecated/org/apache/http/nio/protocol/ThrottlingHttpServiceHandler.java
index 4a7c496..d61d071 100644
--- a/httpcore-nio/src/main/java/org/apache/http/nio/protocol/ThrottlingHttpServiceHandler.java
+++ b/httpcore-nio/src/main/java-deprecated/org/apache/http/nio/protocol/ThrottlingHttpServiceHandler.java
@@ -41,8 +41,8 @@ import org.apache.http.HttpResponseFactory;
 import org.apache.http.HttpStatus;
 import org.apache.http.HttpVersion;
 import org.apache.http.MethodNotSupportedException;
-import org.apache.http.ProtocolVersion;
 import org.apache.http.ProtocolException;
+import org.apache.http.ProtocolVersion;
 import org.apache.http.UnsupportedHttpVersionException;
 import org.apache.http.annotation.ThreadSafe;
 import org.apache.http.entity.ByteArrayEntity;
@@ -61,14 +61,15 @@ import org.apache.http.nio.util.ContentOutputBuffer;
 import org.apache.http.nio.util.DirectByteBufferAllocator;
 import org.apache.http.nio.util.SharedInputBuffer;
 import org.apache.http.nio.util.SharedOutputBuffer;
-import org.apache.http.params.HttpParams;
 import org.apache.http.params.DefaultedHttpParams;
-import org.apache.http.protocol.HttpContext;
+import org.apache.http.params.HttpParams;
 import org.apache.http.protocol.ExecutionContext;
+import org.apache.http.protocol.HttpContext;
 import org.apache.http.protocol.HttpExpectationVerifier;
 import org.apache.http.protocol.HttpProcessor;
 import org.apache.http.protocol.HttpRequestHandler;
 import org.apache.http.protocol.HttpRequestHandlerResolver;
+import org.apache.http.util.Args;
 import org.apache.http.util.EncodingUtils;
 import org.apache.http.util.EntityUtils;
 
@@ -128,12 +129,8 @@ public class ThrottlingHttpServiceHandler extends NHttpHandlerBase
             final Executor executor,
             final HttpParams params) {
         super(httpProcessor, connStrategy, allocator, params);
-        if (responseFactory == null) {
-            throw new IllegalArgumentException("Response factory may not be null");
-        }
-        if (executor == null) {
-            throw new IllegalArgumentException("Executor may not be null");
-        }
+        Args.notNull(responseFactory, "Response factory");
+        Args.notNull(executor, "Executor");
         this.responseFactory = responseFactory;
         this.executor = executor;
         this.bufsize = this.params.getIntParameter(NIOReactorPNames.CONTENT_BUFFER_SIZE, 20480);
@@ -146,7 +143,7 @@ public class ThrottlingHttpServiceHandler extends NHttpHandlerBase
             final Executor executor,
             final HttpParams params) {
         this(httpProcessor, responseFactory, connStrategy,
-                new DirectByteBufferAllocator(), executor, params);
+                DirectByteBufferAllocator.INSTANCE, executor, params);
     }
 
     public void setHandlerResolver(final HttpRequestHandlerResolver handlerResolver) {
@@ -158,9 +155,9 @@ public class ThrottlingHttpServiceHandler extends NHttpHandlerBase
     }
 
     public void connected(final NHttpServerConnection conn) {
-        HttpContext context = conn.getContext();
+        final HttpContext context = conn.getContext();
 
-        ServerConnState connState = new ServerConnState(this.bufsize, conn, allocator);
+        final ServerConnState connState = new ServerConnState(this.bufsize, conn, allocator);
         context.setAttribute(CONN_STATE, connState);
 
         if (this.eventListener != null) {
@@ -169,8 +166,8 @@ public class ThrottlingHttpServiceHandler extends NHttpHandlerBase
     }
 
     public void closed(final NHttpServerConnection conn) {
-        HttpContext context = conn.getContext();
-        ServerConnState connState = (ServerConnState) context.getAttribute(CONN_STATE);
+        final HttpContext context = conn.getContext();
+        final ServerConnState connState = (ServerConnState) context.getAttribute(CONN_STATE);
 
         if (connState != null) {
             synchronized (connState) {
@@ -192,13 +189,13 @@ public class ThrottlingHttpServiceHandler extends NHttpHandlerBase
             return;
         }
 
-        HttpContext context = conn.getContext();
+        final HttpContext context = conn.getContext();
 
-        ServerConnState connState = (ServerConnState) context.getAttribute(CONN_STATE);
+        final ServerConnState connState = (ServerConnState) context.getAttribute(CONN_STATE);
 
         try {
 
-            HttpResponse response = this.responseFactory.newHttpResponse(
+            final HttpResponse response = this.responseFactory.newHttpResponse(
                     HttpVersion.HTTP_1_0,
                     HttpStatus.SC_INTERNAL_SERVER_ERROR,
                     context);
@@ -215,12 +212,12 @@ public class ThrottlingHttpServiceHandler extends NHttpHandlerBase
                 conn.requestOutput();
             }
 
-        } catch (IOException ex) {
+        } catch (final IOException ex) {
             shutdownConnection(conn, ex);
             if (eventListener != null) {
                 eventListener.fatalIOException(ex, conn);
             }
-        } catch (HttpException ex) {
+        } catch (final HttpException ex) {
             closeConnection(conn, ex);
             if (eventListener != null) {
                 eventListener.fatalProtocolException(ex, conn);
@@ -241,7 +238,7 @@ public class ThrottlingHttpServiceHandler extends NHttpHandlerBase
     }
 
     public void requestReceived(final NHttpServerConnection conn) {
-        HttpContext context = conn.getContext();
+        final HttpContext context = conn.getContext();
 
         final HttpRequest request = conn.getHttpRequest();
         final ServerConnState connState = (ServerConnState) context.getAttribute(CONN_STATE);
@@ -249,7 +246,7 @@ public class ThrottlingHttpServiceHandler extends NHttpHandlerBase
         synchronized (connState) {
             boolean contentExpected = false;
             if (request instanceof HttpEntityEnclosingRequest) {
-                HttpEntity entity = ((HttpEntityEnclosingRequest) request).getEntity();
+                final HttpEntity entity = ((HttpEntityEnclosingRequest) request).getEntity();
                 if (entity != null) {
                     contentExpected = true;
                 }
@@ -266,12 +263,12 @@ public class ThrottlingHttpServiceHandler extends NHttpHandlerBase
 
                         handleRequest(request, connState, conn);
 
-                    } catch (IOException ex) {
+                    } catch (final IOException ex) {
                         shutdownConnection(conn, ex);
                         if (eventListener != null) {
                             eventListener.fatalIOException(ex, conn);
                         }
-                    } catch (HttpException ex) {
+                    } catch (final HttpException ex) {
                         shutdownConnection(conn, ex);
                         if (eventListener != null) {
                             eventListener.fatalProtocolException(ex, conn);
@@ -287,14 +284,14 @@ public class ThrottlingHttpServiceHandler extends NHttpHandlerBase
     }
 
     public void inputReady(final NHttpServerConnection conn, final ContentDecoder decoder) {
-        HttpContext context = conn.getContext();
+        final HttpContext context = conn.getContext();
 
-        ServerConnState connState = (ServerConnState) context.getAttribute(CONN_STATE);
+        final ServerConnState connState = (ServerConnState) context.getAttribute(CONN_STATE);
 
         try {
 
             synchronized (connState) {
-                ContentInputBuffer buffer = connState.getInbuffer();
+                final ContentInputBuffer buffer = connState.getInbuffer();
 
                 buffer.consumeContent(decoder);
                 if (decoder.isCompleted()) {
@@ -306,7 +303,7 @@ public class ThrottlingHttpServiceHandler extends NHttpHandlerBase
                 connState.notifyAll();
             }
 
-        } catch (IOException ex) {
+        } catch (final IOException ex) {
             shutdownConnection(conn, ex);
             if (this.eventListener != null) {
                 this.eventListener.fatalIOException(ex, conn);
@@ -316,9 +313,9 @@ public class ThrottlingHttpServiceHandler extends NHttpHandlerBase
     }
 
     public void responseReady(final NHttpServerConnection conn) {
-        HttpContext context = conn.getContext();
+        final HttpContext context = conn.getContext();
 
-        ServerConnState connState = (ServerConnState) context.getAttribute(CONN_STATE);
+        final ServerConnState connState = (ServerConnState) context.getAttribute(CONN_STATE);
 
         try {
 
@@ -331,14 +328,14 @@ public class ThrottlingHttpServiceHandler extends NHttpHandlerBase
                     connState.setExpectationFailed(false);
                 }
 
-                HttpResponse response = connState.getResponse();
+                final HttpResponse response = connState.getResponse();
                 if (connState.getOutputState() == ServerConnState.READY
                         && response != null
                         && !conn.isResponseSubmitted()) {
 
                     conn.submitResponse(response);
-                    int statusCode = response.getStatusLine().getStatusCode();
-                    HttpEntity entity = response.getEntity();
+                    final int statusCode = response.getStatusLine().getStatusCode();
+                    final HttpEntity entity = response.getEntity();
 
                     if (statusCode >= 200 && entity == null) {
                         connState.setOutputState(ServerConnState.RESPONSE_DONE);
@@ -354,12 +351,12 @@ public class ThrottlingHttpServiceHandler extends NHttpHandlerBase
                 connState.notifyAll();
             }
 
-        } catch (IOException ex) {
+        } catch (final IOException ex) {
             shutdownConnection(conn, ex);
             if (eventListener != null) {
                 eventListener.fatalIOException(ex, conn);
             }
-        } catch (HttpException ex) {
+        } catch (final HttpException ex) {
             closeConnection(conn, ex);
             if (eventListener != null) {
                 eventListener.fatalProtocolException(ex, conn);
@@ -368,15 +365,15 @@ public class ThrottlingHttpServiceHandler extends NHttpHandlerBase
     }
 
     public void outputReady(final NHttpServerConnection conn, final ContentEncoder encoder) {
-        HttpContext context = conn.getContext();
+        final HttpContext context = conn.getContext();
 
-        ServerConnState connState = (ServerConnState) context.getAttribute(CONN_STATE);
+        final ServerConnState connState = (ServerConnState) context.getAttribute(CONN_STATE);
 
         try {
 
             synchronized (connState) {
-                HttpResponse response = connState.getResponse();
-                ContentOutputBuffer buffer = connState.getOutbuffer();
+                final HttpResponse response = connState.getResponse();
+                final ContentOutputBuffer buffer = connState.getOutbuffer();
 
                 buffer.produceContent(encoder);
                 if (encoder.isCompleted()) {
@@ -392,7 +389,7 @@ public class ThrottlingHttpServiceHandler extends NHttpHandlerBase
                 connState.notifyAll();
             }
 
-        } catch (IOException ex) {
+        } catch (final IOException ex) {
             shutdownConnection(conn, ex);
             if (this.eventListener != null) {
                 this.eventListener.fatalIOException(ex, conn);
@@ -410,8 +407,8 @@ public class ThrottlingHttpServiceHandler extends NHttpHandlerBase
         } else {
             response.setStatusCode(HttpStatus.SC_INTERNAL_SERVER_ERROR);
         }
-        byte[] msg = EncodingUtils.getAsciiBytes(ex.getMessage());
-        ByteArrayEntity entity = new ByteArrayEntity(msg);
+        final byte[] msg = EncodingUtils.getAsciiBytes(ex.getMessage());
+        final ByteArrayEntity entity = new ByteArrayEntity(msg);
         entity.setContentType("text/plain; charset=US-ASCII");
         response.setEntity(entity);
     }
@@ -421,14 +418,14 @@ public class ThrottlingHttpServiceHandler extends NHttpHandlerBase
             final ServerConnState connState,
             final NHttpServerConnection conn) throws HttpException, IOException {
 
-        HttpContext context = conn.getContext();
+        final HttpContext context = conn.getContext();
 
         // Block until previous request is fully processed and
         // the worker thread no longer holds the shared buffer
         synchronized (connState) {
             try {
                 for (;;) {
-                    int currentState = connState.getOutputState();
+                    final int currentState = connState.getOutputState();
                     if (currentState == ServerConnState.READY) {
                         break;
                     }
@@ -437,7 +434,7 @@ public class ThrottlingHttpServiceHandler extends NHttpHandlerBase
                     }
                     connState.wait();
                 }
-            } catch (InterruptedException ex) {
+            } catch (final InterruptedException ex) {
                 connState.shutdown();
                 return;
             }
@@ -460,7 +457,7 @@ public class ThrottlingHttpServiceHandler extends NHttpHandlerBase
         HttpResponse response = null;
 
         if (request instanceof HttpEntityEnclosingRequest) {
-            HttpEntityEnclosingRequest eeRequest = (HttpEntityEnclosingRequest) request;
+            final HttpEntityEnclosingRequest eeRequest = (HttpEntityEnclosingRequest) request;
 
             if (eeRequest.expectContinue()) {
                 response = this.responseFactory.newHttpResponse(
@@ -472,7 +469,7 @@ public class ThrottlingHttpServiceHandler extends NHttpHandlerBase
                 if (this.expectationVerifier != null) {
                     try {
                         this.expectationVerifier.verify(request, response, context);
-                    } catch (HttpException ex) {
+                    } catch (final HttpException ex) {
                         response = this.responseFactory.newHttpResponse(HttpVersion.HTTP_1_0,
                                 HttpStatus.SC_INTERNAL_SERVER_ERROR, context);
                         response.setParams(
@@ -491,7 +488,7 @@ public class ThrottlingHttpServiceHandler extends NHttpHandlerBase
                         // Block until 1xx response is sent to the client
                         try {
                             for (;;) {
-                                int currentState = connState.getOutputState();
+                                final int currentState = connState.getOutputState();
                                 if (currentState == ServerConnState.RESPONSE_SENT) {
                                     break;
                                 }
@@ -500,7 +497,7 @@ public class ThrottlingHttpServiceHandler extends NHttpHandlerBase
                                 }
                                 connState.wait();
                             }
-                        } catch (InterruptedException ex) {
+                        } catch (final InterruptedException ex) {
                             connState.shutdown();
                             return;
                         }
@@ -540,7 +537,7 @@ public class ThrottlingHttpServiceHandler extends NHttpHandlerBase
 
                 HttpRequestHandler handler = null;
                 if (this.handlerResolver != null) {
-                    String requestURI = request.getRequestLine().getUri();
+                    final String requestURI = request.getRequestLine().getUri();
                     handler = this.handlerResolver.lookup(requestURI);
                 }
                 if (handler != null) {
@@ -549,7 +546,7 @@ public class ThrottlingHttpServiceHandler extends NHttpHandlerBase
                     response.setStatusCode(HttpStatus.SC_NOT_IMPLEMENTED);
                 }
 
-            } catch (HttpException ex) {
+            } catch (final HttpException ex) {
                 response = this.responseFactory.newHttpResponse(HttpVersion.HTTP_1_0,
                         HttpStatus.SC_INTERNAL_SERVER_ERROR, context);
                 response.setParams(
@@ -559,8 +556,8 @@ public class ThrottlingHttpServiceHandler extends NHttpHandlerBase
         }
 
         if (request instanceof HttpEntityEnclosingRequest) {
-            HttpEntityEnclosingRequest eeRequest = (HttpEntityEnclosingRequest) request;
-            HttpEntity entity = eeRequest.getEntity();
+            final HttpEntityEnclosingRequest eeRequest = (HttpEntityEnclosingRequest) request;
+            final HttpEntity entity = eeRequest.getEntity();
             EntityUtils.consume(entity);
         }
 
@@ -578,10 +575,10 @@ public class ThrottlingHttpServiceHandler extends NHttpHandlerBase
         conn.requestOutput();
 
         if (response.getEntity() != null) {
-            ContentOutputBuffer buffer = connState.getOutbuffer();
-            OutputStream outstream = new ContentOutputStream(buffer);
+            final ContentOutputBuffer buffer = connState.getOutbuffer();
+            final OutputStream outstream = new ContentOutputStream(buffer);
 
-            HttpEntity entity = response.getEntity();
+            final HttpEntity entity = response.getEntity();
             entity.writeTo(outstream);
             outstream.flush();
             outstream.close();
@@ -590,7 +587,7 @@ public class ThrottlingHttpServiceHandler extends NHttpHandlerBase
         synchronized (connState) {
             try {
                 for (;;) {
-                    int currentState = connState.getOutputState();
+                    final int currentState = connState.getOutputState();
                     if (currentState == ServerConnState.RESPONSE_DONE) {
                         break;
                     }
@@ -599,7 +596,7 @@ public class ThrottlingHttpServiceHandler extends NHttpHandlerBase
                     }
                     connState.wait();
                 }
-            } catch (InterruptedException ex) {
+            } catch (final InterruptedException ex) {
                 connState.shutdown();
                 return;
             }
@@ -611,9 +608,9 @@ public class ThrottlingHttpServiceHandler extends NHttpHandlerBase
 
     @Override
     protected void shutdownConnection(final NHttpConnection conn, final Throwable cause) {
-        HttpContext context = conn.getContext();
+        final HttpContext context = conn.getContext();
 
-        ServerConnState connState = (ServerConnState) context.getAttribute(CONN_STATE);
+        final ServerConnState connState = (ServerConnState) context.getAttribute(CONN_STATE);
 
         super.shutdownConnection(conn, cause);
 
@@ -646,7 +643,7 @@ public class ThrottlingHttpServiceHandler extends NHttpHandlerBase
         private volatile boolean expectationFailure;
 
         public ServerConnState(
-                int bufsize,
+                final int bufsize,
                 final IOControl ioControl,
                 final ByteBufferAllocator allocator) {
             super();
@@ -668,7 +665,7 @@ public class ThrottlingHttpServiceHandler extends NHttpHandlerBase
             return this.inputState;
         }
 
-        public void setInputState(int inputState) {
+        public void setInputState(final int inputState) {
             this.inputState = inputState;
         }
 
@@ -676,7 +673,7 @@ public class ThrottlingHttpServiceHandler extends NHttpHandlerBase
             return this.outputState;
         }
 
-        public void setOutputState(int outputState) {
+        public void setOutputState(final int outputState) {
             this.outputState = outputState;
         }
 
@@ -700,7 +697,7 @@ public class ThrottlingHttpServiceHandler extends NHttpHandlerBase
             return expectationFailure;
         }
 
-        public void setExpectationFailed(boolean b) {
+        public void setExpectationFailed(final boolean b) {
             this.expectationFailure = b;
         }
 
diff --git a/httpcore-nio/src/main/java/org/apache/http/impl/nio/DefaultHttpClientIODispatch.java b/httpcore-nio/src/main/java/org/apache/http/impl/nio/DefaultHttpClientIODispatch.java
index 3e8d0d2..25fc3ca 100644
--- a/httpcore-nio/src/main/java/org/apache/http/impl/nio/DefaultHttpClientIODispatch.java
+++ b/httpcore-nio/src/main/java/org/apache/http/impl/nio/DefaultHttpClientIODispatch.java
@@ -32,20 +32,23 @@ import java.io.IOException;
 import javax.net.ssl.SSLContext;
 
 import org.apache.http.annotation.Immutable;
+import org.apache.http.config.ConnectionConfig;
 import org.apache.http.impl.nio.reactor.AbstractIODispatch;
 import org.apache.http.nio.NHttpClientEventHandler;
 import org.apache.http.nio.NHttpConnectionFactory;
-import org.apache.http.nio.reactor.IOEventDispatch;
 import org.apache.http.nio.reactor.IOSession;
 import org.apache.http.nio.reactor.ssl.SSLSetupHandler;
 import org.apache.http.params.HttpParams;
+import org.apache.http.util.Args;
 
 /**
- * Default {@link IOEventDispatch} implementation that supports both plain (non-encrypted)
- * and SSL encrypted client side HTTP connections.
+ * Default {@link org.apache.http.nio.reactor.IOEventDispatch} implementation
+ * that supports both plain (non-encrypted) and SSL encrypted client side HTTP
+ * connections.
  *
  * @since 4.2
  */
+ at SuppressWarnings("deprecation")
 @Immutable // provided injected dependencies are immutable
 public class DefaultHttpClientIODispatch
                     extends AbstractIODispatch<DefaultNHttpClientConnection> {
@@ -64,22 +67,26 @@ public class DefaultHttpClientIODispatch
             final NHttpClientEventHandler handler,
             final NHttpConnectionFactory<DefaultNHttpClientConnection> connFactory) {
         super();
-        if (handler == null) {
-            throw new IllegalArgumentException("HTTP client handler may not be null");
-        }
-        if (connFactory == null) {
-            throw new IllegalArgumentException("HTTP client connection factory may not null");
-        }
-        this.handler = handler;
-        this.connFactory = connFactory;
+        this.handler = Args.notNull(handler, "HTTP client handler");
+        this.connFactory = Args.notNull(connFactory, "HTTP client connection factory");
     }
 
+    /**
+     * @deprecated (4.3) use {@link DefaultHttpClientIODispatch#DefaultHttpClientIODispatch(
+     *  NHttpClientEventHandler, ConnectionConfig)}
+     */
+    @Deprecated
     public DefaultHttpClientIODispatch(
             final NHttpClientEventHandler handler,
             final HttpParams params) {
         this(handler, new DefaultNHttpClientConnectionFactory(params));
     }
 
+    /**
+     * @deprecated (4.3) use {@link DefaultHttpClientIODispatch#DefaultHttpClientIODispatch(
+     *  NHttpClientEventHandler, SSLContext, SSLSetupHandler, ConnectionConfig)}
+     */
+    @Deprecated
     public DefaultHttpClientIODispatch(
             final NHttpClientEventHandler handler,
             final SSLContext sslcontext,
@@ -88,6 +95,11 @@ public class DefaultHttpClientIODispatch
         this(handler, new SSLNHttpClientConnectionFactory(sslcontext, sslHandler, params));
     }
 
+    /**
+     * @deprecated (4.3) use {@link DefaultHttpClientIODispatch#DefaultHttpClientIODispatch(
+     *   NHttpClientEventHandler, SSLContext, ConnectionConfig)}
+     */
+    @Deprecated
     public DefaultHttpClientIODispatch(
             final NHttpClientEventHandler handler,
             final SSLContext sslcontext,
@@ -95,6 +107,34 @@ public class DefaultHttpClientIODispatch
         this(handler, sslcontext, null, params);
     }
 
+    /**
+     * @since 4.3
+     */
+    public DefaultHttpClientIODispatch(final NHttpClientEventHandler handler, final ConnectionConfig config) {
+        this(handler, new DefaultNHttpClientConnectionFactory(config));
+    }
+
+    /**
+     * @since 4.3
+     */
+    public DefaultHttpClientIODispatch(
+            final NHttpClientEventHandler handler,
+            final SSLContext sslcontext,
+            final SSLSetupHandler sslHandler,
+            final ConnectionConfig config) {
+        this(handler, new SSLNHttpClientConnectionFactory(sslcontext, sslHandler, config));
+    }
+
+    /**
+     * @since 4.3
+     */
+    public DefaultHttpClientIODispatch(
+            final NHttpClientEventHandler handler,
+            final SSLContext sslcontext,
+            final ConnectionConfig config) {
+        this(handler, new SSLNHttpClientConnectionFactory(sslcontext, null, config));
+    }
+
     @Override
     protected DefaultNHttpClientConnection createConnection(final IOSession session) {
         return this.connFactory.createConnection(session);
@@ -102,10 +142,10 @@ public class DefaultHttpClientIODispatch
 
     @Override
     protected void onConnected(final DefaultNHttpClientConnection conn) {
-        Object attachment = conn.getContext().getAttribute(IOSession.ATTACHMENT_KEY);
+        final Object attachment = conn.getContext().getAttribute(IOSession.ATTACHMENT_KEY);
         try {
             this.handler.connected(conn, attachment);
-        } catch (Exception ex) {
+        } catch (final Exception ex) {
             this.handler.exception(conn, ex);
         }
     }
@@ -116,7 +156,7 @@ public class DefaultHttpClientIODispatch
     }
 
     @Override
-    protected void onException(final DefaultNHttpClientConnection conn, IOException ex) {
+    protected void onException(final DefaultNHttpClientConnection conn, final IOException ex) {
         this.handler.exception(conn, ex);
     }
 
@@ -134,7 +174,7 @@ public class DefaultHttpClientIODispatch
     protected void onTimeout(final DefaultNHttpClientConnection conn) {
         try {
             this.handler.timeout(conn);
-        } catch (Exception ex) {
+        } catch (final Exception ex) {
             this.handler.exception(conn, ex);
         }
     }
diff --git a/httpcore-nio/src/main/java/org/apache/http/impl/nio/DefaultHttpServerIODispatch.java b/httpcore-nio/src/main/java/org/apache/http/impl/nio/DefaultHttpServerIODispatch.java
index 3672deb..0f7e426 100644
--- a/httpcore-nio/src/main/java/org/apache/http/impl/nio/DefaultHttpServerIODispatch.java
+++ b/httpcore-nio/src/main/java/org/apache/http/impl/nio/DefaultHttpServerIODispatch.java
@@ -32,20 +32,23 @@ import java.io.IOException;
 import javax.net.ssl.SSLContext;
 
 import org.apache.http.annotation.Immutable;
+import org.apache.http.config.ConnectionConfig;
 import org.apache.http.impl.nio.reactor.AbstractIODispatch;
 import org.apache.http.nio.NHttpConnectionFactory;
 import org.apache.http.nio.NHttpServerEventHandler;
-import org.apache.http.nio.reactor.IOEventDispatch;
 import org.apache.http.nio.reactor.IOSession;
 import org.apache.http.nio.reactor.ssl.SSLSetupHandler;
 import org.apache.http.params.HttpParams;
+import org.apache.http.util.Args;
 
 /**
- * Default {@link IOEventDispatch} implementation that supports both plain (non-encrypted)
- * and SSL encrypted server side HTTP connections.
+ * Default {@link org.apache.http.nio.reactor.IOEventDispatch} implementation
+ * that supports both plain (non-encrypted) and SSL encrypted server side HTTP
+ * connections.
  *
  * @since 4.2
  */
+ at SuppressWarnings("deprecation")
 @Immutable // provided injected dependencies are immutable
 public class DefaultHttpServerIODispatch
                     extends AbstractIODispatch<DefaultNHttpServerConnection> {
@@ -57,22 +60,26 @@ public class DefaultHttpServerIODispatch
             final NHttpServerEventHandler handler,
             final NHttpConnectionFactory<DefaultNHttpServerConnection> connFactory) {
         super();
-        if (handler == null) {
-            throw new IllegalArgumentException("HTTP client handler may not be null");
-        }
-        if (connFactory == null) {
-            throw new IllegalArgumentException("HTTP server connection factory is null");
-        }
-        this.handler = handler;
-        this.connFactory = connFactory;
+        this.handler = Args.notNull(handler, "HTTP client handler");
+        this.connFactory = Args.notNull(connFactory, "HTTP server connection factory");
     }
 
+    /**
+     * @deprecated (4.3) use {@link DefaultHttpServerIODispatch#DefaultHttpServerIODispatch(
+     *   NHttpServerEventHandler, ConnectionConfig)}
+     */
+    @Deprecated
     public DefaultHttpServerIODispatch(
             final NHttpServerEventHandler handler,
             final HttpParams params) {
         this(handler, new DefaultNHttpServerConnectionFactory(params));
     }
 
+    /**
+     * @deprecated (4.3) use {@link DefaultHttpServerIODispatch#DefaultHttpServerIODispatch(
+     *   NHttpServerEventHandler, SSLContext, SSLSetupHandler, ConnectionConfig)}
+     */
+    @Deprecated
     public DefaultHttpServerIODispatch(
             final NHttpServerEventHandler handler,
             final SSLContext sslcontext,
@@ -81,6 +88,11 @@ public class DefaultHttpServerIODispatch
         this(handler, new SSLNHttpServerConnectionFactory(sslcontext, sslHandler, params));
     }
 
+    /**
+     * @deprecated (4.3) use {@link DefaultHttpServerIODispatch#DefaultHttpServerIODispatch(
+     *   NHttpServerEventHandler, SSLContext, ConnectionConfig)}
+     */
+    @Deprecated
     public DefaultHttpServerIODispatch(
             final NHttpServerEventHandler handler,
             final SSLContext sslcontext,
@@ -88,6 +100,34 @@ public class DefaultHttpServerIODispatch
         this(handler, sslcontext, null, params);
     }
 
+    /**
+     * @since 4.3
+     */
+    public DefaultHttpServerIODispatch(final NHttpServerEventHandler handler, final ConnectionConfig config) {
+        this(handler, new DefaultNHttpServerConnectionFactory(config));
+    }
+
+    /**
+     * @since 4.3
+     */
+    public DefaultHttpServerIODispatch(
+            final NHttpServerEventHandler handler,
+            final SSLContext sslcontext,
+            final SSLSetupHandler sslHandler,
+            final ConnectionConfig config) {
+        this(handler, new SSLNHttpServerConnectionFactory(sslcontext, sslHandler, config));
+    }
+
+    /**
+     * @since 4.3
+     */
+    public DefaultHttpServerIODispatch(
+            final NHttpServerEventHandler handler,
+            final SSLContext sslcontext,
+            final ConnectionConfig config) {
+        this(handler, new SSLNHttpServerConnectionFactory(sslcontext, null, config));
+    }
+
     @Override
     protected DefaultNHttpServerConnection createConnection(final IOSession session) {
         return this.connFactory.createConnection(session);
@@ -97,7 +137,7 @@ public class DefaultHttpServerIODispatch
     protected void onConnected(final DefaultNHttpServerConnection conn) {
         try {
             this.handler.connected(conn);
-        } catch (Exception ex) {
+        } catch (final Exception ex) {
             this.handler.exception(conn, ex);
         }
     }
@@ -108,7 +148,7 @@ public class DefaultHttpServerIODispatch
     }
 
     @Override
-    protected void onException(final DefaultNHttpServerConnection conn, IOException ex) {
+    protected void onException(final DefaultNHttpServerConnection conn, final IOException ex) {
         this.handler.exception(conn, ex);
     }
 
@@ -126,7 +166,7 @@ public class DefaultHttpServerIODispatch
     protected void onTimeout(final DefaultNHttpServerConnection conn) {
         try {
             this.handler.timeout(conn);
-        } catch (Exception ex) {
+        } catch (final Exception ex) {
             this.handler.exception(conn, ex);
         }
     }
diff --git a/httpcore-nio/src/main/java/org/apache/http/impl/nio/DefaultNHttpClientConnection.java b/httpcore-nio/src/main/java/org/apache/http/impl/nio/DefaultNHttpClientConnection.java
index bf3eb62..d80581c 100644
--- a/httpcore-nio/src/main/java/org/apache/http/impl/nio/DefaultNHttpClientConnection.java
+++ b/httpcore-nio/src/main/java/org/apache/http/impl/nio/DefaultNHttpClientConnection.java
@@ -29,6 +29,8 @@ package org.apache.http.impl.nio;
 
 import java.io.IOException;
 import java.nio.channels.SelectionKey;
+import java.nio.charset.CharsetDecoder;
+import java.nio.charset.CharsetEncoder;
 
 import org.apache.http.HttpEntity;
 import org.apache.http.HttpEntityEnclosingRequest;
@@ -37,32 +39,31 @@ import org.apache.http.HttpRequest;
 import org.apache.http.HttpResponse;
 import org.apache.http.HttpResponseFactory;
 import org.apache.http.annotation.NotThreadSafe;
+import org.apache.http.config.MessageConstraints;
+import org.apache.http.entity.ContentLengthStrategy;
 import org.apache.http.impl.nio.codecs.DefaultHttpRequestWriter;
+import org.apache.http.impl.nio.codecs.DefaultHttpRequestWriterFactory;
 import org.apache.http.impl.nio.codecs.DefaultHttpResponseParser;
-import org.apache.http.nio.NHttpClientConnection;
-import org.apache.http.nio.NHttpClientIOTarget;
-import org.apache.http.nio.NHttpClientHandler;
+import org.apache.http.impl.nio.codecs.DefaultHttpResponseParserFactory;
 import org.apache.http.nio.NHttpClientEventHandler;
+import org.apache.http.nio.NHttpClientHandler;
+import org.apache.http.nio.NHttpClientIOTarget;
 import org.apache.http.nio.NHttpMessageParser;
+import org.apache.http.nio.NHttpMessageParserFactory;
 import org.apache.http.nio.NHttpMessageWriter;
+import org.apache.http.nio.NHttpMessageWriterFactory;
 import org.apache.http.nio.reactor.EventMask;
 import org.apache.http.nio.reactor.IOSession;
 import org.apache.http.nio.reactor.SessionInputBuffer;
 import org.apache.http.nio.reactor.SessionOutputBuffer;
 import org.apache.http.nio.util.ByteBufferAllocator;
+import org.apache.http.params.HttpParamConfig;
 import org.apache.http.params.HttpParams;
+import org.apache.http.util.Args;
 
 /**
- * Default implementation of the {@link NHttpClientConnection} interface.
- * <p>
- * The following parameters can be used to customize the behavior of this
- * class:
- * <ul>
- *  <li>{@link org.apache.http.params.CoreProtocolPNames#HTTP_ELEMENT_CHARSET}</li>
- *  <li>{@link org.apache.http.params.CoreConnectionPNames#SOCKET_BUFFER_SIZE}</li>
- *  <li>{@link org.apache.http.params.CoreConnectionPNames#MAX_HEADER_COUNT}</li>
- *  <li>{@link org.apache.http.params.CoreConnectionPNames#MAX_LINE_LENGTH}</li>
- * </ul>
+ * Default implementation of the {@link org.apache.http.nio.NHttpClientConnection}
+ * interface.
  *
  * @since 4.0
  */
@@ -81,16 +82,20 @@ public class DefaultNHttpClientConnection
      * @param responseFactory HTTP response factory.
      * @param allocator byte buffer allocator.
      * @param params HTTP parameters.
+     *
+     * @deprecated (4.3) use {@link DefaultNHttpClientConnection#DefaultNHttpClientConnection(
+     *   IOSession, int, int, ByteBufferAllocator, CharsetDecoder, CharsetEncoder,
+     *   MessageConstraints, ContentLengthStrategy, ContentLengthStrategy,
+     *   NHttpMessageWriterFactory, NHttpMessageParserFactory)}
      */
+    @Deprecated
     public DefaultNHttpClientConnection(
             final IOSession session,
             final HttpResponseFactory responseFactory,
             final ByteBufferAllocator allocator,
             final HttpParams params) {
         super(session, allocator, params);
-        if (responseFactory == null) {
-            throw new IllegalArgumentException("Response factory may not be null");
-        }
+        Args.notNull(responseFactory, "Response factory");
         this.responseParser = createResponseParser(this.inbuf, responseFactory, params);
         this.requestWriter = createRequestWriter(this.outbuf, params);
         this.hasBufferedInput = false;
@@ -99,6 +104,68 @@ public class DefaultNHttpClientConnection
     }
 
     /**
+     * Creates new instance DefaultNHttpClientConnection given the underlying I/O session.
+     *
+     * @param session the underlying I/O session.
+     * @param buffersize buffer size. Must be a positive number.
+     * @param fragmentSizeHint fragment size hint.
+     * @param allocator memory allocator.
+     *   If <code>null</code> {@link org.apache.http.nio.util.HeapByteBufferAllocator#INSTANCE}
+     *   will be used.
+     * @param chardecoder decoder to be used for decoding HTTP protocol elements.
+     *   If <code>null</code> simple type cast will be used for byte to char conversion.
+     * @param charencoder encoder to be used for encoding HTTP protocol elements.
+     *   If <code>null</code> simple type cast will be used for char to byte conversion.
+     * @param constraints Message constraints. If <code>null</code>
+     *   {@link MessageConstraints#DEFAULT} will be used.
+     * @param incomingContentStrategy incoming content length strategy. If <code>null</code>
+     *   {@link org.apache.http.impl.entity.LaxContentLengthStrategy#INSTANCE} will be used.
+     * @param outgoingContentStrategy outgoing content length strategy. If <code>null</code>
+     *   {@link org.apache.http.impl.entity.StrictContentLengthStrategy#INSTANCE} will be used.
+     *
+     * @since 4.3
+     */
+    public DefaultNHttpClientConnection(
+            final IOSession session,
+            final int buffersize,
+            final int fragmentSizeHint,
+            final ByteBufferAllocator allocator,
+            final CharsetDecoder chardecoder,
+            final CharsetEncoder charencoder,
+            final MessageConstraints constraints,
+            final ContentLengthStrategy incomingContentStrategy,
+            final ContentLengthStrategy outgoingContentStrategy,
+            final NHttpMessageWriterFactory<HttpRequest> requestWriterFactory,
+            final NHttpMessageParserFactory<HttpResponse> responseParserFactory) {
+        super(session, buffersize, fragmentSizeHint,  allocator, chardecoder, charencoder,
+                incomingContentStrategy, outgoingContentStrategy);
+        this.requestWriter = (requestWriterFactory != null ? requestWriterFactory :
+            DefaultHttpRequestWriterFactory.INSTANCE).create(this.outbuf);
+        this.responseParser = (responseParserFactory != null ? responseParserFactory :
+            DefaultHttpResponseParserFactory.INSTANCE).create(this.inbuf, constraints);
+    }
+
+    /**
+     * @since 4.3
+     */
+    public DefaultNHttpClientConnection(
+            final IOSession session,
+            final int buffersize,
+            final CharsetDecoder chardecoder,
+            final CharsetEncoder charencoder,
+            final MessageConstraints constraints) {
+        this(session, buffersize, buffersize, null, chardecoder, charencoder, constraints,
+                null, null, null, null);
+    }
+
+    /**
+     * @since 4.3
+     */
+    public DefaultNHttpClientConnection(final IOSession session, final int buffersize) {
+        this(session, buffersize, buffersize, null, null, null, null, null, null, null, null);
+    }
+
+    /**
      * Creates an instance of {@link NHttpMessageParser} to be used
      * by this connection for parsing incoming {@link HttpResponse} messages.
      * <p>
@@ -106,13 +173,17 @@ public class DefaultNHttpClientConnection
      * a different implementation of the {@link NHttpMessageParser} interface.
      *
      * @return HTTP response parser.
+     *
+     * @deprecated (4.3) use constructor.
      */
+    @Deprecated
     protected NHttpMessageParser<HttpResponse> createResponseParser(
             final SessionInputBuffer buffer,
             final HttpResponseFactory responseFactory,
             final HttpParams params) {
         // override in derived class to specify a line parser
-        return new DefaultHttpResponseParser(buffer, null, responseFactory, params);
+        final MessageConstraints constraints = HttpParamConfig.getMessageConstraints(params);
+        return new DefaultHttpResponseParser(buffer, null, responseFactory, constraints);
     }
 
     /**
@@ -123,12 +194,15 @@ public class DefaultNHttpClientConnection
      * a different implementation of the {@link NHttpMessageWriter} interface.
      *
      * @return HTTP response parser.
+     *
+     * @deprecated (4.3) use constructor.
      */
+    @Deprecated
     protected NHttpMessageWriter<HttpRequest> createRequestWriter(
             final SessionOutputBuffer buffer,
             final HttpParams params) {
         // override in derived class to specify a line formatter
-        return new DefaultHttpRequestWriter(buffer, null, params);
+        return new DefaultHttpRequestWriter(buffer, null);
     }
 
     /**
@@ -136,13 +210,13 @@ public class DefaultNHttpClientConnection
      */
     protected void onResponseReceived(final HttpResponse response) {
     }
-    
+
     /**
      * @since 4.2
      */
     protected void onRequestSubmitted(final HttpRequest request) {
     }
-    
+
     public void resetInput() {
         this.response = null;
         this.contentDecoder = null;
@@ -172,7 +246,7 @@ public class DefaultNHttpClientConnection
                 } while (bytesRead > 0 && this.response == null);
                 if (this.response != null) {
                     if (this.response.getStatusLine().getStatusCode() >= 200) {
-                        HttpEntity entity = prepareDecoder(this.response);
+                        final HttpEntity entity = prepareDecoder(this.response);
                         this.response.setEntity(entity);
                         this.connMetrics.incrementResponseCount();
                     }
@@ -186,18 +260,26 @@ public class DefaultNHttpClientConnection
                     handler.endOfInput(this);
                 }
             }
-            if (this.contentDecoder != null && (this.session.getEventMask() & SelectionKey.OP_READ) > 0) {
-                handler.inputReady(this, this.contentDecoder);
-                if (this.contentDecoder.isCompleted()) {
-                    // Response entity received
-                    // Ready to receive a new response
-                    resetInput();
+            if (this.contentDecoder != null) {
+                // Loop until there is interest in input,
+                // decoder is not done and there is buffered session data
+                while ((this.session.getEventMask() & SelectionKey.OP_READ) > 0) {
+                    handler.inputReady(this, this.contentDecoder);
+                    if (this.contentDecoder.isCompleted()) {
+                        // Response entity received
+                        // Ready to receive a new response
+                        resetInput();
+                        break;
+                    }
+                    if (!this.inbuf.hasData()) {
+                        break;
+                    }
                 }
             }
-        } catch (HttpException ex) {
+        } catch (final HttpException ex) {
             resetInput();
             handler.exception(this, ex);
-        } catch (Exception ex) {
+        } catch (final Exception ex) {
             handler.exception(this, ex);
         } finally {
             // Finally set buffered input flag
@@ -207,8 +289,19 @@ public class DefaultNHttpClientConnection
 
     public void produceOutput(final NHttpClientEventHandler handler) {
         try {
+            if (this.status == ACTIVE) {
+                if (this.contentEncoder == null) {
+                    handler.requestReady(this);
+                }
+                if (this.contentEncoder != null) {
+                    handler.outputReady(this, this.contentEncoder);
+                    if (this.contentEncoder.isCompleted()) {
+                        resetOutput();
+                    }
+                }
+            }
             if (this.outbuf.hasData()) {
-                int bytesWritten = this.outbuf.flush(this.session.channel());
+                final int bytesWritten = this.outbuf.flush(this.session.channel());
                 if (bytesWritten > 0) {
                     this.outTransportMetrics.incrementBytesTransferred(bytesWritten);
                 }
@@ -218,39 +311,21 @@ public class DefaultNHttpClientConnection
                     this.session.close();
                     this.status = CLOSED;
                     resetOutput();
-                    return;
-                } else {
-                    if (this.contentEncoder != null) {
-                        handler.outputReady(this, this.contentEncoder);
-                        if (this.contentEncoder.isCompleted()) {
-                            resetOutput();
-                        }
-                    }
                 }
-
-                if (this.contentEncoder == null && !this.outbuf.hasData()) {
-                    if (this.status == CLOSING) {
-                        this.session.close();
-                        this.status = CLOSED;
-                    }
-                    if (this.status != CLOSED) {
-                        this.session.clearEvent(EventMask.WRITE);
-                        handler.requestReady(this);
-                    }
+                if (this.contentEncoder == null && this.status != CLOSED) {
+                    this.session.clearEvent(EventMask.WRITE);
                 }
             }
-        } catch (Exception ex) {
+        } catch (final Exception ex) {
             handler.exception(this, ex);
         } finally {
-            // Finally set buffered output flag
+            // Finally set the buffered output flag
             this.hasBufferedOutput = this.outbuf.hasData();
         }
     }
 
     public void submitRequest(final HttpRequest request) throws IOException, HttpException {
-        if (request == null) {
-            throw new IllegalArgumentException("HTTP request may not be null");
-        }
+        Args.notNull(request, "HTTP request");
         assertNotClosed();
         if (this.request != null) {
             throw new HttpException("Request already submitted");
diff --git a/httpcore-nio/src/main/java/org/apache/http/impl/nio/DefaultNHttpClientConnectionFactory.java b/httpcore-nio/src/main/java/org/apache/http/impl/nio/DefaultNHttpClientConnectionFactory.java
index 7dc9fbc..7560c79 100644
--- a/httpcore-nio/src/main/java/org/apache/http/impl/nio/DefaultNHttpClientConnectionFactory.java
+++ b/httpcore-nio/src/main/java/org/apache/http/impl/nio/DefaultNHttpClientConnectionFactory.java
@@ -26,63 +26,136 @@
  */
 package org.apache.http.impl.nio;
 
+import org.apache.http.HttpRequest;
+import org.apache.http.HttpResponse;
 import org.apache.http.HttpResponseFactory;
 import org.apache.http.annotation.Immutable;
+import org.apache.http.config.ConnectionConfig;
+import org.apache.http.entity.ContentLengthStrategy;
+import org.apache.http.impl.ConnSupport;
 import org.apache.http.impl.DefaultHttpResponseFactory;
-import org.apache.http.nio.NHttpClientConnection;
+import org.apache.http.impl.nio.codecs.DefaultHttpResponseParserFactory;
 import org.apache.http.nio.NHttpConnectionFactory;
+import org.apache.http.nio.NHttpMessageParserFactory;
+import org.apache.http.nio.NHttpMessageWriterFactory;
 import org.apache.http.nio.reactor.IOSession;
 import org.apache.http.nio.util.ByteBufferAllocator;
 import org.apache.http.nio.util.HeapByteBufferAllocator;
-import org.apache.http.params.HttpConnectionParams;
+import org.apache.http.params.HttpParamConfig;
 import org.apache.http.params.HttpParams;
+import org.apache.http.util.Args;
 
 /**
- * Factory for plain (non-encrypted), non-blocking {@link NHttpClientConnection}s.
- * <p>
- * The following parameters can be used to customize the behavior of this
- * class:
- * <ul>
- *  <li>{@link org.apache.http.params.CoreProtocolPNames#HTTP_ELEMENT_CHARSET}</li>
- *  <li>{@link org.apache.http.params.CoreConnectionPNames#SO_TIMEOUT}</li>
- *  <li>{@link org.apache.http.params.CoreConnectionPNames#SOCKET_BUFFER_SIZE}</li>
- *  <li>{@link org.apache.http.params.CoreConnectionPNames#MAX_HEADER_COUNT}</li>
- *  <li>{@link org.apache.http.params.CoreConnectionPNames#MAX_LINE_LENGTH}</li>
- * </ul>
+ * Default factory for plain (non-encrypted), non-blocking
+ * {@link org.apache.http.nio.NHttpClientConnection}s.
  *
  * @since 4.2
  */
+ at SuppressWarnings("deprecation")
 @Immutable
 public class DefaultNHttpClientConnectionFactory
     implements NHttpConnectionFactory<DefaultNHttpClientConnection> {
 
-    private final HttpResponseFactory responseFactory;
+    public static final DefaultNHttpClientConnectionFactory INSTANCE = new DefaultNHttpClientConnectionFactory();
+
+    private final ContentLengthStrategy incomingContentStrategy;
+    private final ContentLengthStrategy outgoingContentStrategy;
+    private final NHttpMessageParserFactory<HttpResponse> responseParserFactory;
+    private final NHttpMessageWriterFactory<HttpRequest> requestWriterFactory;
     private final ByteBufferAllocator allocator;
-    private final HttpParams params;
+    private final ConnectionConfig cconfig;
 
+    /**
+     * @deprecated (4.3) use {@link
+     *   DefaultNHttpClientConnectionFactory#DefaultNHttpClientConnectionFactory(
+     *      NHttpMessageParserFactory, NHttpMessageWriterFactory, ByteBufferAllocator,
+     *      ConnectionConfig)}
+     */
+    @Deprecated
     public DefaultNHttpClientConnectionFactory(
             final HttpResponseFactory responseFactory,
             final ByteBufferAllocator allocator,
             final HttpParams params) {
         super();
-        if (responseFactory == null) {
-            throw new IllegalArgumentException("HTTP response factory may not be null");
-        }
-        if (allocator == null) {
-            throw new IllegalArgumentException("Byte buffer allocator may not be null");
-        }
-        if (params == null) {
-            throw new IllegalArgumentException("HTTP parameters may not be null");
-        }
-        this.responseFactory = responseFactory;
+        Args.notNull(responseFactory, "HTTP response factory");
+        Args.notNull(allocator, "Byte buffer allocator");
+        Args.notNull(params, "HTTP parameters");
         this.allocator = allocator;
-        this.params = params;
+        this.incomingContentStrategy = null;
+        this.outgoingContentStrategy = null;
+        this.responseParserFactory = new DefaultHttpResponseParserFactory(null, responseFactory);
+        this.requestWriterFactory = null;
+        this.cconfig = HttpParamConfig.getConnectionConfig(params);
     }
 
+    /**
+     * @deprecated (4.3) use {@link
+     *   DefaultNHttpClientConnectionFactory#DefaultNHttpClientConnectionFactory(
+     *     ConnectionConfig)}
+     */
+    @Deprecated
     public DefaultNHttpClientConnectionFactory(final HttpParams params) {
-        this(new DefaultHttpResponseFactory(), new HeapByteBufferAllocator(), params);
+        this(DefaultHttpResponseFactory.INSTANCE, HeapByteBufferAllocator.INSTANCE, params);
+    }
+
+    /**
+     * @since 4.3
+     */
+    public DefaultNHttpClientConnectionFactory(
+            final ContentLengthStrategy incomingContentStrategy,
+            final ContentLengthStrategy outgoingContentStrategy,
+            final NHttpMessageParserFactory<HttpResponse> responseParserFactory,
+            final NHttpMessageWriterFactory<HttpRequest> requestWriterFactory,
+            final ByteBufferAllocator allocator,
+            final ConnectionConfig cconfig) {
+        super();
+        this.incomingContentStrategy = incomingContentStrategy;
+        this.outgoingContentStrategy = outgoingContentStrategy;
+        this.responseParserFactory = responseParserFactory;
+        this.requestWriterFactory = requestWriterFactory;
+        this.allocator = allocator;
+        this.cconfig = cconfig != null ? cconfig : ConnectionConfig.DEFAULT;
+    }
+
+    /**
+     * @since 4.3
+     */
+    public DefaultNHttpClientConnectionFactory(
+            final NHttpMessageParserFactory<HttpResponse> responseParserFactory,
+            final NHttpMessageWriterFactory<HttpRequest> requestWriterFactory,
+            final ByteBufferAllocator allocator,
+            final ConnectionConfig cconfig) {
+        this(null, null, responseParserFactory, requestWriterFactory, allocator, cconfig);
+    }
+
+    /**
+     * @since 4.3
+     */
+    public DefaultNHttpClientConnectionFactory(
+            final NHttpMessageParserFactory<HttpResponse> responseParserFactory,
+            final NHttpMessageWriterFactory<HttpRequest> requestWriterFactory,
+            final ConnectionConfig cconfig) {
+        this(null, null, responseParserFactory, requestWriterFactory, null, cconfig);
+    }
+
+    /**
+     * @since 4.3
+     */
+    public DefaultNHttpClientConnectionFactory(final ConnectionConfig cconfig) {
+        this(null, null, null, null, null, cconfig);
+    }
+
+    /**
+     * @since 4.3
+     */
+    public DefaultNHttpClientConnectionFactory() {
+        this(null, null, null, null, null, null);
     }
 
+    /**
+     * @deprecated (4.3) no longer used.
+     */
+    @Deprecated
     protected DefaultNHttpClientConnection createConnection(
             final IOSession session,
             final HttpResponseFactory responseFactory,
@@ -92,10 +165,18 @@ public class DefaultNHttpClientConnectionFactory
     }
 
     public DefaultNHttpClientConnection createConnection(final IOSession session) {
-        DefaultNHttpClientConnection conn = createConnection(session, this.responseFactory, this.allocator, this.params);
-        int timeout = HttpConnectionParams.getSoTimeout(this.params);
-        conn.setSocketTimeout(timeout);
-        return conn;
+        return new DefaultNHttpClientConnection(
+                session,
+                this.cconfig.getBufferSize(),
+                this.cconfig.getFragmentSizeHint(),
+                this.allocator,
+                ConnSupport.createDecoder(this.cconfig),
+                ConnSupport.createEncoder(this.cconfig),
+                this.cconfig.getMessageConstraints(),
+                this.incomingContentStrategy,
+                this.outgoingContentStrategy,
+                this.requestWriterFactory,
+                this.responseParserFactory);
     }
 
 }
diff --git a/httpcore-nio/src/main/java/org/apache/http/impl/nio/DefaultNHttpServerConnection.java b/httpcore-nio/src/main/java/org/apache/http/impl/nio/DefaultNHttpServerConnection.java
index 28b4046..9bebee6 100644
--- a/httpcore-nio/src/main/java/org/apache/http/impl/nio/DefaultNHttpServerConnection.java
+++ b/httpcore-nio/src/main/java/org/apache/http/impl/nio/DefaultNHttpServerConnection.java
@@ -29,6 +29,8 @@ package org.apache.http.impl.nio;
 
 import java.io.IOException;
 import java.nio.channels.SelectionKey;
+import java.nio.charset.CharsetDecoder;
+import java.nio.charset.CharsetEncoder;
 
 import org.apache.http.HttpEntity;
 import org.apache.http.HttpEntityEnclosingRequest;
@@ -37,35 +39,34 @@ import org.apache.http.HttpRequest;
 import org.apache.http.HttpRequestFactory;
 import org.apache.http.HttpResponse;
 import org.apache.http.annotation.NotThreadSafe;
+import org.apache.http.config.MessageConstraints;
 import org.apache.http.entity.ContentLengthStrategy;
 import org.apache.http.impl.entity.DisallowIdentityContentLengthStrategy;
 import org.apache.http.impl.entity.LaxContentLengthStrategy;
+import org.apache.http.impl.entity.StrictContentLengthStrategy;
 import org.apache.http.impl.nio.codecs.DefaultHttpRequestParser;
+import org.apache.http.impl.nio.codecs.DefaultHttpRequestParserFactory;
 import org.apache.http.impl.nio.codecs.DefaultHttpResponseWriter;
+import org.apache.http.impl.nio.codecs.DefaultHttpResponseWriterFactory;
 import org.apache.http.nio.NHttpMessageParser;
+import org.apache.http.nio.NHttpMessageParserFactory;
 import org.apache.http.nio.NHttpMessageWriter;
-import org.apache.http.nio.NHttpServerConnection;
-import org.apache.http.nio.NHttpServerIOTarget;
+import org.apache.http.nio.NHttpMessageWriterFactory;
 import org.apache.http.nio.NHttpServerEventHandler;
+import org.apache.http.nio.NHttpServerIOTarget;
 import org.apache.http.nio.NHttpServiceHandler;
 import org.apache.http.nio.reactor.EventMask;
 import org.apache.http.nio.reactor.IOSession;
 import org.apache.http.nio.reactor.SessionInputBuffer;
 import org.apache.http.nio.reactor.SessionOutputBuffer;
 import org.apache.http.nio.util.ByteBufferAllocator;
+import org.apache.http.params.HttpParamConfig;
 import org.apache.http.params.HttpParams;
+import org.apache.http.util.Args;
 
 /**
- * Default implementation of the {@link NHttpServerConnection} interface.
- * <p>
- * The following parameters can be used to customize the behavior of this
- * class:
- * <ul>
- *  <li>{@link org.apache.http.params.CoreProtocolPNames#HTTP_ELEMENT_CHARSET}</li>
- *  <li>{@link org.apache.http.params.CoreConnectionPNames#SOCKET_BUFFER_SIZE}</li>
- *  <li>{@link org.apache.http.params.CoreConnectionPNames#MAX_HEADER_COUNT}</li>
- *  <li>{@link org.apache.http.params.CoreConnectionPNames#MAX_LINE_LENGTH}</li>
- * </ul>
+ * Default implementation of the {@link org.apache.http.nio.NHttpServerConnection}
+ * interface.
  *
  * @since 4.0
  */
@@ -84,21 +85,98 @@ public class DefaultNHttpServerConnection
      * @param requestFactory HTTP request factory.
      * @param allocator byte buffer allocator.
      * @param params HTTP parameters.
+     *
+     * @deprecated (4.3) use {@link DefaultNHttpServerConnection#DefaultNHttpServerConnection(
+     *   IOSession, int, int, ByteBufferAllocator, CharsetDecoder, CharsetEncoder,
+     *   MessageConstraints, ContentLengthStrategy, ContentLengthStrategy,
+     *   NHttpMessageParserFactory, NHttpMessageWriterFactory)}
      */
+    @Deprecated
     public DefaultNHttpServerConnection(
             final IOSession session,
             final HttpRequestFactory requestFactory,
             final ByteBufferAllocator allocator,
             final HttpParams params) {
         super(session, allocator, params);
-        if (requestFactory == null) {
-            throw new IllegalArgumentException("Request factory may not be null");
-        }
+        Args.notNull(requestFactory, "Request factory");
         this.requestParser = createRequestParser(this.inbuf, requestFactory, params);
         this.responseWriter = createResponseWriter(this.outbuf, params);
     }
 
+    /**
+     * Creates new instance DefaultNHttpServerConnection given the underlying I/O session.
+     *
+     * @param session the underlying I/O session.
+     * @param buffersize buffer size. Must be a positive number.
+     * @param fragmentSizeHint fragment size hint.
+     * @param allocator memory allocator.
+     *   If <code>null</code> {@link org.apache.http.nio.util.HeapByteBufferAllocator#INSTANCE}
+     *   will be used.
+     * @param chardecoder decoder to be used for decoding HTTP protocol elements.
+     *   If <code>null</code> simple type cast will be used for byte to char conversion.
+     * @param charencoder encoder to be used for encoding HTTP protocol elements.
+     *   If <code>null</code> simple type cast will be used for char to byte conversion.
+     * @param constraints Message constraints. If <code>null</code>
+     *   {@link MessageConstraints#DEFAULT} will be used.
+     * @param incomingContentStrategy incoming content length strategy. If <code>null</code>
+     *   {@link DisallowIdentityContentLengthStrategy#INSTANCE} will be used.
+     * @param outgoingContentStrategy outgoing content length strategy. If <code>null</code>
+     *   {@link StrictContentLengthStrategy#INSTANCE} will be used.
+     * @param requestParserFactory request parser factory. If <code>null</code>
+     *   {@link DefaultHttpRequestParserFactory#INSTANCE} will be used.
+     * @param responseWriterFactory response writer factory. If <code>null</code>
+     *   {@link DefaultHttpResponseWriterFactory#INSTANCE} will be used.
+     *
+     * @since 4.3
+     */
+    public DefaultNHttpServerConnection(
+            final IOSession session,
+            final int buffersize,
+            final int fragmentSizeHint,
+            final ByteBufferAllocator allocator,
+            final CharsetDecoder chardecoder,
+            final CharsetEncoder charencoder,
+            final MessageConstraints constraints,
+            final ContentLengthStrategy incomingContentStrategy,
+            final ContentLengthStrategy outgoingContentStrategy,
+            final NHttpMessageParserFactory<HttpRequest> requestParserFactory,
+            final NHttpMessageWriterFactory<HttpResponse> responseWriterFactory) {
+        super(session, buffersize, fragmentSizeHint, allocator, chardecoder, charencoder,
+                incomingContentStrategy != null ? incomingContentStrategy :
+                    DisallowIdentityContentLengthStrategy.INSTANCE,
+                outgoingContentStrategy != null ? outgoingContentStrategy :
+                    StrictContentLengthStrategy.INSTANCE);
+        this.requestParser = (requestParserFactory != null ? requestParserFactory :
+            DefaultHttpRequestParserFactory.INSTANCE).create(this.inbuf, constraints);
+        this.responseWriter = (responseWriterFactory != null ? responseWriterFactory :
+            DefaultHttpResponseWriterFactory.INSTANCE).create(this.outbuf);
+    }
+
+    /**
+     * @since 4.3
+     */
+    public DefaultNHttpServerConnection(
+            final IOSession session,
+            final int buffersize,
+            final CharsetDecoder chardecoder,
+            final CharsetEncoder charencoder,
+            final MessageConstraints constraints) {
+        this(session, buffersize, buffersize, null, chardecoder, charencoder, constraints,
+                null, null, null, null);
+    }
+
+    /**
+     * @since 4.3
+     */
+    public DefaultNHttpServerConnection(final IOSession session, final int buffersize) {
+        this(session, buffersize, buffersize, null, null, null, null, null, null, null, null);
+    }
+
+    /**
+     * @deprecated (4.3) use constructor.
+     */
     @Override
+    @Deprecated
     protected ContentLengthStrategy createIncomingContentStrategy() {
         return new DisallowIdentityContentLengthStrategy(new LaxContentLengthStrategy(0));
     }
@@ -111,13 +189,16 @@ public class DefaultNHttpServerConnection
      * a different implementation of the {@link NHttpMessageParser} interface.
      *
      * @return HTTP response parser.
+     *
+     * @deprecated (4.3) use constructor.
      */
+    @Deprecated
     protected NHttpMessageParser<HttpRequest> createRequestParser(
             final SessionInputBuffer buffer,
             final HttpRequestFactory requestFactory,
             final HttpParams params) {
-        // override in derived class to specify a line parser
-        return new DefaultHttpRequestParser(buffer, null, requestFactory, params);
+        final MessageConstraints constraints = HttpParamConfig.getMessageConstraints(params);
+        return new DefaultHttpRequestParser(buffer, null, requestFactory, constraints);
     }
 
     /**
@@ -129,12 +210,15 @@ public class DefaultNHttpServerConnection
      * a different implementation of the {@link NHttpMessageWriter} interface.
      *
      * @return HTTP response parser.
+     *
+     * @deprecated (4.3) use constructor.
      */
+    @Deprecated
     protected NHttpMessageWriter<HttpResponse> createResponseWriter(
             final SessionOutputBuffer buffer,
             final HttpParams params) {
         // override in derived class to specify a line formatter
-        return new DefaultHttpResponseWriter(buffer, null, params);
+        return new DefaultHttpResponseWriter(buffer, null);
     }
 
     /**
@@ -142,13 +226,13 @@ public class DefaultNHttpServerConnection
      */
     protected void onRequestReceived(final HttpRequest request) {
     }
-    
+
     /**
      * @since 4.2
      */
     protected void onResponseSubmitted(final HttpResponse response) {
     }
-    
+
     public void resetInput() {
         this.request = null;
         this.contentDecoder = null;
@@ -179,7 +263,7 @@ public class DefaultNHttpServerConnection
                 if (this.request != null) {
                     if (this.request instanceof HttpEntityEnclosingRequest) {
                         // Receive incoming entity
-                        HttpEntity entity = prepareDecoder(this.request);
+                        final HttpEntity entity = prepareDecoder(this.request);
                         ((HttpEntityEnclosingRequest)this.request).setEntity(entity);
                     }
                     this.connMetrics.incrementRequestCount();
@@ -195,18 +279,26 @@ public class DefaultNHttpServerConnection
                     handler.endOfInput(this);
                 }
             }
-            if (this.contentDecoder != null && (this.session.getEventMask() & SelectionKey.OP_READ) > 0) {
-                handler.inputReady(this, this.contentDecoder);
-                if (this.contentDecoder.isCompleted()) {
-                    // Request entity received
-                    // Ready to receive a new request
-                    resetInput();
+            if (this.contentDecoder != null) {
+                // Loop until there is interest in input,
+                // decoder is not done and there is buffered session data
+                while ((this.session.getEventMask() & SelectionKey.OP_READ) > 0) {
+                    handler.inputReady(this, this.contentDecoder);
+                    if (this.contentDecoder.isCompleted()) {
+                        // Response entity received
+                        // Ready to receive a new response
+                        resetInput();
+                        break;
+                    }
+                    if (!this.inbuf.hasData()) {
+                        break;
+                    }
                 }
             }
-        } catch (HttpException ex) {
+        } catch (final HttpException ex) {
             resetInput();
             handler.exception(this, ex);
-        } catch (Exception ex) {
+        } catch (final Exception ex) {
             handler.exception(this, ex);
         } finally {
             // Finally set buffered input flag
@@ -216,8 +308,19 @@ public class DefaultNHttpServerConnection
 
     public void produceOutput(final NHttpServerEventHandler handler) {
         try {
+            if (this.status == ACTIVE) {
+                if (this.contentEncoder == null) {
+                    handler.responseReady(this);
+                }
+                if (this.contentEncoder != null) {
+                    handler.outputReady(this, this.contentEncoder);
+                    if (this.contentEncoder.isCompleted()) {
+                        resetOutput();
+                    }
+                }
+            }
             if (this.outbuf.hasData()) {
-                int bytesWritten = this.outbuf.flush(this.session.channel());
+                final int bytesWritten = this.outbuf.flush(this.session.channel());
                 if (bytesWritten > 0) {
                     this.outTransportMetrics.incrementBytesTransferred(bytesWritten);
                 }
@@ -227,28 +330,12 @@ public class DefaultNHttpServerConnection
                     this.session.close();
                     this.status = CLOSED;
                     resetOutput();
-                    return;
-                } else {
-                    if (this.contentEncoder != null) {
-                        handler.outputReady(this, this.contentEncoder);
-                        if (this.contentEncoder.isCompleted()) {
-                            resetOutput();
-                        }
-                    }
                 }
-
-                if (this.contentEncoder == null && !this.outbuf.hasData()) {
-                    if (this.status == CLOSING) {
-                        this.session.close();
-                        this.status = CLOSED;
-                    }
-                    if (this.status != CLOSED) {
-                        this.session.clearEvent(EventMask.WRITE);
-                        handler.responseReady(this);
-                    }
+                if (this.contentEncoder == null && this.status != CLOSED) {
+                    this.session.clearEvent(EventMask.WRITE);
                 }
             }
-        } catch (Exception ex) {
+        } catch (final Exception ex) {
             handler.exception(this, ex);
         } finally {
             // Finally set the buffered output flag
@@ -257,9 +344,7 @@ public class DefaultNHttpServerConnection
     }
 
     public void submitResponse(final HttpResponse response) throws IOException, HttpException {
-        if (response == null) {
-            throw new IllegalArgumentException("HTTP response may not be null");
-        }
+        Args.notNull(response, "HTTP response");
         assertNotClosed();
         if (this.response != null) {
             throw new HttpException("Response already submitted");
@@ -287,7 +372,7 @@ public class DefaultNHttpServerConnection
         consumeInput(new NHttpServerEventHandlerAdaptor(handler));
     }
 
-    public void produceOutput(NHttpServiceHandler handler) {
+    public void produceOutput(final NHttpServiceHandler handler) {
         produceOutput(new NHttpServerEventHandlerAdaptor(handler));
     }
 
diff --git a/httpcore-nio/src/main/java/org/apache/http/impl/nio/DefaultNHttpServerConnectionFactory.java b/httpcore-nio/src/main/java/org/apache/http/impl/nio/DefaultNHttpServerConnectionFactory.java
index d842448..12726d8 100644
--- a/httpcore-nio/src/main/java/org/apache/http/impl/nio/DefaultNHttpServerConnectionFactory.java
+++ b/httpcore-nio/src/main/java/org/apache/http/impl/nio/DefaultNHttpServerConnectionFactory.java
@@ -26,63 +26,79 @@
  */
 package org.apache.http.impl.nio;
 
+import org.apache.http.HttpRequest;
 import org.apache.http.HttpRequestFactory;
+import org.apache.http.HttpResponse;
 import org.apache.http.annotation.Immutable;
+import org.apache.http.config.ConnectionConfig;
+import org.apache.http.entity.ContentLengthStrategy;
+import org.apache.http.impl.ConnSupport;
 import org.apache.http.impl.DefaultHttpRequestFactory;
+import org.apache.http.impl.nio.codecs.DefaultHttpRequestParserFactory;
 import org.apache.http.nio.NHttpConnectionFactory;
-import org.apache.http.nio.NHttpServerConnection;
+import org.apache.http.nio.NHttpMessageParserFactory;
+import org.apache.http.nio.NHttpMessageWriterFactory;
 import org.apache.http.nio.reactor.IOSession;
 import org.apache.http.nio.util.ByteBufferAllocator;
 import org.apache.http.nio.util.HeapByteBufferAllocator;
-import org.apache.http.params.HttpConnectionParams;
+import org.apache.http.params.HttpParamConfig;
 import org.apache.http.params.HttpParams;
+import org.apache.http.util.Args;
 
 /**
- * Factory for plain (non-encrypted), non-blocking {@link NHttpServerConnection}s.
- * <p>
- * The following parameters can be used to customize the behavior of this
- * class:
- * <ul>
- *  <li>{@link org.apache.http.params.CoreProtocolPNames#HTTP_ELEMENT_CHARSET}</li>
- *  <li>{@link org.apache.http.params.CoreConnectionPNames#SO_TIMEOUT}</li>
- *  <li>{@link org.apache.http.params.CoreConnectionPNames#SOCKET_BUFFER_SIZE}</li>
- *  <li>{@link org.apache.http.params.CoreConnectionPNames#MAX_HEADER_COUNT}</li>
- *  <li>{@link org.apache.http.params.CoreConnectionPNames#MAX_LINE_LENGTH}</li>
- * </ul>
+ * Default factory for plain (non-encrypted), non-blocking
+ * {@link org.apache.http.nio.NHttpServerConnection}s.
  *
  * @since 4.2
  */
+ at SuppressWarnings("deprecation")
 @Immutable
 public class DefaultNHttpServerConnectionFactory
     implements NHttpConnectionFactory<DefaultNHttpServerConnection> {
 
-    private final HttpRequestFactory requestFactory;
+    private final ContentLengthStrategy incomingContentStrategy;
+    private final ContentLengthStrategy outgoingContentStrategy;
+    private final NHttpMessageParserFactory<HttpRequest> requestParserFactory;
+    private final NHttpMessageWriterFactory<HttpResponse> responseWriterFactory;
     private final ByteBufferAllocator allocator;
-    private final HttpParams params;
+    private final ConnectionConfig cconfig;
 
+    /**
+     * @deprecated (4.3) use {@link
+     *   DefaultNHttpServerConnectionFactory#DefaultNHttpServerConnectionFactory(
+     *      ByteBufferAllocator, NHttpMessageParserFactory, NHttpMessageWriterFactory,
+     *      ConnectionConfig)}
+     */
+    @Deprecated
     public DefaultNHttpServerConnectionFactory(
             final HttpRequestFactory requestFactory,
             final ByteBufferAllocator allocator,
             final HttpParams params) {
         super();
-        if (requestFactory == null) {
-            throw new IllegalArgumentException("HTTP request factory may not be null");
-        }
-        if (allocator == null) {
-            throw new IllegalArgumentException("Byte buffer allocator may not be null");
-        }
-        if (params == null) {
-            throw new IllegalArgumentException("HTTP parameters may not be null");
-        }
-        this.requestFactory = requestFactory;
+        Args.notNull(requestFactory, "HTTP request factory");
+        Args.notNull(allocator, "Byte buffer allocator");
+        Args.notNull(params, "HTTP parameters");
+        this.incomingContentStrategy = null;
+        this.outgoingContentStrategy = null;
+        this.requestParserFactory = new DefaultHttpRequestParserFactory(null, requestFactory);
+        this.responseWriterFactory = null;
         this.allocator = allocator;
-        this.params = params;
+        this.cconfig = HttpParamConfig.getConnectionConfig(params);
     }
 
+    /**
+     * @deprecated (4.3) use {@link
+     *   DefaultNHttpServerConnectionFactory#DefaultNHttpServerConnectionFactory(ConnectionConfig)}
+     */
+    @Deprecated
     public DefaultNHttpServerConnectionFactory(final HttpParams params) {
-        this(new DefaultHttpRequestFactory(), new HeapByteBufferAllocator(), params);
+        this(DefaultHttpRequestFactory.INSTANCE, HeapByteBufferAllocator.INSTANCE, params);
     }
 
+    /**
+     * @deprecated (4.3) no longer used.
+     */
+    @Deprecated
     protected DefaultNHttpServerConnection createConnection(
             final IOSession session,
             final HttpRequestFactory requestFactory,
@@ -91,12 +107,62 @@ public class DefaultNHttpServerConnectionFactory
         return new DefaultNHttpServerConnection(session, requestFactory, allocator, params);
     }
 
+    /**
+     * @since 4.3
+     */
+    public DefaultNHttpServerConnectionFactory(
+            final ContentLengthStrategy incomingContentStrategy,
+            final ContentLengthStrategy outgoingContentStrategy,
+            final NHttpMessageParserFactory<HttpRequest> requestParserFactory,
+            final NHttpMessageWriterFactory<HttpResponse> responseWriterFactory,
+            final ByteBufferAllocator allocator,
+            final ConnectionConfig cconfig) {
+        super();
+        this.incomingContentStrategy = incomingContentStrategy;
+        this.outgoingContentStrategy = outgoingContentStrategy;
+        this.requestParserFactory = requestParserFactory;
+        this.responseWriterFactory = responseWriterFactory;
+        this.allocator = allocator;
+        this.cconfig = cconfig != null ? cconfig : ConnectionConfig.DEFAULT;
+    }
+
+    /**
+     * @since 4.3
+     */
+    public DefaultNHttpServerConnectionFactory(
+            final ByteBufferAllocator allocator,
+            final NHttpMessageParserFactory<HttpRequest> requestParserFactory,
+            final NHttpMessageWriterFactory<HttpResponse> responseWriterFactory,
+            final ConnectionConfig cconfig) {
+        this(null, null, requestParserFactory, responseWriterFactory, allocator, cconfig);
+    }
+
+    /**
+     * @since 4.3
+     */
+    public DefaultNHttpServerConnectionFactory(final ConnectionConfig config) {
+        this(null, null, null, null, null, config);
+    }
+
+    /**
+     * @since 4.3
+     */
+    public DefaultNHttpServerConnectionFactory() {
+        this(null, null, null, null, null, null);
+    }
+
     public DefaultNHttpServerConnection createConnection(final IOSession session) {
-        DefaultNHttpServerConnection conn = createConnection(
-                session, this.requestFactory, this.allocator, this.params);
-        int timeout = HttpConnectionParams.getSoTimeout(this.params);
-        conn.setSocketTimeout(timeout);
-        return conn;
+        return new DefaultNHttpServerConnection(session,
+                this.cconfig.getBufferSize(),
+                this.cconfig.getFragmentSizeHint(),
+                this.allocator,
+                ConnSupport.createDecoder(this.cconfig),
+                ConnSupport.createEncoder(this.cconfig),
+                this.cconfig.getMessageConstraints(),
+                this.incomingContentStrategy,
+                this.outgoingContentStrategy,
+                this.requestParserFactory,
+                this.responseWriterFactory);
     }
 
 }
diff --git a/httpcore-nio/src/main/java/org/apache/http/impl/nio/NHttpClientEventHandlerAdaptor.java b/httpcore-nio/src/main/java/org/apache/http/impl/nio/NHttpClientEventHandlerAdaptor.java
index 7978a92..93374e1 100644
--- a/httpcore-nio/src/main/java/org/apache/http/impl/nio/NHttpClientEventHandlerAdaptor.java
+++ b/httpcore-nio/src/main/java/org/apache/http/impl/nio/NHttpClientEventHandlerAdaptor.java
@@ -33,8 +33,8 @@ import org.apache.http.HttpException;
 import org.apache.http.nio.ContentDecoder;
 import org.apache.http.nio.ContentEncoder;
 import org.apache.http.nio.NHttpClientConnection;
-import org.apache.http.nio.NHttpClientHandler;
 import org.apache.http.nio.NHttpClientEventHandler;
+import org.apache.http.nio.NHttpClientHandler;
 
 /**
  * @deprecated (4.2)
diff --git a/httpcore-nio/src/main/java/org/apache/http/impl/nio/NHttpConnectionBase.java b/httpcore-nio/src/main/java/org/apache/http/impl/nio/NHttpConnectionBase.java
index 781282d..e863708 100644
--- a/httpcore-nio/src/main/java/org/apache/http/impl/nio/NHttpConnectionBase.java
+++ b/httpcore-nio/src/main/java/org/apache/http/impl/nio/NHttpConnectionBase.java
@@ -34,8 +34,13 @@ import java.net.Socket;
 import java.net.SocketAddress;
 import java.nio.channels.ReadableByteChannel;
 import java.nio.channels.WritableByteChannel;
+import java.nio.charset.Charset;
+import java.nio.charset.CharsetDecoder;
+import java.nio.charset.CharsetEncoder;
+import java.nio.charset.CodingErrorAction;
 
 import org.apache.http.ConnectionClosedException;
+import org.apache.http.Consts;
 import org.apache.http.Header;
 import org.apache.http.HttpConnectionMetrics;
 import org.apache.http.HttpEntity;
@@ -51,9 +56,6 @@ import org.apache.http.impl.HttpConnectionMetricsImpl;
 import org.apache.http.impl.entity.LaxContentLengthStrategy;
 import org.apache.http.impl.entity.StrictContentLengthStrategy;
 import org.apache.http.impl.io.HttpTransportMetricsImpl;
-import org.apache.http.nio.ContentDecoder;
-import org.apache.http.nio.ContentEncoder;
-import org.apache.http.nio.NHttpConnection;
 import org.apache.http.impl.nio.codecs.ChunkDecoder;
 import org.apache.http.impl.nio.codecs.ChunkEncoder;
 import org.apache.http.impl.nio.codecs.IdentityDecoder;
@@ -63,6 +65,9 @@ import org.apache.http.impl.nio.codecs.LengthDelimitedEncoder;
 import org.apache.http.impl.nio.reactor.SessionInputBufferImpl;
 import org.apache.http.impl.nio.reactor.SessionOutputBufferImpl;
 import org.apache.http.io.HttpTransportMetrics;
+import org.apache.http.nio.ContentDecoder;
+import org.apache.http.nio.ContentEncoder;
+import org.apache.http.nio.NHttpConnection;
 import org.apache.http.nio.reactor.EventMask;
 import org.apache.http.nio.reactor.IOSession;
 import org.apache.http.nio.reactor.SessionBufferStatus;
@@ -70,25 +75,22 @@ import org.apache.http.nio.reactor.SessionInputBuffer;
 import org.apache.http.nio.reactor.SessionOutputBuffer;
 import org.apache.http.nio.reactor.SocketAccessor;
 import org.apache.http.nio.util.ByteBufferAllocator;
-import org.apache.http.params.HttpConnectionParams;
+import org.apache.http.params.CoreConnectionPNames;
+import org.apache.http.params.CoreProtocolPNames;
 import org.apache.http.params.HttpParams;
 import org.apache.http.protocol.HTTP;
 import org.apache.http.protocol.HttpContext;
+import org.apache.http.util.Args;
+import org.apache.http.util.CharsetUtils;
+import org.apache.http.util.NetUtils;
 
 /**
- * This class serves as a base for all {@link NHttpConnection} implementations
- * and implements functionality common to both client and server
- * HTTP connections.
- * <p>
- * The following parameters can be used to customize the behavior of this
- * class:
- * <ul>
- *  <li>{@link org.apache.http.params.CoreProtocolPNames#HTTP_ELEMENT_CHARSET}</li>
- *  <li>{@link org.apache.http.params.CoreConnectionPNames#SOCKET_BUFFER_SIZE}</li>
- * </ul>
+ * This class serves as a base for all {@link NHttpConnection} implementations and provides
+ * functionality common to both client and server HTTP connections.
  *
  * @since 4.0
  */
+ at SuppressWarnings("deprecation")
 @NotThreadSafe
 public class NHttpConnectionBase
         implements NHttpConnection, HttpInetConnection, SessionBufferStatus, SocketAccessor {
@@ -98,6 +100,7 @@ public class NHttpConnectionBase
 
     protected final SessionInputBufferImpl inbuf;
     protected final SessionOutputBufferImpl outbuf;
+    private final int fragmentSizeHint;
 
     protected final HttpTransportMetricsImpl inTransportMetrics;
     protected final HttpTransportMetricsImpl outTransportMetrics;
@@ -121,20 +124,21 @@ public class NHttpConnectionBase
      * @param session the underlying I/O session.
      * @param allocator byte buffer allocator.
      * @param params HTTP parameters.
+     *
+     * @deprecated (4.3) use
+     *   {@link NHttpConnectionBase#NHttpConnectionBase(IOSession, int, int, ByteBufferAllocator,
+     *   CharsetDecoder, CharsetEncoder, ContentLengthStrategy, ContentLengthStrategy)}
      */
+    @Deprecated
     public NHttpConnectionBase(
             final IOSession session,
             final ByteBufferAllocator allocator,
             final HttpParams params) {
         super();
-        if (session == null) {
-            throw new IllegalArgumentException("I/O session may not be null");
-        }
-        if (params == null) {
-            throw new IllegalArgumentException("HTTP params may not be null");
-        }
+        Args.notNull(session, "I/O session");
+        Args.notNull(params, "HTTP params");
 
-        int buffersize = HttpConnectionParams.getSocketBufferSize(params);
+        int buffersize = params.getIntParameter(CoreConnectionPNames.SOCKET_BUFFER_SIZE, -1);
         if (buffersize <= 0) {
             buffersize = 4096;
         }
@@ -143,8 +147,24 @@ public class NHttpConnectionBase
             linebuffersize = 512;
         }
 
-        this.inbuf = new SessionInputBufferImpl(buffersize, linebuffersize, allocator, params);
-        this.outbuf = new SessionOutputBufferImpl(buffersize, linebuffersize, allocator, params);
+        CharsetDecoder decoder = null;
+        CharsetEncoder encoder = null;
+        Charset charset = CharsetUtils.lookup(
+                (String) params.getParameter(CoreProtocolPNames.HTTP_ELEMENT_CHARSET));
+        if (charset != null) {
+            charset = Consts.ASCII;
+            decoder = charset.newDecoder();
+            encoder = charset.newEncoder();
+            final CodingErrorAction malformedCharAction = (CodingErrorAction) params.getParameter(
+                    CoreProtocolPNames.HTTP_MALFORMED_INPUT_ACTION);
+            final CodingErrorAction unmappableCharAction = (CodingErrorAction) params.getParameter(
+                    CoreProtocolPNames.HTTP_UNMAPPABLE_INPUT_ACTION);
+            decoder.onMalformedInput(malformedCharAction).onUnmappableCharacter(unmappableCharAction);
+            encoder.onMalformedInput(malformedCharAction).onUnmappableCharacter(unmappableCharAction);
+        }
+        this.inbuf = new SessionInputBufferImpl(buffersize, linebuffersize, decoder, allocator);
+        this.outbuf = new SessionOutputBufferImpl(buffersize, linebuffersize, encoder, allocator);
+        this.fragmentSizeHint = buffersize;
 
         this.incomingContentStrategy = createIncomingContentStrategy();
         this.outgoingContentStrategy = createOutgoingContentStrategy();
@@ -159,6 +179,57 @@ public class NHttpConnectionBase
         this.status = ACTIVE;
     }
 
+    /**
+     * Creates new instance NHttpConnectionBase given the underlying I/O session.
+     *
+     * @param session the underlying I/O session.
+     * @param buffersize buffer size. Must be a positive number.
+     * @param fragmentSizeHint fragment size hint.
+     * @param allocator memory allocator.
+     *   If <code>null</code> {@link org.apache.http.nio.util.HeapByteBufferAllocator#INSTANCE}
+     *   will be used.
+     * @param chardecoder decoder to be used for decoding HTTP protocol elements.
+     *   If <code>null</code> simple type cast will be used for byte to char conversion.
+     * @param charencoder encoder to be used for encoding HTTP protocol elements.
+     *   If <code>null</code> simple type cast will be used for char to byte conversion.
+     * @param incomingContentStrategy incoming content length strategy. If <code>null</code>
+     *   {@link LaxContentLengthStrategy#INSTANCE} will be used.
+     * @param outgoingContentStrategy outgoing content length strategy. If <code>null</code>
+     *   {@link StrictContentLengthStrategy#INSTANCE} will be used.
+     *
+     * @since 4.3
+     */
+    protected NHttpConnectionBase(
+            final IOSession session,
+            final int buffersize,
+            final int fragmentSizeHint,
+            final ByteBufferAllocator allocator,
+            final CharsetDecoder chardecoder,
+            final CharsetEncoder charencoder,
+            final ContentLengthStrategy incomingContentStrategy,
+            final ContentLengthStrategy outgoingContentStrategy) {
+        Args.notNull(session, "I/O session");
+        Args.positive(buffersize, "Buffer size");
+        int linebuffersize = buffersize;
+        if (linebuffersize > 512) {
+            linebuffersize = 512;
+        }
+        this.inbuf = new SessionInputBufferImpl(buffersize, linebuffersize, chardecoder, allocator);
+        this.outbuf = new SessionOutputBufferImpl(buffersize, linebuffersize, charencoder, allocator);
+        this.fragmentSizeHint = fragmentSizeHint >= 0 ? fragmentSizeHint : buffersize;
+
+        this.inTransportMetrics = new HttpTransportMetricsImpl();
+        this.outTransportMetrics = new HttpTransportMetricsImpl();
+        this.connMetrics = new HttpConnectionMetricsImpl(this.inTransportMetrics, this.outTransportMetrics);
+        this.incomingContentStrategy = incomingContentStrategy != null ? incomingContentStrategy :
+            LaxContentLengthStrategy.INSTANCE;
+        this.outgoingContentStrategy = outgoingContentStrategy != null ? outgoingContentStrategy :
+            StrictContentLengthStrategy.INSTANCE;
+
+        setSession(session);
+        this.status = ACTIVE;
+    }
+
     private void setSession(final IOSession session) {
         this.session = session;
         this.context = new SessionHttpContext(this.session);
@@ -173,37 +244,47 @@ public class NHttpConnectionBase
      * @since 4.2
      */
     protected void bind(final IOSession session) {
-        if (session == null) {
-            throw new IllegalArgumentException("I/O session may not be null");
-        }
+        Args.notNull(session, "I/O session");
         this.session.setBufferStatus(null);
         setSession(session);
     }
 
     /**
      * @since 4.2
+     *
+     * @deprecated (4.3) use constructor.
      */
+    @Deprecated
     protected ContentLengthStrategy createIncomingContentStrategy() {
         return new LaxContentLengthStrategy();
     }
 
     /**
      * @since 4.2
+     *
+     * @deprecated (4.3) use constructor.
      */
+    @Deprecated
     protected ContentLengthStrategy createOutgoingContentStrategy() {
         return new StrictContentLengthStrategy();
     }
 
     /**
      * @since 4.1
+     *
+     * @deprecated (4.3) no longer used.
      */
+    @Deprecated
     protected HttpTransportMetricsImpl createTransportMetrics() {
         return new HttpTransportMetricsImpl();
     }
 
     /**
      * @since 4.1
+     *
+     * @deprecated (4.3) use decorator to add additional metrics.
      */
+    @Deprecated
     protected HttpConnectionMetricsImpl createConnectionMetrics(
             final HttpTransportMetrics inTransportMetric,
             final HttpTransportMetrics outTransportMetric) {
@@ -252,8 +333,8 @@ public class NHttpConnectionBase
      * @throws HttpException in case of an HTTP protocol violation.
      */
     protected HttpEntity prepareDecoder(final HttpMessage message) throws HttpException {
-        BasicHttpEntity entity = new BasicHttpEntity();
-        long len = this.incomingContentStrategy.determineLength(message);
+        final BasicHttpEntity entity = new BasicHttpEntity();
+        final long len = this.incomingContentStrategy.determineLength(message);
         this.contentDecoder = createContentDecoder(
                 len,
                 this.session.channel(),
@@ -270,11 +351,11 @@ public class NHttpConnectionBase
             entity.setContentLength(len);
         }
 
-        Header contentTypeHeader = message.getFirstHeader(HTTP.CONTENT_TYPE);
+        final Header contentTypeHeader = message.getFirstHeader(HTTP.CONTENT_TYPE);
         if (contentTypeHeader != null) {
             entity.setContentType(contentTypeHeader);
         }
-        Header contentEncodingHeader = message.getFirstHeader(HTTP.CONTENT_ENCODING);
+        final Header contentEncodingHeader = message.getFirstHeader(HTTP.CONTENT_ENCODING);
         if (contentEncodingHeader != null) {
             entity.setContentEncoding(contentEncodingHeader);
         }
@@ -316,7 +397,7 @@ public class NHttpConnectionBase
      * @throws HttpException in case of an HTTP protocol violation.
      */
     protected void prepareEncoder(final HttpMessage message) throws HttpException {
-        long len = this.outgoingContentStrategy.determineLength(message);
+        final long len = this.outgoingContentStrategy.determineLength(message);
         this.contentEncoder = createContentEncoder(
                 len,
                 this.session.channel(),
@@ -343,11 +424,11 @@ public class NHttpConnectionBase
             final SessionOutputBuffer buffer,
             final HttpTransportMetricsImpl metrics) {
         if (len == ContentLengthStrategy.CHUNKED) {
-            return new ChunkEncoder(channel, buffer, metrics);
+            return new ChunkEncoder(channel, buffer, metrics, this.fragmentSizeHint);
         } else if (len == ContentLengthStrategy.IDENTITY) {
-            return new IdentityEncoder(channel, buffer, metrics);
+            return new IdentityEncoder(channel, buffer, metrics, this.fragmentSizeHint);
         } else {
-            return new LengthDelimitedEncoder(channel, buffer, metrics, len);
+            return new LengthDelimitedEncoder(channel, buffer, metrics, len, this.fragmentSizeHint);
         }
     }
 
@@ -393,7 +474,7 @@ public class NHttpConnectionBase
     }
 
     public InetAddress getLocalAddress() {
-        SocketAddress address = this.session.getLocalAddress();
+        final SocketAddress address = this.session.getLocalAddress();
         if (address instanceof InetSocketAddress) {
             return ((InetSocketAddress) address).getAddress();
         } else {
@@ -402,7 +483,7 @@ public class NHttpConnectionBase
     }
 
     public int getLocalPort() {
-        SocketAddress address = this.session.getLocalAddress();
+        final SocketAddress address = this.session.getLocalAddress();
         if (address instanceof InetSocketAddress) {
             return ((InetSocketAddress) address).getPort();
         } else {
@@ -411,7 +492,7 @@ public class NHttpConnectionBase
     }
 
     public InetAddress getRemoteAddress() {
-        SocketAddress address = this.session.getRemoteAddress();
+        final SocketAddress address = this.session.getRemoteAddress();
         if (address instanceof InetSocketAddress) {
             return ((InetSocketAddress) address).getAddress();
         } else {
@@ -420,7 +501,7 @@ public class NHttpConnectionBase
     }
 
     public int getRemotePort() {
-        SocketAddress address = this.session.getRemoteAddress();
+        final SocketAddress address = this.session.getRemoteAddress();
         if (address instanceof InetSocketAddress) {
             return ((InetSocketAddress) address).getPort();
         } else {
@@ -428,7 +509,7 @@ public class NHttpConnectionBase
         }
     }
 
-    public void setSocketTimeout(int timeout) {
+    public void setSocketTimeout(final int timeout) {
         this.session.setSocketTimeout(timeout);
     }
 
@@ -445,27 +526,15 @@ public class NHttpConnectionBase
         return this.connMetrics;
     }
 
-    private static void formatAddress(final StringBuilder buffer, final SocketAddress socketAddress) {
-        if (socketAddress instanceof InetSocketAddress) {
-            InetSocketAddress addr = ((InetSocketAddress) socketAddress);
-            buffer.append(addr.getAddress() != null ? addr.getAddress().getHostAddress() :
-                addr.getAddress())
-            .append(':')
-            .append(addr.getPort());
-        } else {
-            buffer.append(socketAddress);
-        }
-    }
-
     @Override
     public String toString() {
-        StringBuilder buffer = new StringBuilder();
-        SocketAddress remoteAddress = this.session.getRemoteAddress();
-        SocketAddress localAddress = this.session.getLocalAddress();
+        final StringBuilder buffer = new StringBuilder();
+        final SocketAddress remoteAddress = this.session.getRemoteAddress();
+        final SocketAddress localAddress = this.session.getLocalAddress();
         if (remoteAddress != null && localAddress != null) {
-            formatAddress(buffer, localAddress);
+            NetUtils.formatAddress(buffer, localAddress);
             buffer.append("<->");
-            formatAddress(buffer, remoteAddress);
+            NetUtils.formatAddress(buffer, remoteAddress);
         }
         buffer.append("[");
         switch (this.status) {
@@ -482,7 +551,7 @@ public class NHttpConnectionBase
         buffer.append("]");
         return buffer.toString();
     }
-    
+
     public Socket getSocket() {
         if (this.session instanceof SocketAccessor) {
             return ((SocketAccessor) this.session).getSocket();
diff --git a/httpcore-nio/src/test/java/org/apache/http/nio/integration/RndTestPatternGenerator.java b/httpcore-nio/src/main/java/org/apache/http/impl/nio/SSLContextUtils.java
similarity index 63%
copy from httpcore-nio/src/test/java/org/apache/http/nio/integration/RndTestPatternGenerator.java
copy to httpcore-nio/src/main/java/org/apache/http/impl/nio/SSLContextUtils.java
index f837815..e0956ae 100644
--- a/httpcore-nio/src/test/java/org/apache/http/nio/integration/RndTestPatternGenerator.java
+++ b/httpcore-nio/src/main/java/org/apache/http/impl/nio/SSLContextUtils.java
@@ -24,27 +24,27 @@
  * <http://www.apache.org/>.
  *
  */
+package org.apache.http.impl.nio;
 
-package org.apache.http.nio.integration;
+import javax.net.ssl.SSLContext;
+import java.security.NoSuchAlgorithmException;
 
-import java.util.Random;
+// TODO: to be replaced by SSLContext#getDefault() after upgrade to 1.6
+class SSLContextUtils {
 
-final class RndTestPatternGenerator {
-
-    private static final Random RND = new Random();
-    private static final String TEST_CHARS = "0123456789ABCDEF";
-
-    public static String generateText() {
-        StringBuilder buffer = new StringBuilder();
-        for (int i = 0; i < 5; i++) {
-            char rndchar = TEST_CHARS.charAt(RND.nextInt(TEST_CHARS.length() - 1));
-            buffer.append(rndchar);
+    static SSLContext getDefault() {
+        SSLContext sslcontext;
+        try {
+            try {
+                sslcontext = SSLContext.getInstance("Default");
+            }  catch (NoSuchAlgorithmException ex) {
+                sslcontext = SSLContext.getInstance("TLS");
+            }
+            sslcontext.init(null, null, null);
+        } catch (final Exception ex) {
+            throw new IllegalStateException("Failure initializing default SSL context", ex);
         }
-        return buffer.toString();
-    }
-
-    public static int generateCount(int max) {
-        return RND.nextInt(max - 1) + 1;
+        return sslcontext;
     }
 
 }
diff --git a/httpcore-nio/src/main/java/org/apache/http/impl/nio/SSLNHttpClientConnectionFactory.java b/httpcore-nio/src/main/java/org/apache/http/impl/nio/SSLNHttpClientConnectionFactory.java
index 687f8e1..30feaf8 100644
--- a/httpcore-nio/src/main/java/org/apache/http/impl/nio/SSLNHttpClientConnectionFactory.java
+++ b/httpcore-nio/src/main/java/org/apache/http/impl/nio/SSLNHttpClientConnectionFactory.java
@@ -28,45 +28,57 @@ package org.apache.http.impl.nio;
 
 import javax.net.ssl.SSLContext;
 
+import org.apache.http.HttpRequest;
+import org.apache.http.HttpResponse;
 import org.apache.http.HttpResponseFactory;
 import org.apache.http.annotation.Immutable;
+import org.apache.http.config.ConnectionConfig;
+import org.apache.http.entity.ContentLengthStrategy;
+import org.apache.http.impl.ConnSupport;
 import org.apache.http.impl.DefaultHttpResponseFactory;
-import org.apache.http.nio.NHttpClientConnection;
+import org.apache.http.impl.nio.codecs.DefaultHttpResponseParserFactory;
 import org.apache.http.nio.NHttpConnectionFactory;
+import org.apache.http.nio.NHttpMessageParserFactory;
+import org.apache.http.nio.NHttpMessageWriterFactory;
 import org.apache.http.nio.reactor.IOSession;
 import org.apache.http.nio.reactor.ssl.SSLIOSession;
 import org.apache.http.nio.reactor.ssl.SSLMode;
 import org.apache.http.nio.reactor.ssl.SSLSetupHandler;
 import org.apache.http.nio.util.ByteBufferAllocator;
 import org.apache.http.nio.util.HeapByteBufferAllocator;
-import org.apache.http.params.HttpConnectionParams;
+import org.apache.http.params.HttpParamConfig;
 import org.apache.http.params.HttpParams;
+import org.apache.http.util.Args;
 
 /**
- * Factory for SSL encrypted, non-blocking {@link NHttpClientConnection}s.
- * <p>
- * The following parameters can be used to customize the behavior of this
- * class:
- * <ul>
- *  <li>{@link org.apache.http.params.CoreProtocolPNames#HTTP_ELEMENT_CHARSET}</li>
- *  <li>{@link org.apache.http.params.CoreConnectionPNames#SO_TIMEOUT}</li>
- *  <li>{@link org.apache.http.params.CoreConnectionPNames#SOCKET_BUFFER_SIZE}</li>
- *  <li>{@link org.apache.http.params.CoreConnectionPNames#MAX_HEADER_COUNT}</li>
- *  <li>{@link org.apache.http.params.CoreConnectionPNames#MAX_LINE_LENGTH}</li>
- * </ul>
+ * Default factory for SSL encrypted, non-blocking
+ * {@link org.apache.http.nio.NHttpClientConnection}s.
  *
  * @since 4.2
  */
+ at SuppressWarnings("deprecation")
 @Immutable
 public class SSLNHttpClientConnectionFactory
     implements NHttpConnectionFactory<DefaultNHttpClientConnection> {
 
-    private final HttpResponseFactory responseFactory;
+    public static final SSLNHttpClientConnectionFactory INSTANCE = new SSLNHttpClientConnectionFactory();
+
+    private final ContentLengthStrategy incomingContentStrategy;
+    private final ContentLengthStrategy outgoingContentStrategy;
+    private final NHttpMessageParserFactory<HttpResponse> responseParserFactory;
+    private final NHttpMessageWriterFactory<HttpRequest> requestWriterFactory;
     private final ByteBufferAllocator allocator;
     private final SSLContext sslcontext;
     private final SSLSetupHandler sslHandler;
-    private final HttpParams params;
+    private final ConnectionConfig cconfig;
 
+    /**
+     * @deprecated (4.3) use {@link
+     *   SSLNHttpClientConnectionFactory#SSLNHttpClientConnectionFactory(SSLContext,
+     *      SSLSetupHandler, NHttpMessageParserFactory, NHttpMessageWriterFactory,
+     *      ByteBufferAllocator, ConnectionConfig)}
+     */
+    @Deprecated
     public SSLNHttpClientConnectionFactory(
             final SSLContext sslcontext,
             final SSLSetupHandler sslHandler,
@@ -74,44 +86,120 @@ public class SSLNHttpClientConnectionFactory
             final ByteBufferAllocator allocator,
             final HttpParams params) {
         super();
-        if (responseFactory == null) {
-            throw new IllegalArgumentException("HTTP response factory may not be null");
-        }
-        if (allocator == null) {
-            throw new IllegalArgumentException("Byte buffer allocator may not be null");
-        }
-        if (params == null) {
-            throw new IllegalArgumentException("HTTP parameters may not be null");
-        }
+        Args.notNull(responseFactory, "HTTP response factory");
+        Args.notNull(allocator, "Byte buffer allocator");
+        Args.notNull(params, "HTTP parameters");
         this.sslcontext = sslcontext;
         this.sslHandler = sslHandler;
-        this.responseFactory = responseFactory;
         this.allocator = allocator;
-        this.params = params;
+        this.incomingContentStrategy = null;
+        this.outgoingContentStrategy = null;
+        this.responseParserFactory = new DefaultHttpResponseParserFactory(null, responseFactory);
+        this.requestWriterFactory = null;
+        this.cconfig = HttpParamConfig.getConnectionConfig(params);
     }
 
+    /**
+     * @deprecated (4.3) use {@link
+     *   SSLNHttpClientConnectionFactory#SSLNHttpClientConnectionFactory(SSLContext,
+     *     SSLSetupHandler, ConnectionConfig)}
+     */
+    @Deprecated
     public SSLNHttpClientConnectionFactory(
             final SSLContext sslcontext,
             final SSLSetupHandler sslHandler,
             final HttpParams params) {
-        this(sslcontext, sslHandler, new DefaultHttpResponseFactory(), new HeapByteBufferAllocator(), params);
+        this(sslcontext, sslHandler, DefaultHttpResponseFactory.INSTANCE,
+                HeapByteBufferAllocator.INSTANCE, params);
     }
 
+    /**
+     * @deprecated (4.3) use {@link
+     *   SSLNHttpClientConnectionFactory#SSLNHttpClientConnectionFactory(ConnectionConfig)}
+     */
+    @Deprecated
     public SSLNHttpClientConnectionFactory(final HttpParams params) {
         this(null, null, params);
     }
 
-    private SSLContext getDefaultSSLContext() {
-        SSLContext sslcontext;
-        try {
-            sslcontext = SSLContext.getInstance("TLS");
-            sslcontext.init(null, null, null);
-        } catch (Exception ex) {
-            throw new IllegalStateException("Failure initializing default SSL context", ex);
-        }
-        return sslcontext;
+    /**
+     * @since 4.3
+     */
+    public SSLNHttpClientConnectionFactory(
+            final SSLContext sslcontext,
+            final SSLSetupHandler sslHandler,
+            final ContentLengthStrategy incomingContentStrategy,
+            final ContentLengthStrategy outgoingContentStrategy,
+            final NHttpMessageParserFactory<HttpResponse> responseParserFactory,
+            final NHttpMessageWriterFactory<HttpRequest> requestWriterFactory,
+            final ByteBufferAllocator allocator,
+            final ConnectionConfig cconfig) {
+        super();
+        this.sslcontext = sslcontext;
+        this.sslHandler = sslHandler;
+        this.incomingContentStrategy = incomingContentStrategy;
+        this.outgoingContentStrategy = outgoingContentStrategy;
+        this.responseParserFactory = responseParserFactory;
+        this.requestWriterFactory = requestWriterFactory;
+        this.allocator = allocator;
+        this.cconfig = cconfig != null ? cconfig : ConnectionConfig.DEFAULT;
+    }
+
+    /**
+     * @since 4.3
+     */
+    public SSLNHttpClientConnectionFactory(
+            final SSLContext sslcontext,
+            final SSLSetupHandler sslHandler,
+            final NHttpMessageParserFactory<HttpResponse> responseParserFactory,
+            final NHttpMessageWriterFactory<HttpRequest> requestWriterFactory,
+            final ByteBufferAllocator allocator,
+            final ConnectionConfig cconfig) {
+        this(sslcontext, sslHandler,
+                null, null, responseParserFactory, requestWriterFactory, allocator, cconfig);
+    }
+
+    /**
+     * @since 4.3
+     */
+    public SSLNHttpClientConnectionFactory(
+            final SSLContext sslcontext,
+            final SSLSetupHandler sslHandler,
+            final NHttpMessageParserFactory<HttpResponse> responseParserFactory,
+            final NHttpMessageWriterFactory<HttpRequest> requestWriterFactory,
+            final ConnectionConfig cconfig) {
+        this(sslcontext, sslHandler,
+                null, null, responseParserFactory, requestWriterFactory, null, cconfig);
+    }
+
+    /**
+     * @since 4.3
+     */
+    public SSLNHttpClientConnectionFactory(
+            final SSLContext sslcontext,
+            final SSLSetupHandler sslHandler,
+            final ConnectionConfig config) {
+        this(sslcontext, sslHandler, null, null, null, null, null, config);
+    }
+
+    /**
+     * @since 4.3
+     */
+    public SSLNHttpClientConnectionFactory(final ConnectionConfig config) {
+        this(null, null, null, null, null, null, null, config);
+    }
+
+    /**
+     * @since 4.3
+     */
+    public SSLNHttpClientConnectionFactory() {
+        this(null, null, null, null, null, null);
     }
 
+    /**
+     * @deprecated (4.3) no longer used.
+     */
+    @Deprecated
     protected DefaultNHttpClientConnection createConnection(
             final IOSession session,
             final HttpResponseFactory responseFactory,
@@ -120,15 +208,34 @@ public class SSLNHttpClientConnectionFactory
         return new DefaultNHttpClientConnection(session, responseFactory, allocator, params);
     }
 
-    public DefaultNHttpClientConnection createConnection(final IOSession session) {
-        SSLContext sslcontext = this.sslcontext != null ? this.sslcontext : getDefaultSSLContext();
-        SSLIOSession ssliosession = new SSLIOSession(session, SSLMode.CLIENT, sslcontext, this.sslHandler);
-        session.setAttribute(SSLIOSession.SESSION_KEY, ssliosession);
-        DefaultNHttpClientConnection conn = createConnection(
-                ssliosession, this.responseFactory, this.allocator, this.params);
-        int timeout = HttpConnectionParams.getSoTimeout(this.params);
-        conn.setSocketTimeout(timeout);
-        return conn;
+    /**
+     * @since 4.3
+     */
+    protected SSLIOSession createSSLIOSession(
+            final IOSession iosession,
+            final SSLContext sslcontext,
+            final SSLSetupHandler sslHandler) {
+        final SSLIOSession ssliosession = new SSLIOSession(iosession, SSLMode.CLIENT,
+                (sslcontext != null ? sslcontext : SSLContextUtils.getDefault()),
+                sslHandler);
+        return ssliosession;
+    }
+
+    public DefaultNHttpClientConnection createConnection(final IOSession iosession) {
+        final SSLIOSession ssliosession = createSSLIOSession(iosession, this.sslcontext, this.sslHandler);
+        iosession.setAttribute(SSLIOSession.SESSION_KEY, ssliosession);
+        return new DefaultNHttpClientConnection(
+                ssliosession,
+                this.cconfig.getBufferSize(),
+                this.cconfig.getFragmentSizeHint(),
+                this.allocator,
+                ConnSupport.createDecoder(this.cconfig),
+                ConnSupport.createEncoder(this.cconfig),
+                this.cconfig.getMessageConstraints(),
+                this.incomingContentStrategy,
+                this.outgoingContentStrategy,
+                this.requestWriterFactory,
+                this.responseParserFactory);
     }
 
 }
diff --git a/httpcore-nio/src/main/java/org/apache/http/impl/nio/SSLNHttpServerConnectionFactory.java b/httpcore-nio/src/main/java/org/apache/http/impl/nio/SSLNHttpServerConnectionFactory.java
index cad359e..8894e14 100644
--- a/httpcore-nio/src/main/java/org/apache/http/impl/nio/SSLNHttpServerConnectionFactory.java
+++ b/httpcore-nio/src/main/java/org/apache/http/impl/nio/SSLNHttpServerConnectionFactory.java
@@ -28,45 +28,55 @@ package org.apache.http.impl.nio;
 
 import javax.net.ssl.SSLContext;
 
+import org.apache.http.HttpRequest;
 import org.apache.http.HttpRequestFactory;
+import org.apache.http.HttpResponse;
 import org.apache.http.annotation.Immutable;
+import org.apache.http.config.ConnectionConfig;
+import org.apache.http.entity.ContentLengthStrategy;
+import org.apache.http.impl.ConnSupport;
 import org.apache.http.impl.DefaultHttpRequestFactory;
+import org.apache.http.impl.nio.codecs.DefaultHttpRequestParserFactory;
 import org.apache.http.nio.NHttpConnectionFactory;
-import org.apache.http.nio.NHttpServerConnection;
+import org.apache.http.nio.NHttpMessageParserFactory;
+import org.apache.http.nio.NHttpMessageWriterFactory;
 import org.apache.http.nio.reactor.IOSession;
 import org.apache.http.nio.reactor.ssl.SSLIOSession;
 import org.apache.http.nio.reactor.ssl.SSLMode;
 import org.apache.http.nio.reactor.ssl.SSLSetupHandler;
 import org.apache.http.nio.util.ByteBufferAllocator;
 import org.apache.http.nio.util.HeapByteBufferAllocator;
-import org.apache.http.params.HttpConnectionParams;
+import org.apache.http.params.HttpParamConfig;
 import org.apache.http.params.HttpParams;
+import org.apache.http.util.Args;
 
 /**
- * Factory for SSL encrypted, non-blocking {@link NHttpServerConnection}s.
- * <p>
- * The following parameters can be used to customize the behavior of this
- * class:
- * <ul>
- *  <li>{@link org.apache.http.params.CoreProtocolPNames#HTTP_ELEMENT_CHARSET}</li>
- *  <li>{@link org.apache.http.params.CoreConnectionPNames#SO_TIMEOUT}</li>
- *  <li>{@link org.apache.http.params.CoreConnectionPNames#SOCKET_BUFFER_SIZE}</li>
- *  <li>{@link org.apache.http.params.CoreConnectionPNames#MAX_HEADER_COUNT}</li>
- *  <li>{@link org.apache.http.params.CoreConnectionPNames#MAX_LINE_LENGTH}</li>
- * </ul>
+ * Default factory for SSL encrypted, non-blocking
+ * {@link org.apache.http.nio.NHttpServerConnection}s.
  *
  * @since 4.2
  */
+ at SuppressWarnings("deprecation")
 @Immutable
 public class SSLNHttpServerConnectionFactory
     implements NHttpConnectionFactory<DefaultNHttpServerConnection> {
 
-    private final HttpRequestFactory requestFactory;
-    private final ByteBufferAllocator allocator;
     private final SSLContext sslcontext;
     private final SSLSetupHandler sslHandler;
-    private final HttpParams params;
+    private final ContentLengthStrategy incomingContentStrategy;
+    private final ContentLengthStrategy outgoingContentStrategy;
+    private final NHttpMessageParserFactory<HttpRequest> requestParserFactory;
+    private final NHttpMessageWriterFactory<HttpResponse> responseWriterFactory;
+    private final ByteBufferAllocator allocator;
+    private final ConnectionConfig cconfig;
 
+    /**
+     * @deprecated (4.3) use {@link
+     *   SSLNHttpServerConnectionFactory#SSLNHttpServerConnectionFactory(SSLContext,
+     *      SSLSetupHandler, NHttpMessageParserFactory, NHttpMessageWriterFactory,
+     *      ByteBufferAllocator, ConnectionConfig)}
+     */
+    @Deprecated
     public SSLNHttpServerConnectionFactory(
             final SSLContext sslcontext,
             final SSLSetupHandler sslHandler,
@@ -74,44 +84,120 @@ public class SSLNHttpServerConnectionFactory
             final ByteBufferAllocator allocator,
             final HttpParams params) {
         super();
-        if (requestFactory == null) {
-            throw new IllegalArgumentException("HTTP request factory may not be null");
-        }
-        if (allocator == null) {
-            throw new IllegalArgumentException("Byte buffer allocator may not be null");
-        }
-        if (params == null) {
-            throw new IllegalArgumentException("HTTP parameters may not be null");
-        }
+        Args.notNull(requestFactory, "HTTP request factory");
+        Args.notNull(allocator, "Byte buffer allocator");
+        Args.notNull(params, "HTTP parameters");
         this.sslcontext = sslcontext;
         this.sslHandler = sslHandler;
-        this.requestFactory = requestFactory;
+        this.incomingContentStrategy = null;
+        this.outgoingContentStrategy = null;
+        this.requestParserFactory = new DefaultHttpRequestParserFactory(null, requestFactory);
+        this.responseWriterFactory = null;
         this.allocator = allocator;
-        this.params = params;
+        this.cconfig = HttpParamConfig.getConnectionConfig(params);
     }
 
+    /**
+     * @deprecated (4.3) use {@link
+     *   SSLNHttpServerConnectionFactory#SSLNHttpServerConnectionFactory(SSLContext,
+     *     SSLSetupHandler, ConnectionConfig)}
+     */
+    @Deprecated
     public SSLNHttpServerConnectionFactory(
             final SSLContext sslcontext,
             final SSLSetupHandler sslHandler,
             final HttpParams params) {
-        this(sslcontext, sslHandler, new DefaultHttpRequestFactory(), new HeapByteBufferAllocator(), params);
+        this(sslcontext, sslHandler, DefaultHttpRequestFactory.INSTANCE,
+                HeapByteBufferAllocator.INSTANCE, params);
     }
 
+    /**
+     * @deprecated (4.3) use {@link
+     *   SSLNHttpServerConnectionFactory#SSLNHttpServerConnectionFactory(ConnectionConfig)}
+     */
+    @Deprecated
     public SSLNHttpServerConnectionFactory(final HttpParams params) {
         this(null, null, params);
     }
 
-    private SSLContext getDefaultSSLContext() {
-        SSLContext sslcontext;
-        try {
-            sslcontext = SSLContext.getInstance("TLS");
-            sslcontext.init(null, null, null);
-        } catch (Exception ex) {
-            throw new IllegalStateException("Failure initializing default SSL context", ex);
-        }
-        return sslcontext;
+    /**
+     * @since 4.3
+     */
+    public SSLNHttpServerConnectionFactory(
+            final SSLContext sslcontext,
+            final SSLSetupHandler sslHandler,
+            final ContentLengthStrategy incomingContentStrategy,
+            final ContentLengthStrategy outgoingContentStrategy,
+            final NHttpMessageParserFactory<HttpRequest> requestParserFactory,
+            final NHttpMessageWriterFactory<HttpResponse> responseWriterFactory,
+            final ByteBufferAllocator allocator,
+            final ConnectionConfig cconfig) {
+        super();
+        this.sslcontext = sslcontext;
+        this.sslHandler = sslHandler;
+        this.incomingContentStrategy = incomingContentStrategy;
+        this.outgoingContentStrategy = outgoingContentStrategy;
+        this.requestParserFactory = requestParserFactory;
+        this.responseWriterFactory = responseWriterFactory;
+        this.allocator = allocator;
+        this.cconfig = cconfig != null ? cconfig : ConnectionConfig.DEFAULT;
+    }
+
+    /**
+     * @since 4.3
+     */
+    public SSLNHttpServerConnectionFactory(
+            final SSLContext sslcontext,
+            final SSLSetupHandler sslHandler,
+            final NHttpMessageParserFactory<HttpRequest> requestParserFactory,
+            final NHttpMessageWriterFactory<HttpResponse> responseWriterFactory,
+            final ByteBufferAllocator allocator,
+            final ConnectionConfig cconfig) {
+        this(sslcontext, sslHandler,
+                null, null, requestParserFactory, responseWriterFactory, allocator, cconfig);
     }
 
+    /**
+     * @since 4.3
+     */
+    public SSLNHttpServerConnectionFactory(
+            final SSLContext sslcontext,
+            final SSLSetupHandler sslHandler,
+            final NHttpMessageParserFactory<HttpRequest> requestParserFactory,
+            final NHttpMessageWriterFactory<HttpResponse> responseWriterFactory,
+            final ConnectionConfig cconfig) {
+        this(sslcontext, sslHandler,
+                null, null, requestParserFactory, responseWriterFactory, null, cconfig);
+    }
+
+    /**
+     * @since 4.3
+     */
+    public SSLNHttpServerConnectionFactory(
+            final SSLContext sslcontext,
+            final SSLSetupHandler sslHandler,
+            final ConnectionConfig config) {
+        this(sslcontext, sslHandler, null, null, null, null, null, config);
+    }
+
+    /**
+     * @since 4.3
+     */
+    public SSLNHttpServerConnectionFactory(final ConnectionConfig config) {
+        this(null, null, null, null, null, null, null, config);
+    }
+
+    /**
+     * @since 4.3
+     */
+    public SSLNHttpServerConnectionFactory() {
+        this(null, null, null, null, null, null, null, null);
+    }
+
+    /**
+     * @deprecated (4.3) no longer used.
+     */
+    @Deprecated
     protected DefaultNHttpServerConnection createConnection(
             final IOSession session,
             final HttpRequestFactory requestFactory,
@@ -120,15 +206,33 @@ public class SSLNHttpServerConnectionFactory
         return new DefaultNHttpServerConnection(session, requestFactory, allocator, params);
     }
 
-    public DefaultNHttpServerConnection createConnection(final IOSession session) {
-        SSLContext sslcontext = this.sslcontext != null ? this.sslcontext : getDefaultSSLContext();
-        SSLIOSession ssliosession = new SSLIOSession(session, SSLMode.SERVER, sslcontext, this.sslHandler);
-        session.setAttribute(SSLIOSession.SESSION_KEY, ssliosession);
-        DefaultNHttpServerConnection conn =  createConnection(
-                ssliosession, this.requestFactory, this.allocator, this.params);
-        int timeout = HttpConnectionParams.getSoTimeout(this.params);
-        conn.setSocketTimeout(timeout);
-        return conn;
+    /**
+     * @since 4.3
+     */
+    protected SSLIOSession createSSLIOSession(
+            final IOSession iosession,
+            final SSLContext sslcontext,
+            final SSLSetupHandler sslHandler) {
+        final SSLIOSession ssliosession = new SSLIOSession(iosession, SSLMode.SERVER,
+                (sslcontext != null ? sslcontext : SSLContextUtils.getDefault()),
+                sslHandler);
+        return ssliosession;
+    }
+
+    public DefaultNHttpServerConnection createConnection(final IOSession iosession) {
+        final SSLIOSession ssliosession = createSSLIOSession(iosession, this.sslcontext, this.sslHandler);
+        iosession.setAttribute(SSLIOSession.SESSION_KEY, ssliosession);
+        return new DefaultNHttpServerConnection(ssliosession,
+                this.cconfig.getBufferSize(),
+                this.cconfig.getFragmentSizeHint(),
+                this.allocator,
+                ConnSupport.createDecoder(this.cconfig),
+                ConnSupport.createEncoder(this.cconfig),
+                this.cconfig.getMessageConstraints(),
+                this.incomingContentStrategy,
+                this.outgoingContentStrategy,
+                this.requestParserFactory,
+                this.responseWriterFactory);
     }
 
 }
diff --git a/httpcore-nio/src/main/java/org/apache/http/impl/nio/codecs/AbstractContentDecoder.java b/httpcore-nio/src/main/java/org/apache/http/impl/nio/codecs/AbstractContentDecoder.java
index 6a7997a..0917784 100644
--- a/httpcore-nio/src/main/java/org/apache/http/impl/nio/codecs/AbstractContentDecoder.java
+++ b/httpcore-nio/src/main/java/org/apache/http/impl/nio/codecs/AbstractContentDecoder.java
@@ -27,12 +27,15 @@
 
 package org.apache.http.impl.nio.codecs;
 
+import java.io.IOException;
+import java.nio.ByteBuffer;
 import java.nio.channels.ReadableByteChannel;
 
-import org.apache.http.nio.ContentDecoder;
-import org.apache.http.nio.reactor.SessionInputBuffer;
 import org.apache.http.annotation.NotThreadSafe;
 import org.apache.http.impl.io.HttpTransportMetricsImpl;
+import org.apache.http.nio.ContentDecoder;
+import org.apache.http.nio.reactor.SessionInputBuffer;
+import org.apache.http.util.Args;
 
 /**
  * Abstract {@link ContentDecoder} that serves as a base for all content
@@ -62,15 +65,9 @@ public abstract class AbstractContentDecoder implements ContentDecoder {
             final SessionInputBuffer buffer,
             final HttpTransportMetricsImpl metrics) {
         super();
-        if (channel == null) {
-            throw new IllegalArgumentException("Channel may not be null");
-        }
-        if (buffer == null) {
-            throw new IllegalArgumentException("Session input buffer may not be null");
-        }
-        if (metrics == null) {
-            throw new IllegalArgumentException("Transport metrics may not be null");
-        }
+        Args.notNull(channel, "Channel");
+        Args.notNull(buffer, "Session input buffer");
+        Args.notNull(metrics, "Transport metrics");
         this.buffer = buffer;
         this.channel = channel;
         this.metrics = metrics;
@@ -80,4 +77,60 @@ public abstract class AbstractContentDecoder implements ContentDecoder {
         return this.completed;
     }
 
+    /**
+     * Reads from the channel to the destination.
+     *
+     * @param dst destination.
+     * @return number of bytes transferred.
+     *
+     * @since 4.3
+     */
+    protected int readFromChannel(final ByteBuffer dst) throws IOException {
+        final int bytesRead = this.channel.read(dst);
+        if (bytesRead > 0) {
+            this.metrics.incrementBytesTransferred(bytesRead);
+        }
+        return bytesRead;
+    }
+
+    /**
+     * Reads from the channel to the session buffer.
+     * @return number of bytes transferred.
+     *
+     * @since 4.3
+     */
+    protected int fillBufferFromChannel() throws IOException {
+        final int bytesRead = this.buffer.fill(this.channel);
+        if (bytesRead > 0) {
+            this.metrics.incrementBytesTransferred(bytesRead);
+        }
+        return bytesRead;
+    }
+
+    /**
+     * Reads from the channel to the destination.
+     *
+     * @param dst destination.
+     * @param limit max number of bytes to transfer.
+     * @return number of bytes transferred.
+     *
+     * @since 4.3
+     */
+    protected int readFromChannel(final ByteBuffer dst, final int limit) throws IOException {
+        final int bytesRead;
+        if (dst.remaining() > limit) {
+            final int oldLimit = dst.limit();
+            final int newLimit = oldLimit - (dst.remaining() - limit);
+            dst.limit(newLimit);
+            bytesRead = this.channel.read(dst);
+            dst.limit(oldLimit);
+        } else {
+            bytesRead = this.channel.read(dst);
+        }
+        if (bytesRead > 0) {
+            this.metrics.incrementBytesTransferred(bytesRead);
+        }
+        return bytesRead;
+    }
+
 }
diff --git a/httpcore-nio/src/main/java/org/apache/http/impl/nio/codecs/AbstractContentEncoder.java b/httpcore-nio/src/main/java/org/apache/http/impl/nio/codecs/AbstractContentEncoder.java
index 478d9ef..7dc0923 100644
--- a/httpcore-nio/src/main/java/org/apache/http/impl/nio/codecs/AbstractContentEncoder.java
+++ b/httpcore-nio/src/main/java/org/apache/http/impl/nio/codecs/AbstractContentEncoder.java
@@ -28,12 +28,15 @@
 package org.apache.http.impl.nio.codecs;
 
 import java.io.IOException;
+import java.nio.ByteBuffer;
 import java.nio.channels.WritableByteChannel;
 
 import org.apache.http.annotation.NotThreadSafe;
 import org.apache.http.impl.io.HttpTransportMetricsImpl;
 import org.apache.http.nio.ContentEncoder;
 import org.apache.http.nio.reactor.SessionOutputBuffer;
+import org.apache.http.util.Args;
+import org.apache.http.util.Asserts;
 
 /**
  * Abstract {@link ContentEncoder} that serves as a base for all content
@@ -48,6 +51,11 @@ public abstract class AbstractContentEncoder implements ContentEncoder {
     protected final SessionOutputBuffer buffer;
     protected final HttpTransportMetricsImpl metrics;
 
+    /**
+     * @deprecated since 4.3-beta3 - use {@link #isCompleted()} or {@link #complete()} instead
+     * Will probably be made private at some point.
+     */
+    @Deprecated
     protected boolean completed;
 
     /**
@@ -63,15 +71,9 @@ public abstract class AbstractContentEncoder implements ContentEncoder {
             final SessionOutputBuffer buffer,
             final HttpTransportMetricsImpl metrics) {
         super();
-        if (channel == null) {
-            throw new IllegalArgumentException("Channel may not be null");
-        }
-        if (buffer == null) {
-            throw new IllegalArgumentException("Session input buffer may not be null");
-        }
-        if (metrics == null) {
-            throw new IllegalArgumentException("Transport metrics may not be null");
-        }
+        Args.notNull(channel, "Channel");
+        Args.notNull(buffer, "Session input buffer");
+        Args.notNull(metrics, "Transport metrics");
         this.buffer = buffer;
         this.channel = channel;
         this.metrics = metrics;
@@ -86,8 +88,97 @@ public abstract class AbstractContentEncoder implements ContentEncoder {
     }
 
     protected void assertNotCompleted() {
-        if (this.completed) {
-            throw new IllegalStateException("Encoding process already completed");
+        Asserts.check(!this.completed, "Encoding process already completed");
+    }
+
+    /**
+     * Flushes content of the session buffer to the channel and updates transport metrics.
+     *
+     * @return number of bytes written to the channel.
+     *
+     * @since 4.3
+     */
+    protected int flushToChannel() throws IOException {
+        if (!this.buffer.hasData()) {
+            return 0;
+        }
+        final int bytesWritten = this.buffer.flush(this.channel);
+        if (bytesWritten > 0) {
+            this.metrics.incrementBytesTransferred(bytesWritten);
+        }
+        return bytesWritten;
+    }
+
+    /**
+     * Flushes content of the given buffer to the channel and updates transport metrics.
+     *
+     * @return number of bytes written to the channel.
+     *
+     * @since 4.3
+     */
+    protected int writeToChannel(final ByteBuffer src) throws IOException {
+        if (!src.hasRemaining()) {
+            return 0;
+        }
+        final int bytesWritten = this.channel.write(src);
+        if (bytesWritten > 0) {
+            this.metrics.incrementBytesTransferred(bytesWritten);
+        }
+        return bytesWritten;
+    }
+
+    /**
+     * Transfers content of the source to the channel and updates transport metrics.
+     *
+     * @param src source.
+     * @param limit max number of bytes to transfer.
+     * @return number of bytes transferred.
+     *
+     * @since 4.3
+     */
+    protected int writeToChannel(final ByteBuffer src, final int limit) throws IOException {
+        return doWriteChunk(src, limit, true);
+    }
+
+    /**
+     * Transfers content of the source to the buffer and updates transport metrics.
+     *
+     * @param src source.
+     * @param limit max number of bytes to transfer.
+     * @return number of bytes transferred.
+     *
+     * @since 4.3
+     */
+    protected int writeToBuffer(final ByteBuffer src, final int limit) throws IOException {
+        return doWriteChunk(src, limit, false);
+    }
+
+    private int doWriteChunk(
+        final ByteBuffer src, final int chunk, final boolean direct) throws IOException {
+        final int bytesWritten;
+        if (src.remaining() > chunk) {
+            final int oldLimit = src.limit();
+            final int newLimit = oldLimit - (src.remaining() - chunk);
+            src.limit(newLimit);
+            bytesWritten = doWriteChunk(src, direct);
+            src.limit(oldLimit);
+        } else {
+            bytesWritten = doWriteChunk(src, direct);
+        }
+        return bytesWritten;
+    }
+
+    private int doWriteChunk(final ByteBuffer src, final boolean direct) throws IOException {
+        if (direct) {
+            final int bytesWritten = this.channel.write(src);
+            if (bytesWritten > 0) {
+                this.metrics.incrementBytesTransferred(bytesWritten);
+            }
+            return bytesWritten;
+        } else {
+            final int chunk = src.remaining();
+            this.buffer.write(src);
+            return chunk;
         }
     }
 
diff --git a/httpcore-nio/src/main/java/org/apache/http/impl/nio/codecs/AbstractMessageParser.java b/httpcore-nio/src/main/java/org/apache/http/impl/nio/codecs/AbstractMessageParser.java
index 89e699a..300ce8d 100644
--- a/httpcore-nio/src/main/java/org/apache/http/impl/nio/codecs/AbstractMessageParser.java
+++ b/httpcore-nio/src/main/java/org/apache/http/impl/nio/codecs/AbstractMessageParser.java
@@ -34,30 +34,27 @@ import java.util.List;
 
 import org.apache.http.HttpException;
 import org.apache.http.HttpMessage;
+import org.apache.http.MessageConstraintException;
 import org.apache.http.ParseException;
 import org.apache.http.ProtocolException;
 import org.apache.http.annotation.NotThreadSafe;
-import org.apache.http.message.LineParser;
+import org.apache.http.config.MessageConstraints;
 import org.apache.http.message.BasicLineParser;
+import org.apache.http.message.LineParser;
 import org.apache.http.nio.NHttpMessageParser;
 import org.apache.http.nio.reactor.SessionInputBuffer;
-import org.apache.http.params.CoreConnectionPNames;
+import org.apache.http.params.HttpParamConfig;
 import org.apache.http.params.HttpParams;
+import org.apache.http.util.Args;
 import org.apache.http.util.CharArrayBuffer;
 
 /**
  * Abstract {@link NHttpMessageParser} that serves as a base for all message
  * parser implementations.
- * <p>
- * The following parameters can be used to customize the behavior of this
- * class:
- * <ul>
- *  <li>{@link org.apache.http.params.CoreConnectionPNames#MAX_HEADER_COUNT}</li>
- *  <li>{@link org.apache.http.params.CoreConnectionPNames#MAX_LINE_LENGTH}</li>
- * </ul>
  *
  * @since 4.0
  */
+ at SuppressWarnings("deprecation")
 @NotThreadSafe
 public abstract class AbstractMessageParser<T extends HttpMessage> implements NHttpMessageParser<T> {
 
@@ -74,34 +71,58 @@ public abstract class AbstractMessageParser<T extends HttpMessage> implements NH
     private CharArrayBuffer lineBuf;
     private final List<CharArrayBuffer> headerBufs;
 
-    private int maxLineLen = -1;
-    private int maxHeaderCount = -1;
     protected final LineParser lineParser;
+    private final MessageConstraints constraints;
 
     /**
      * Creates an instance of this class.
      *
      * @param buffer the session input buffer.
-     * @param parser the line parser.
+     * @param lineParser the line parser.
      * @param params HTTP parameters.
+     *
+     * @deprecated (4.3) use
+     *   {@link AbstractMessageParser#AbstractMessageParser(SessionInputBuffer, LineParser,
+     *     MessageConstraints)}
      */
-    public AbstractMessageParser(final SessionInputBuffer buffer, final LineParser parser, final HttpParams params) {
+    @Deprecated
+    public AbstractMessageParser(
+            final SessionInputBuffer buffer,
+            final LineParser lineParser,
+            final HttpParams params) {
         super();
-        if (buffer == null) {
-            throw new IllegalArgumentException("Session input buffer may not be null");
-        }
-        if (params == null) {
-            throw new IllegalArgumentException("HTTP parameters may not be null");
-        }
+        Args.notNull(buffer, "Session input buffer");
+        Args.notNull(params, "HTTP parameters");
         this.sessionBuffer = buffer;
         this.state = READ_HEAD_LINE;
         this.endOfStream = false;
         this.headerBufs = new ArrayList<CharArrayBuffer>();
-        this.maxLineLen = params.getIntParameter(
-                CoreConnectionPNames.MAX_LINE_LENGTH, -1);
-        this.maxHeaderCount = params.getIntParameter(
-                CoreConnectionPNames.MAX_HEADER_COUNT, -1);
-        this.lineParser = (parser != null) ? parser : BasicLineParser.DEFAULT;
+        this.constraints = HttpParamConfig.getMessageConstraints(params);
+        this.lineParser = (lineParser != null) ? lineParser : BasicLineParser.INSTANCE;
+    }
+
+    /**
+     * Creates an instance of AbstractMessageParser.
+     *
+     * @param buffer the session input buffer.
+     * @param lineParser the line parser. If <code>null</code> {@link BasicLineParser#INSTANCE}
+     *   will be used.
+     * @param constraints Message constraints. If <code>null</code>
+     *   {@link MessageConstraints#DEFAULT} will be used.
+     *
+     * @since 4.3
+     */
+    public AbstractMessageParser(
+            final SessionInputBuffer buffer,
+            final LineParser lineParser,
+            final MessageConstraints constraints) {
+        super();
+        this.sessionBuffer = Args.notNull(buffer, "Session input buffer");
+        this.lineParser = lineParser != null ? lineParser : BasicLineParser.INSTANCE;
+        this.constraints = constraints != null ? constraints : MessageConstraints.DEFAULT;
+        this.headerBufs = new ArrayList<CharArrayBuffer>();
+        this.state = READ_HEAD_LINE;
+        this.endOfStream = false;
     }
 
     public void reset() {
@@ -112,7 +133,7 @@ public abstract class AbstractMessageParser<T extends HttpMessage> implements NH
     }
 
     public int fillBuffer(final ReadableByteChannel channel) throws IOException {
-        int bytesRead = this.sessionBuffer.fill(channel);
+        final int bytesRead = this.sessionBuffer.fill(channel);
         if (bytesRead == -1) {
             this.endOfStream = true;
         }
@@ -136,22 +157,22 @@ public abstract class AbstractMessageParser<T extends HttpMessage> implements NH
     }
 
     private void parseHeader() throws IOException {
-        CharArrayBuffer current = this.lineBuf;
-        int count = this.headerBufs.size();
+        final CharArrayBuffer current = this.lineBuf;
+        final int count = this.headerBufs.size();
         if ((this.lineBuf.charAt(0) == ' ' || this.lineBuf.charAt(0) == '\t') && count > 0) {
             // Handle folded header line
-            CharArrayBuffer previous = this.headerBufs.get(count - 1);
+            final CharArrayBuffer previous = this.headerBufs.get(count - 1);
             int i = 0;
             while (i < current.length()) {
-                char ch = current.charAt(i);
+                final char ch = current.charAt(i);
                 if (ch != ' ' && ch != '\t') {
                     break;
                 }
                 i++;
             }
-            if (this.maxLineLen > 0
-                    && previous.length() + 1 + current.length() - i > this.maxLineLen) {
-                throw new IOException("Maximum line length limit exceeded");
+            final int maxLineLen = this.constraints.getMaxLineLength();
+            if (maxLineLen > 0 && previous.length() + 1 + current.length() - i > maxLineLen) {
+                throw new MessageConstraintException("Maximum line length limit exceeded");
             }
             previous.append(' ');
             previous.append(current, i, current.length() - i);
@@ -168,11 +189,12 @@ public abstract class AbstractMessageParser<T extends HttpMessage> implements NH
             } else {
                 this.lineBuf.clear();
             }
-            boolean lineComplete = this.sessionBuffer.readLine(this.lineBuf, this.endOfStream);
-            if (this.maxLineLen > 0 &&
-                    (this.lineBuf.length() > this.maxLineLen ||
-                            (!lineComplete && this.sessionBuffer.length() > this.maxLineLen))) {
-                throw new IOException("Maximum line length limit exceeded");
+            final boolean lineComplete = this.sessionBuffer.readLine(this.lineBuf, this.endOfStream);
+            final int maxLineLen = this.constraints.getMaxLineLength();
+            if (maxLineLen > 0 &&
+                    (this.lineBuf.length() > maxLineLen ||
+                            (!lineComplete && this.sessionBuffer.length() > maxLineLen))) {
+                throw new MessageConstraintException("Maximum line length limit exceeded");
             }
             if (!lineComplete) {
                 break;
@@ -182,15 +204,16 @@ public abstract class AbstractMessageParser<T extends HttpMessage> implements NH
             case READ_HEAD_LINE:
                 try {
                     parseHeadLine();
-                } catch (ParseException px) {
+                } catch (final ParseException px) {
                     throw new ProtocolException(px.getMessage(), px);
                 }
                 this.state = READ_HEADERS;
                 break;
             case READ_HEADERS:
                 if (this.lineBuf.length() > 0) {
-                    if (this.maxHeaderCount > 0 && headerBufs.size() >= this.maxHeaderCount) {
-                        throw new IOException("Maximum header count exceeded");
+                    final int maxHeaderCount = this.constraints.getMaxHeaderCount();
+                    if (maxHeaderCount > 0 && headerBufs.size() >= maxHeaderCount) {
+                        throw new MessageConstraintException("Maximum header count exceeded");
                     }
 
                     parseHeader();
@@ -204,11 +227,10 @@ public abstract class AbstractMessageParser<T extends HttpMessage> implements NH
             }
         }
         if (this.state == COMPLETED) {
-            for (int i = 0; i < this.headerBufs.size(); i++) {
-                CharArrayBuffer buffer = this.headerBufs.get(i);
+            for (final CharArrayBuffer buffer : this.headerBufs) {
                 try {
                     this.message.addHeader(lineParser.parseHeader(buffer));
-                } catch (ParseException ex) {
+                } catch (final ParseException ex) {
                     throw new ProtocolException(ex.getMessage(), ex);
                 }
             }
diff --git a/httpcore-nio/src/main/java/org/apache/http/impl/nio/codecs/AbstractMessageWriter.java b/httpcore-nio/src/main/java/org/apache/http/impl/nio/codecs/AbstractMessageWriter.java
index ea6637d..8c29e52 100644
--- a/httpcore-nio/src/main/java/org/apache/http/impl/nio/codecs/AbstractMessageWriter.java
+++ b/httpcore-nio/src/main/java/org/apache/http/impl/nio/codecs/AbstractMessageWriter.java
@@ -34,11 +34,12 @@ import org.apache.http.Header;
 import org.apache.http.HttpException;
 import org.apache.http.HttpMessage;
 import org.apache.http.annotation.NotThreadSafe;
-import org.apache.http.message.LineFormatter;
 import org.apache.http.message.BasicLineFormatter;
+import org.apache.http.message.LineFormatter;
 import org.apache.http.nio.NHttpMessageWriter;
 import org.apache.http.nio.reactor.SessionOutputBuffer;
 import org.apache.http.params.HttpParams;
+import org.apache.http.util.Args;
 import org.apache.http.util.CharArrayBuffer;
 
 /**
@@ -47,6 +48,7 @@ import org.apache.http.util.CharArrayBuffer;
  *
  * @since 4.0
  */
+ at SuppressWarnings("deprecation")
 @NotThreadSafe
 public abstract class AbstractMessageWriter<T extends HttpMessage> implements NHttpMessageWriter<T> {
 
@@ -60,18 +62,37 @@ public abstract class AbstractMessageWriter<T extends HttpMessage> implements NH
      * @param buffer the session output buffer.
      * @param formatter the line formatter.
      * @param params HTTP parameters.
+     *
+     * @deprecated (4.3) use
+     *   {@link AbstractMessageWriter#AbstractMessageWriter(SessionOutputBuffer, LineFormatter)}
      */
+    @Deprecated
     public AbstractMessageWriter(final SessionOutputBuffer buffer,
                                  final LineFormatter formatter,
                                  final HttpParams params) {
         super();
-        if (buffer == null) {
-            throw new IllegalArgumentException("Session input buffer may not be null");
-        }
+        Args.notNull(buffer, "Session input buffer");
         this.sessionBuffer = buffer;
         this.lineBuf = new CharArrayBuffer(64);
-        this.lineFormatter = (formatter != null) ?
-            formatter : BasicLineFormatter.DEFAULT;
+        this.lineFormatter = (formatter != null) ? formatter : BasicLineFormatter.INSTANCE;
+    }
+
+    /**
+     * Creates an instance of AbstractMessageWriter.
+     *
+     * @param buffer the session output buffer.
+     * @param formatter the line formatter If <code>null</code> {@link BasicLineFormatter#INSTANCE}
+     *   will be used.
+     *
+     * @since 4.3
+     */
+    public AbstractMessageWriter(
+            final SessionOutputBuffer buffer,
+            final LineFormatter formatter) {
+        super();
+        this.sessionBuffer = Args.notNull(buffer, "Session input buffer");
+        this.lineFormatter = (formatter != null) ? formatter : BasicLineFormatter.INSTANCE;
+        this.lineBuf = new CharArrayBuffer(64);
     }
 
     public void reset() {
@@ -81,17 +102,14 @@ public abstract class AbstractMessageWriter<T extends HttpMessage> implements NH
      * Writes out the first line of {@link HttpMessage}.
      *
      * @param message HTTP message.
-     * @throws HttpException in case of HTTP protocol violation
      */
     protected abstract void writeHeadLine(T message) throws IOException;
 
     public void write(final T message) throws IOException, HttpException {
-        if (message == null) {
-            throw new IllegalArgumentException("HTTP message may not be null");
-        }
+        Args.notNull(message, "HTTP message");
         writeHeadLine(message);
-        for (Iterator<?> it = message.headerIterator(); it.hasNext(); ) {
-            Header header = (Header) it.next();
+        for (final Iterator<?> it = message.headerIterator(); it.hasNext(); ) {
+            final Header header = (Header) it.next();
             this.sessionBuffer.writeLine
                 (lineFormatter.formatHeader(this.lineBuf, header));
         }
diff --git a/httpcore-nio/src/main/java/org/apache/http/impl/nio/codecs/ChunkDecoder.java b/httpcore-nio/src/main/java/org/apache/http/impl/nio/codecs/ChunkDecoder.java
index 48e9ffb..d5ed74a 100644
--- a/httpcore-nio/src/main/java/org/apache/http/impl/nio/codecs/ChunkDecoder.java
+++ b/httpcore-nio/src/main/java/org/apache/http/impl/nio/codecs/ChunkDecoder.java
@@ -35,13 +35,14 @@ import java.util.List;
 
 import org.apache.http.Header;
 import org.apache.http.MalformedChunkCodingException;
+import org.apache.http.ParseException;
 import org.apache.http.TruncatedChunkException;
-import org.apache.http.message.BufferedHeader;
-import org.apache.http.nio.reactor.SessionInputBuffer;
 import org.apache.http.annotation.NotThreadSafe;
 import org.apache.http.impl.io.HttpTransportMetricsImpl;
-import org.apache.http.ParseException;
+import org.apache.http.message.BufferedHeader;
+import org.apache.http.nio.reactor.SessionInputBuffer;
 import org.apache.http.protocol.HTTP;
+import org.apache.http.util.Args;
 import org.apache.http.util.CharArrayBuffer;
 
 /**
@@ -87,8 +88,8 @@ public class ChunkDecoder extends AbstractContentDecoder {
             if (this.buffer.length() < 2) {
                 return;
             }
-            int cr = this.buffer.read();
-            int lf = this.buffer.read();
+            final int cr = this.buffer.read();
+            final int lf = this.buffer.read();
             if (cr != HTTP.CR || lf != HTTP.LF) {
                 throw new MalformedChunkCodingException("CRLF expected at end of chunk");
             }
@@ -105,9 +106,9 @@ public class ChunkDecoder extends AbstractContentDecoder {
                 separator = this.lineBuf.length();
             }
             try {
-                String s = this.lineBuf.substringTrimmed(0, separator);
+                final String s = this.lineBuf.substringTrimmed(0, separator);
                 this.chunkSize = Integer.parseInt(s, 16);
-            } catch (NumberFormatException e) {
+            } catch (final NumberFormatException e) {
                 throw new MalformedChunkCodingException("Bad chunk header");
             }
             this.pos = 0;
@@ -115,14 +116,14 @@ public class ChunkDecoder extends AbstractContentDecoder {
     }
 
     private void parseHeader() {
-        CharArrayBuffer current = this.lineBuf;
-        int count = this.trailerBufs.size();
+        final CharArrayBuffer current = this.lineBuf;
+        final int count = this.trailerBufs.size();
         if ((this.lineBuf.charAt(0) == ' ' || this.lineBuf.charAt(0) == '\t') && count > 0) {
             // Handle folded header line
-            CharArrayBuffer previous = this.trailerBufs.get(count - 1);
+            final CharArrayBuffer previous = this.trailerBufs.get(count - 1);
             int i = 0;
             while (i < current.length()) {
-                char ch = current.charAt(i);
+                final char ch = current.charAt(i);
                 if (ch != ' ' && ch != '\t') {
                     break;
                 }
@@ -137,14 +138,14 @@ public class ChunkDecoder extends AbstractContentDecoder {
     }
 
     private void processFooters() throws IOException {
-        int count = this.trailerBufs.size();
+        final int count = this.trailerBufs.size();
         if (count > 0) {
             this.footers = new Header[this.trailerBufs.size()];
             for (int i = 0; i < this.trailerBufs.size(); i++) {
-                CharArrayBuffer buffer = this.trailerBufs.get(i);
+                final CharArrayBuffer buffer = this.trailerBufs.get(i);
                 try {
                     this.footers[i] = new BufferedHeader(buffer);
-                } catch (ParseException ex) {
+                } catch (final ParseException ex) {
                     throw new IOException(ex.getMessage());
                 }
             }
@@ -153,9 +154,7 @@ public class ChunkDecoder extends AbstractContentDecoder {
     }
 
     public int read(final ByteBuffer dst) throws IOException {
-        if (dst == null) {
-            throw new IllegalArgumentException("Byte buffer may not be null");
-        }
+        Args.notNull(dst, "Byte buffer");
         if (this.state == COMPLETED) {
             return -1;
         }
@@ -164,10 +163,7 @@ public class ChunkDecoder extends AbstractContentDecoder {
         while (this.state != COMPLETED) {
 
             if (!this.buffer.hasData() || this.chunkSize == -1) {
-                int bytesRead = this.buffer.fill(this.channel);
-                if (bytesRead > 0) {
-                    this.metrics.incrementBytesTransferred(bytesRead);
-                }
+                final int bytesRead = fillBufferFromChannel();
                 if (bytesRead == -1) {
                     this.endOfStream = true;
                 }
@@ -193,8 +189,8 @@ public class ChunkDecoder extends AbstractContentDecoder {
                         break;
                     }
                 }
-                int maxLen = this.chunkSize - this.pos;
-                int len = this.buffer.read(dst, maxLen);
+                final int maxLen = this.chunkSize - this.pos;
+                final int len = this.buffer.read(dst, maxLen);
                 if (len > 0) {
                     this.pos += len;
                     totalRead += len;
@@ -254,7 +250,7 @@ public class ChunkDecoder extends AbstractContentDecoder {
 
     @Override
     public String toString() {
-        StringBuilder buffer = new StringBuilder();
+        final StringBuilder buffer = new StringBuilder();
         buffer.append("[chunk-coded; completed: ");
         buffer.append(this.completed);
         buffer.append("]");
diff --git a/httpcore-nio/src/main/java/org/apache/http/impl/nio/codecs/ChunkEncoder.java b/httpcore-nio/src/main/java/org/apache/http/impl/nio/codecs/ChunkEncoder.java
index 1fe1b7c..4384b82 100644
--- a/httpcore-nio/src/main/java/org/apache/http/impl/nio/codecs/ChunkEncoder.java
+++ b/httpcore-nio/src/main/java/org/apache/http/impl/nio/codecs/ChunkEncoder.java
@@ -46,15 +46,28 @@ import org.apache.http.util.CharArrayBuffer;
 @NotThreadSafe
 public class ChunkEncoder extends AbstractContentEncoder {
 
+    private final int fragHint;
     private final CharArrayBuffer lineBuffer;
 
     private final BufferInfo bufferinfo;
 
+    /**
+     * @since 4.3
+     *
+     * @param channel underlying channel.
+     * @param buffer  session buffer.
+     * @param metrics transport metrics.
+     * @param fragementSizeHint fragment size hint defining an minimal size of a fragment
+     *   that should be written out directly to the channel bypassing the session buffer.
+     *   Value <code>0</code> disables fragment buffering.
+     */
     public ChunkEncoder(
             final WritableByteChannel channel,
             final SessionOutputBuffer buffer,
-            final HttpTransportMetricsImpl metrics) {
+            final HttpTransportMetricsImpl metrics,
+            final int fragementSizeHint) {
         super(channel, buffer, metrics);
+        this.fragHint = fragementSizeHint > 0 ? fragementSizeHint : 0;
         this.lineBuffer = new CharArrayBuffer(16);
         if (buffer instanceof BufferInfo) {
             this.bufferinfo = (BufferInfo) buffer;
@@ -63,53 +76,63 @@ public class ChunkEncoder extends AbstractContentEncoder {
         }
     }
 
+    public ChunkEncoder(
+            final WritableByteChannel channel,
+            final SessionOutputBuffer buffer,
+            final HttpTransportMetricsImpl metrics) {
+        this(channel, buffer, metrics, 0);
+    }
+
     public int write(final ByteBuffer src) throws IOException {
         if (src == null) {
             return 0;
         }
         assertNotCompleted();
-        int chunk = src.remaining();
-        if (chunk == 0) {
-            return 0;
-        }
 
-        long bytesWritten = this.buffer.flush(this.channel);
-        if (bytesWritten > 0) {
-            this.metrics.incrementBytesTransferred(bytesWritten);
-        }
-        int avail;
-        if (this.bufferinfo != null) {
-            avail = this.bufferinfo.available();
-        } else {
-            avail = 4096;
-        }
+        int total = 0;
+        while (src.hasRemaining()) {
+            int chunk = src.remaining();
+            int avail;
+            if (this.bufferinfo != null) {
+                avail = this.bufferinfo.available();
+            } else {
+                avail = 4096;
+            }
 
-        // subtract the length of the longest chunk header
-        // 12345678\r\n
-        // <chunk-data>\r\n
-        avail -= 12;
-        if (avail <= 0) {
-            return 0;
-        } else if (avail < chunk) {
-            // write no more than 'avail' bytes
-            chunk = avail;
-            this.lineBuffer.clear();
-            this.lineBuffer.append(Integer.toHexString(chunk));
-            this.buffer.writeLine(this.lineBuffer);
-            int oldlimit = src.limit();
-            src.limit(src.position() + chunk);
-            this.buffer.write(src);
-            src.limit(oldlimit);
-        } else {
-            // write all
-            this.lineBuffer.clear();
-            this.lineBuffer.append(Integer.toHexString(chunk));
-            this.buffer.writeLine(this.lineBuffer);
-            this.buffer.write(src);
+            // subtract the length of the longest chunk header
+            // 12345678\r\n
+            // <chunk-data>\r\n
+            avail -= 12;
+            if (avail > 0) {
+                if (avail < chunk) {
+                    // write no more than 'avail' bytes
+                    chunk = avail;
+                    this.lineBuffer.clear();
+                    this.lineBuffer.append(Integer.toHexString(chunk));
+                    this.buffer.writeLine(this.lineBuffer);
+                    final int oldlimit = src.limit();
+                    src.limit(src.position() + chunk);
+                    this.buffer.write(src);
+                    src.limit(oldlimit);
+                } else {
+                    // write all
+                    this.lineBuffer.clear();
+                    this.lineBuffer.append(Integer.toHexString(chunk));
+                    this.buffer.writeLine(this.lineBuffer);
+                    this.buffer.write(src);
+                }
+                this.lineBuffer.clear();
+                this.buffer.writeLine(this.lineBuffer);
+                total += chunk;
+            }
+            if (this.buffer.length() >= this.fragHint || src.hasRemaining()) {
+                final int bytesWritten = flushToChannel();
+                if (bytesWritten == 0) {
+                    break;
+                }
+            }
         }
-        this.lineBuffer.clear();
-        this.buffer.writeLine(this.lineBuffer);
-        return chunk;
+        return total;
     }
 
     @Override
@@ -120,14 +143,14 @@ public class ChunkEncoder extends AbstractContentEncoder {
         this.buffer.writeLine(this.lineBuffer);
         this.lineBuffer.clear();
         this.buffer.writeLine(this.lineBuffer);
-        this.completed = true; // == super.complete()
+        super.complete();
     }
 
     @Override
     public String toString() {
-        StringBuilder buffer = new StringBuilder();
+        final StringBuilder buffer = new StringBuilder();
         buffer.append("[chunk-coded; completed: ");
-        buffer.append(this.completed);
+        buffer.append(isCompleted());
         buffer.append("]");
         return buffer.toString();
     }
diff --git a/httpcore-nio/src/main/java/org/apache/http/impl/nio/codecs/DefaultHttpRequestParser.java b/httpcore-nio/src/main/java/org/apache/http/impl/nio/codecs/DefaultHttpRequestParser.java
index e1a4917..bb20b0e 100644
--- a/httpcore-nio/src/main/java/org/apache/http/impl/nio/codecs/DefaultHttpRequestParser.java
+++ b/httpcore-nio/src/main/java/org/apache/http/impl/nio/codecs/DefaultHttpRequestParser.java
@@ -30,50 +30,93 @@ package org.apache.http.impl.nio.codecs;
 import org.apache.http.HttpException;
 import org.apache.http.HttpRequest;
 import org.apache.http.HttpRequestFactory;
-import org.apache.http.RequestLine;
 import org.apache.http.ParseException;
+import org.apache.http.RequestLine;
 import org.apache.http.annotation.NotThreadSafe;
+import org.apache.http.config.MessageConstraints;
+import org.apache.http.impl.DefaultHttpRequestFactory;
 import org.apache.http.message.LineParser;
 import org.apache.http.message.ParserCursor;
-import org.apache.http.nio.NHttpMessageParser;
 import org.apache.http.nio.reactor.SessionInputBuffer;
 import org.apache.http.params.HttpParams;
+import org.apache.http.util.Args;
 import org.apache.http.util.CharArrayBuffer;
 
 /**
- * Default {@link NHttpMessageParser} implementation for {@link HttpRequest}s.
- * <p>
- * The following parameters can be used to customize the behavior of this
- * class:
- * <ul>
- *  <li>{@link org.apache.http.params.CoreConnectionPNames#MAX_HEADER_COUNT}</li>
- *  <li>{@link org.apache.http.params.CoreConnectionPNames#MAX_LINE_LENGTH}</li>
- * </ul>
+ * Default {@link org.apache.http.nio.NHttpMessageParser} implementation
+ * for {@link HttpRequest}s.
  *
  * @since 4.1
  */
+ at SuppressWarnings("deprecation")
 @NotThreadSafe
 public class DefaultHttpRequestParser extends AbstractMessageParser<HttpRequest> {
 
     private final HttpRequestFactory requestFactory;
 
+    /**
+     * Creates an instance of this class.
+     *
+     * @param buffer the session input buffer.
+     * @param parser the line parser.
+     * @param params HTTP parameters.
+     *
+     * @deprecated (4.3) use
+     *   {@link DefaultHttpRequestParser#DefaultHttpRequestParser(
+     *   SessionInputBuffer, LineParser, HttpRequestFactory, MessageConstraints)}
+     */
+    @Deprecated
     public DefaultHttpRequestParser(
             final SessionInputBuffer buffer,
             final LineParser parser,
             final HttpRequestFactory requestFactory,
             final HttpParams params) {
         super(buffer, parser, params);
-        if (requestFactory == null) {
-            throw new IllegalArgumentException("Request factory may not be null");
-        }
+        Args.notNull(requestFactory, "Request factory");
         this.requestFactory = requestFactory;
     }
 
+    /**
+     * Creates an instance of DefaultHttpRequestParser.
+     *
+     * @param buffer the session input buffer.
+     * @param parser the line parser. If <code>null</code>
+     *   {@link org.apache.http.message.BasicLineParser#INSTANCE} will be used.
+     * @param requestFactory the request factory. If <code>null</code>
+     *   {@link DefaultHttpRequestFactory#INSTANCE} will be used.
+     * @param constraints Message constraints. If <code>null</code>
+     *   {@link MessageConstraints#DEFAULT} will be used.
+     *
+     * @since 4.3
+     */
+    public DefaultHttpRequestParser(
+            final SessionInputBuffer buffer,
+            final LineParser parser,
+            final HttpRequestFactory requestFactory,
+            final MessageConstraints constraints) {
+        super(buffer, parser, constraints);
+        this.requestFactory = requestFactory != null ? requestFactory : DefaultHttpRequestFactory.INSTANCE;
+    }
+
+    /**
+    * @since 4.3
+    */
+    public DefaultHttpRequestParser(final SessionInputBuffer buffer, final MessageConstraints constraints) {
+        this(buffer, null, null, constraints);
+    }
+
+    /**
+    * @since 4.3
+    */
+    public DefaultHttpRequestParser(final SessionInputBuffer buffer) {
+        this(buffer, null);
+    }
+
     @Override
     protected HttpRequest createMessage(final CharArrayBuffer buffer)
             throws HttpException, ParseException {
-        ParserCursor cursor = new ParserCursor(0, buffer.length());
-        RequestLine requestLine = lineParser.parseRequestLine(buffer, cursor);
+        final ParserCursor cursor = new ParserCursor(0, buffer.length());
+        final RequestLine requestLine = lineParser.parseRequestLine(buffer, cursor);
         return this.requestFactory.newHttpRequest(requestLine);
     }
 
diff --git a/httpcore-nio/src/main/java/org/apache/http/impl/nio/codecs/DefaultHttpRequestParser.java b/httpcore-nio/src/main/java/org/apache/http/impl/nio/codecs/DefaultHttpRequestParserFactory.java
similarity index 50%
copy from httpcore-nio/src/main/java/org/apache/http/impl/nio/codecs/DefaultHttpRequestParser.java
copy to httpcore-nio/src/main/java/org/apache/http/impl/nio/codecs/DefaultHttpRequestParserFactory.java
index e1a4917..507f769 100644
--- a/httpcore-nio/src/main/java/org/apache/http/impl/nio/codecs/DefaultHttpRequestParser.java
+++ b/httpcore-nio/src/main/java/org/apache/http/impl/nio/codecs/DefaultHttpRequestParserFactory.java
@@ -27,54 +27,45 @@
 
 package org.apache.http.impl.nio.codecs;
 
-import org.apache.http.HttpException;
 import org.apache.http.HttpRequest;
 import org.apache.http.HttpRequestFactory;
-import org.apache.http.RequestLine;
-import org.apache.http.ParseException;
-import org.apache.http.annotation.NotThreadSafe;
+import org.apache.http.annotation.Immutable;
+import org.apache.http.config.MessageConstraints;
+import org.apache.http.impl.DefaultHttpRequestFactory;
+import org.apache.http.message.BasicLineParser;
 import org.apache.http.message.LineParser;
-import org.apache.http.message.ParserCursor;
 import org.apache.http.nio.NHttpMessageParser;
+import org.apache.http.nio.NHttpMessageParserFactory;
 import org.apache.http.nio.reactor.SessionInputBuffer;
-import org.apache.http.params.HttpParams;
-import org.apache.http.util.CharArrayBuffer;
 
 /**
- * Default {@link NHttpMessageParser} implementation for {@link HttpRequest}s.
- * <p>
- * The following parameters can be used to customize the behavior of this
- * class:
- * <ul>
- *  <li>{@link org.apache.http.params.CoreConnectionPNames#MAX_HEADER_COUNT}</li>
- *  <li>{@link org.apache.http.params.CoreConnectionPNames#MAX_LINE_LENGTH}</li>
- * </ul>
+ * Default factory for request message parsers.
  *
- * @since 4.1
+ * @since 4.3
  */
- at NotThreadSafe
-public class DefaultHttpRequestParser extends AbstractMessageParser<HttpRequest> {
+ at Immutable
+public class DefaultHttpRequestParserFactory implements NHttpMessageParserFactory<HttpRequest> {
 
+    public static final DefaultHttpRequestParserFactory INSTANCE = new DefaultHttpRequestParserFactory();
+
+    private final LineParser lineParser;
     private final HttpRequestFactory requestFactory;
 
-    public DefaultHttpRequestParser(
-            final SessionInputBuffer buffer,
-            final LineParser parser,
-            final HttpRequestFactory requestFactory,
-            final HttpParams params) {
-        super(buffer, parser, params);
-        if (requestFactory == null) {
-            throw new IllegalArgumentException("Request factory may not be null");
-        }
-        this.requestFactory = requestFactory;
+    public DefaultHttpRequestParserFactory(final LineParser lineParser,
+            final HttpRequestFactory requestFactory) {
+        super();
+        this.lineParser = lineParser != null ? lineParser : BasicLineParser.INSTANCE;
+        this.requestFactory = requestFactory != null ? requestFactory
+                : DefaultHttpRequestFactory.INSTANCE;
+    }
+
+    public DefaultHttpRequestParserFactory() {
+        this(null, null);
     }
 
-    @Override
-    protected HttpRequest createMessage(final CharArrayBuffer buffer)
-            throws HttpException, ParseException {
-        ParserCursor cursor = new ParserCursor(0, buffer.length());
-        RequestLine requestLine = lineParser.parseRequestLine(buffer, cursor);
-        return this.requestFactory.newHttpRequest(requestLine);
+    public NHttpMessageParser<HttpRequest> create(final SessionInputBuffer buffer,
+            final MessageConstraints constraints) {
+        return new DefaultHttpRequestParser(buffer, lineParser, requestFactory, constraints);
     }
 
 }
diff --git a/httpcore-nio/src/main/java/org/apache/http/impl/nio/codecs/DefaultHttpRequestWriter.java b/httpcore-nio/src/main/java/org/apache/http/impl/nio/codecs/DefaultHttpRequestWriter.java
index f4ef092..15d9bc7 100644
--- a/httpcore-nio/src/main/java/org/apache/http/impl/nio/codecs/DefaultHttpRequestWriter.java
+++ b/httpcore-nio/src/main/java/org/apache/http/impl/nio/codecs/DefaultHttpRequestWriter.java
@@ -32,28 +32,56 @@ import java.io.IOException;
 import org.apache.http.HttpRequest;
 import org.apache.http.annotation.NotThreadSafe;
 import org.apache.http.message.LineFormatter;
-import org.apache.http.nio.NHttpMessageWriter;
 import org.apache.http.nio.reactor.SessionOutputBuffer;
 import org.apache.http.params.HttpParams;
 import org.apache.http.util.CharArrayBuffer;
 
 /**
- * Default {@link NHttpMessageWriter} implementation for {@link HttpRequest}s.
+ * Default {@link org.apache.http.nio.NHttpMessageWriter} implementation
+ * for {@link HttpRequest}s.
  *
  * @since 4.1
  */
+ at SuppressWarnings("deprecation")
 @NotThreadSafe
 public class DefaultHttpRequestWriter extends AbstractMessageWriter<HttpRequest> {
 
+    /**
+     * @deprecated (4.3) use
+     *   {@link DefaultHttpRequestWriter#DefaultHttpRequestWriter(SessionOutputBuffer, LineFormatter)}
+     */
+    @Deprecated
     public DefaultHttpRequestWriter(final SessionOutputBuffer buffer,
                              final LineFormatter formatter,
                              final HttpParams params) {
         super(buffer, formatter, params);
     }
 
+    /**
+     * Creates an instance of DefaultHttpRequestWriter.
+     *
+     * @param buffer the session output buffer.
+     * @param formatter the line formatter If <code>null</code>
+     *   {@link org.apache.http.message.BasicLineFormatter#INSTANCE} will be used.
+     *
+     * @since 4.3
+     */
+    public DefaultHttpRequestWriter(
+            final SessionOutputBuffer buffer,
+            final LineFormatter formatter) {
+        super(buffer, formatter);
+    }
+
+    /**
+     * @since 4.3
+     */
+    public DefaultHttpRequestWriter(final SessionOutputBuffer buffer) {
+        super(buffer, null);
+    }
+
     @Override
     protected void writeHeadLine(final HttpRequest message) throws IOException {
-        CharArrayBuffer buffer = lineFormatter.formatRequestLine(
+        final CharArrayBuffer buffer = lineFormatter.formatRequestLine(
                 this.lineBuf, message.getRequestLine());
         this.sessionBuffer.writeLine(buffer);
     }
diff --git a/httpcore-nio/src/main/java/org/apache/http/impl/nio/codecs/DefaultHttpRequestWriter.java b/httpcore-nio/src/main/java/org/apache/http/impl/nio/codecs/DefaultHttpRequestWriterFactory.java
similarity index 61%
copy from httpcore-nio/src/main/java/org/apache/http/impl/nio/codecs/DefaultHttpRequestWriter.java
copy to httpcore-nio/src/main/java/org/apache/http/impl/nio/codecs/DefaultHttpRequestWriterFactory.java
index f4ef092..2a4714c 100644
--- a/httpcore-nio/src/main/java/org/apache/http/impl/nio/codecs/DefaultHttpRequestWriter.java
+++ b/httpcore-nio/src/main/java/org/apache/http/impl/nio/codecs/DefaultHttpRequestWriterFactory.java
@@ -27,35 +27,37 @@
 
 package org.apache.http.impl.nio.codecs;
 
-import java.io.IOException;
-
 import org.apache.http.HttpRequest;
-import org.apache.http.annotation.NotThreadSafe;
+import org.apache.http.annotation.Immutable;
+import org.apache.http.message.BasicLineFormatter;
 import org.apache.http.message.LineFormatter;
 import org.apache.http.nio.NHttpMessageWriter;
+import org.apache.http.nio.NHttpMessageWriterFactory;
 import org.apache.http.nio.reactor.SessionOutputBuffer;
-import org.apache.http.params.HttpParams;
-import org.apache.http.util.CharArrayBuffer;
 
 /**
- * Default {@link NHttpMessageWriter} implementation for {@link HttpRequest}s.
+ * Default factory for request message writers.
  *
- * @since 4.1
+ * @since 4.3
  */
- at NotThreadSafe
-public class DefaultHttpRequestWriter extends AbstractMessageWriter<HttpRequest> {
+ at Immutable
+public class DefaultHttpRequestWriterFactory implements NHttpMessageWriterFactory<HttpRequest> {
+
+    public static final DefaultHttpRequestWriterFactory INSTANCE = new DefaultHttpRequestWriterFactory();
+
+    private final LineFormatter lineFormatter;
+
+    public DefaultHttpRequestWriterFactory(final LineFormatter lineFormatter) {
+        super();
+        this.lineFormatter = lineFormatter != null ? lineFormatter : BasicLineFormatter.INSTANCE;
+    }
 
-    public DefaultHttpRequestWriter(final SessionOutputBuffer buffer,
-                             final LineFormatter formatter,
-                             final HttpParams params) {
-        super(buffer, formatter, params);
+    public DefaultHttpRequestWriterFactory() {
+        this(null);
     }
 
-    @Override
-    protected void writeHeadLine(final HttpRequest message) throws IOException {
-        CharArrayBuffer buffer = lineFormatter.formatRequestLine(
-                this.lineBuf, message.getRequestLine());
-        this.sessionBuffer.writeLine(buffer);
+    public NHttpMessageWriter<HttpRequest> create(final SessionOutputBuffer buffer) {
+        return new DefaultHttpRequestWriter(buffer, lineFormatter);
     }
 
 }
diff --git a/httpcore-nio/src/main/java/org/apache/http/impl/nio/codecs/DefaultHttpResponseParser.java b/httpcore-nio/src/main/java/org/apache/http/impl/nio/codecs/DefaultHttpResponseParser.java
index 122aa81..9874838 100644
--- a/httpcore-nio/src/main/java/org/apache/http/impl/nio/codecs/DefaultHttpResponseParser.java
+++ b/httpcore-nio/src/main/java/org/apache/http/impl/nio/codecs/DefaultHttpResponseParser.java
@@ -30,50 +30,88 @@ package org.apache.http.impl.nio.codecs;
 import org.apache.http.HttpException;
 import org.apache.http.HttpResponse;
 import org.apache.http.HttpResponseFactory;
-import org.apache.http.StatusLine;
 import org.apache.http.ParseException;
+import org.apache.http.StatusLine;
 import org.apache.http.annotation.NotThreadSafe;
+import org.apache.http.config.MessageConstraints;
+import org.apache.http.impl.DefaultHttpResponseFactory;
 import org.apache.http.message.LineParser;
 import org.apache.http.message.ParserCursor;
-import org.apache.http.nio.NHttpMessageParser;
 import org.apache.http.nio.reactor.SessionInputBuffer;
 import org.apache.http.params.HttpParams;
+import org.apache.http.util.Args;
 import org.apache.http.util.CharArrayBuffer;
 
 /**
- * Default {@link NHttpMessageParser} implementation for {@link HttpResponse}s.
- * <p>
- * The following parameters can be used to customize the behavior of this
- * class:
- * <ul>
- *  <li>{@link org.apache.http.params.CoreConnectionPNames#MAX_HEADER_COUNT}</li>
- *  <li>{@link org.apache.http.params.CoreConnectionPNames#MAX_LINE_LENGTH}</li>
- * </ul>
+ * Default {@link org.apache.http.nio.NHttpMessageParser} implementation
+ * for {@link HttpResponse}s.
  *
  * @since 4.1
  */
+ at SuppressWarnings("deprecation")
 @NotThreadSafe
 public class DefaultHttpResponseParser extends AbstractMessageParser<HttpResponse> {
 
     private final HttpResponseFactory responseFactory;
 
+    /**
+     * @deprecated (4.3) use
+     *   {@link DefaultHttpResponseParser#DefaultHttpResponseParser(
+     *   SessionInputBuffer, LineParser, HttpResponseFactory, MessageConstraints)}
+     */
+    @Deprecated
     public DefaultHttpResponseParser(
             final SessionInputBuffer buffer,
             final LineParser parser,
             final HttpResponseFactory responseFactory,
             final HttpParams params) {
         super(buffer, parser, params);
-        if (responseFactory == null) {
-            throw new IllegalArgumentException("Response factory may not be null");
-        }
+        Args.notNull(responseFactory, "Response factory");
         this.responseFactory = responseFactory;
     }
 
+    /**
+     * Creates an instance of DefaultHttpResponseParser.
+     *
+     * @param buffer the session input buffer.
+     * @param parser the line parser. If <code>null</code>
+     *   {@link org.apache.http.message.BasicLineParser#INSTANCE} will be used.
+     * @param responseFactory the response factory. If <code>null</code>
+     *   {@link DefaultHttpResponseFactory#INSTANCE} will be used.
+     * @param constraints Message constraints. If <code>null</code>
+     *   {@link MessageConstraints#DEFAULT} will be used.
+     *
+     * @since 4.3
+     */
+    public DefaultHttpResponseParser(
+            final SessionInputBuffer buffer,
+            final LineParser parser,
+            final HttpResponseFactory responseFactory,
+            final MessageConstraints constraints) {
+        super(buffer, parser, constraints);
+        this.responseFactory = responseFactory != null ? responseFactory :
+            DefaultHttpResponseFactory.INSTANCE;
+    }
+
+    /**
+     * @since 4.3
+     */
+    public DefaultHttpResponseParser(final SessionInputBuffer buffer, final MessageConstraints constraints) {
+        this(buffer, null, null, constraints);
+    }
+
+    /**
+     * @since 4.3
+     */
+    public DefaultHttpResponseParser(final SessionInputBuffer buffer) {
+        this(buffer, null);
+    }
+
     @Override
     protected HttpResponse createMessage(final CharArrayBuffer buffer)
             throws HttpException, ParseException {
-        ParserCursor cursor = new ParserCursor(0, buffer.length());
-        StatusLine statusline = lineParser.parseStatusLine(buffer, cursor);
+        final ParserCursor cursor = new ParserCursor(0, buffer.length());
+        final StatusLine statusline = lineParser.parseStatusLine(buffer, cursor);
         return this.responseFactory.newHttpResponse(statusline, null);
     }
 
diff --git a/httpcore-nio/src/main/java/org/apache/http/impl/nio/codecs/DefaultHttpResponseParserFactory.java b/httpcore-nio/src/main/java/org/apache/http/impl/nio/codecs/DefaultHttpResponseParserFactory.java
new file mode 100644
index 0000000..25af0e8
--- /dev/null
+++ b/httpcore-nio/src/main/java/org/apache/http/impl/nio/codecs/DefaultHttpResponseParserFactory.java
@@ -0,0 +1,71 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+
+package org.apache.http.impl.nio.codecs;
+
+import org.apache.http.HttpResponse;
+import org.apache.http.HttpResponseFactory;
+import org.apache.http.annotation.Immutable;
+import org.apache.http.config.MessageConstraints;
+import org.apache.http.impl.DefaultHttpResponseFactory;
+import org.apache.http.message.BasicLineParser;
+import org.apache.http.message.LineParser;
+import org.apache.http.nio.NHttpMessageParser;
+import org.apache.http.nio.NHttpMessageParserFactory;
+import org.apache.http.nio.reactor.SessionInputBuffer;
+
+/**
+ * Default factory for response message parsers.
+ *
+ * @since 4.3
+ */
+ at Immutable
+public class DefaultHttpResponseParserFactory implements NHttpMessageParserFactory<HttpResponse> {
+
+    public static final DefaultHttpResponseParserFactory INSTANCE = new DefaultHttpResponseParserFactory();
+
+    private final LineParser lineParser;
+    private final HttpResponseFactory responseFactory;
+
+    public DefaultHttpResponseParserFactory(final LineParser lineParser,
+            final HttpResponseFactory responseFactory) {
+        super();
+        this.lineParser = lineParser != null ? lineParser : BasicLineParser.INSTANCE;
+        this.responseFactory = responseFactory != null ? responseFactory
+                : DefaultHttpResponseFactory.INSTANCE;
+    }
+
+    public DefaultHttpResponseParserFactory() {
+        this(null, null);
+    }
+
+    public NHttpMessageParser<HttpResponse> create(final SessionInputBuffer buffer,
+            final MessageConstraints constraints) {
+        return new DefaultHttpResponseParser(buffer, lineParser, responseFactory, constraints);
+    }
+
+}
diff --git a/httpcore-nio/src/main/java/org/apache/http/impl/nio/codecs/DefaultHttpResponseWriter.java b/httpcore-nio/src/main/java/org/apache/http/impl/nio/codecs/DefaultHttpResponseWriter.java
index 6fd9de4..1dbad5a 100644
--- a/httpcore-nio/src/main/java/org/apache/http/impl/nio/codecs/DefaultHttpResponseWriter.java
+++ b/httpcore-nio/src/main/java/org/apache/http/impl/nio/codecs/DefaultHttpResponseWriter.java
@@ -32,28 +32,56 @@ import java.io.IOException;
 import org.apache.http.HttpResponse;
 import org.apache.http.annotation.NotThreadSafe;
 import org.apache.http.message.LineFormatter;
-import org.apache.http.nio.NHttpMessageWriter;
 import org.apache.http.nio.reactor.SessionOutputBuffer;
 import org.apache.http.params.HttpParams;
 import org.apache.http.util.CharArrayBuffer;
 
 /**
- * Default {@link NHttpMessageWriter} implementation for {@link HttpResponse}s.
+ * Default {@link org.apache.http.nio.NHttpMessageWriter} implementation
+ * for {@link HttpResponse}s.
  *
  * @since 4.1
  */
+ at SuppressWarnings("deprecation")
 @NotThreadSafe
 public class DefaultHttpResponseWriter extends AbstractMessageWriter<HttpResponse> {
 
+    /**
+     * @deprecated (4.3) use
+     *   {@link DefaultHttpResponseWriter#DefaultHttpResponseWriter(SessionOutputBuffer, LineFormatter)}
+     */
+    @Deprecated
     public DefaultHttpResponseWriter(final SessionOutputBuffer buffer,
                               final LineFormatter formatter,
                               final HttpParams params) {
         super(buffer, formatter, params);
     }
 
+    /**
+     * Creates an instance of DefaultHttpResponseWriter.
+     *
+     * @param buffer the session output buffer.
+     * @param formatter the line formatter If <code>null</code>
+     *   {@link org.apache.http.message.BasicLineFormatter#INSTANCE} will be used.
+     *
+     * @since 4.3
+     */
+    public DefaultHttpResponseWriter(
+            final SessionOutputBuffer buffer,
+            final LineFormatter formatter) {
+        super(buffer, formatter);
+    }
+
+    /**
+     * @since 4.3
+     */
+    public DefaultHttpResponseWriter(final SessionOutputBuffer buffer) {
+        super(buffer, null);
+    }
+
     @Override
     protected void writeHeadLine(final HttpResponse message) throws IOException {
-        CharArrayBuffer buffer = lineFormatter.formatStatusLine(
+        final CharArrayBuffer buffer = lineFormatter.formatStatusLine(
                 this.lineBuf, message.getStatusLine());
         this.sessionBuffer.writeLine(buffer);
     }
diff --git a/httpcore-nio/src/main/java/org/apache/http/impl/nio/codecs/DefaultHttpResponseWriter.java b/httpcore-nio/src/main/java/org/apache/http/impl/nio/codecs/DefaultHttpResponseWriterFactory.java
similarity index 61%
copy from httpcore-nio/src/main/java/org/apache/http/impl/nio/codecs/DefaultHttpResponseWriter.java
copy to httpcore-nio/src/main/java/org/apache/http/impl/nio/codecs/DefaultHttpResponseWriterFactory.java
index 6fd9de4..a5e300b 100644
--- a/httpcore-nio/src/main/java/org/apache/http/impl/nio/codecs/DefaultHttpResponseWriter.java
+++ b/httpcore-nio/src/main/java/org/apache/http/impl/nio/codecs/DefaultHttpResponseWriterFactory.java
@@ -27,35 +27,37 @@
 
 package org.apache.http.impl.nio.codecs;
 
-import java.io.IOException;
-
 import org.apache.http.HttpResponse;
-import org.apache.http.annotation.NotThreadSafe;
+import org.apache.http.annotation.Immutable;
+import org.apache.http.message.BasicLineFormatter;
 import org.apache.http.message.LineFormatter;
 import org.apache.http.nio.NHttpMessageWriter;
+import org.apache.http.nio.NHttpMessageWriterFactory;
 import org.apache.http.nio.reactor.SessionOutputBuffer;
-import org.apache.http.params.HttpParams;
-import org.apache.http.util.CharArrayBuffer;
 
 /**
- * Default {@link NHttpMessageWriter} implementation for {@link HttpResponse}s.
+ * Default factory for response message writers.
  *
- * @since 4.1
+ * @since 4.3
  */
- at NotThreadSafe
-public class DefaultHttpResponseWriter extends AbstractMessageWriter<HttpResponse> {
+ at Immutable
+public class DefaultHttpResponseWriterFactory implements NHttpMessageWriterFactory<HttpResponse> {
+
+    public static final DefaultHttpResponseWriterFactory INSTANCE = new DefaultHttpResponseWriterFactory();
+
+    private final LineFormatter lineFormatter;
+
+    public DefaultHttpResponseWriterFactory(final LineFormatter lineFormatter) {
+        super();
+        this.lineFormatter = lineFormatter != null ? lineFormatter : BasicLineFormatter.INSTANCE;
+    }
 
-    public DefaultHttpResponseWriter(final SessionOutputBuffer buffer,
-                              final LineFormatter formatter,
-                              final HttpParams params) {
-        super(buffer, formatter, params);
+    public DefaultHttpResponseWriterFactory() {
+        this(null);
     }
 
-    @Override
-    protected void writeHeadLine(final HttpResponse message) throws IOException {
-        CharArrayBuffer buffer = lineFormatter.formatStatusLine(
-                this.lineBuf, message.getStatusLine());
-        this.sessionBuffer.writeLine(buffer);
+    public NHttpMessageWriter<HttpResponse> create(final SessionOutputBuffer buffer) {
+        return new DefaultHttpResponseWriter(buffer, lineFormatter);
     }
 
 }
diff --git a/httpcore-nio/src/main/java/org/apache/http/impl/nio/codecs/IdentityDecoder.java b/httpcore-nio/src/main/java/org/apache/http/impl/nio/codecs/IdentityDecoder.java
index 8cce7d6..6a2d578 100644
--- a/httpcore-nio/src/main/java/org/apache/http/impl/nio/codecs/IdentityDecoder.java
+++ b/httpcore-nio/src/main/java/org/apache/http/impl/nio/codecs/IdentityDecoder.java
@@ -36,6 +36,7 @@ import org.apache.http.annotation.NotThreadSafe;
 import org.apache.http.impl.io.HttpTransportMetricsImpl;
 import org.apache.http.nio.FileContentDecoder;
 import org.apache.http.nio.reactor.SessionInputBuffer;
+import org.apache.http.util.Args;
 
 /**
  * Content decoder that reads data without any transformation. The end of the
@@ -67,26 +68,21 @@ public class IdentityDecoder extends AbstractContentDecoder
      * some other means to know all the necessary data has been read and want to
      * reuse the underlying connection for more messages.
      */
-    public void setCompleted(boolean completed) {
+    public void setCompleted(final boolean completed) {
         this.completed = completed;
     }
 
     public int read(final ByteBuffer dst) throws IOException {
-        if (dst == null) {
-            throw new IllegalArgumentException("Byte buffer may not be null");
-        }
+        Args.notNull(dst, "Byte buffer");
         if (this.completed) {
             return -1;
         }
 
-        int bytesRead;
+        final int bytesRead;
         if (this.buffer.hasData()) {
             bytesRead = this.buffer.read(dst);
         } else {
-            bytesRead = this.channel.read(dst);
-            if (bytesRead > 0) {
-                this.metrics.incrementBytesTransferred(bytesRead);
-            }
+            bytesRead = readFromChannel(dst);
         }
         if (bytesRead == -1) {
             this.completed = true;
@@ -96,8 +92,8 @@ public class IdentityDecoder extends AbstractContentDecoder
 
     public long transfer(
             final FileChannel dst,
-            long position,
-            long count) throws IOException {
+            final long position,
+            final long count) throws IOException {
 
         if (dst == null) {
             return 0;
@@ -135,7 +131,7 @@ public class IdentityDecoder extends AbstractContentDecoder
 
     @Override
     public String toString() {
-        StringBuilder buffer = new StringBuilder();
+        final StringBuilder buffer = new StringBuilder();
         buffer.append("[identity; completed: ");
         buffer.append(this.completed);
         buffer.append("]");
diff --git a/httpcore-nio/src/main/java/org/apache/http/impl/nio/codecs/IdentityEncoder.java b/httpcore-nio/src/main/java/org/apache/http/impl/nio/codecs/IdentityEncoder.java
index 73ea1b1..9ffe1c6 100644
--- a/httpcore-nio/src/main/java/org/apache/http/impl/nio/codecs/IdentityEncoder.java
+++ b/httpcore-nio/src/main/java/org/apache/http/impl/nio/codecs/IdentityEncoder.java
@@ -53,11 +53,32 @@ import org.apache.http.nio.reactor.SessionOutputBuffer;
 public class IdentityEncoder extends AbstractContentEncoder
         implements FileContentEncoder {
 
+    private final int fragHint;
+
+    /**
+     * @since 4.3
+     *
+     * @param channel underlying channel.
+     * @param buffer  session buffer.
+     * @param metrics transport metrics.
+     * @param fragementSizeHint fragment size hint defining an minimal size of a fragment
+     *   that should be written out directly to the channel bypassing the session buffer.
+     *   Value <code>0</code> disables fragment buffering.
+     */
     public IdentityEncoder(
             final WritableByteChannel channel,
             final SessionOutputBuffer buffer,
-            final HttpTransportMetricsImpl metrics) {
+            final HttpTransportMetricsImpl metrics,
+            final int fragementSizeHint) {
         super(channel, buffer, metrics);
+        this.fragHint = fragementSizeHint > 0 ? fragementSizeHint : 0;
+    }
+
+    public IdentityEncoder(
+            final WritableByteChannel channel,
+            final SessionOutputBuffer buffer,
+            final HttpTransportMetricsImpl metrics) {
+        this(channel, buffer, metrics, 0);
     }
 
     public int write(final ByteBuffer src) throws IOException {
@@ -65,23 +86,54 @@ public class IdentityEncoder extends AbstractContentEncoder
             return 0;
         }
         assertNotCompleted();
-        int bytesWritten = this.channel.write(src);
-        if (bytesWritten > 0) {
-            this.metrics.incrementBytesTransferred(bytesWritten);
+
+        int total = 0;
+        while (src.hasRemaining()) {
+            if (this.buffer.hasData() || this.fragHint > 0) {
+                if (src.remaining() <= this.fragHint) {
+                    final int capacity = this.fragHint - this.buffer.length();
+                    if (capacity > 0) {
+                        final int limit = Math.min(capacity, src.remaining());
+                        final int bytesWritten = writeToBuffer(src, limit);
+                        total += bytesWritten;
+                    }
+                }
+            }
+            if (this.buffer.hasData()) {
+                if (this.buffer.length() >= this.fragHint || src.hasRemaining()) {
+                    final int bytesWritten = flushToChannel();
+                    if (bytesWritten == 0) {
+                        break;
+                    }
+                }
+            }
+            if (!this.buffer.hasData() && src.remaining() > this.fragHint) {
+                final int bytesWritten = writeToChannel(src);
+                total += bytesWritten;
+                if (bytesWritten == 0) {
+                    break;
+                }
+            }
         }
-        return bytesWritten;
+        return total;
     }
 
     public long transfer(
             final FileChannel src,
-            long position,
-            long count) throws IOException {
+            final long position,
+            final long count) throws IOException {
 
         if (src == null) {
             return 0;
         }
         assertNotCompleted();
-        long bytesWritten = src.transferTo(position, count, this.channel);
+
+        flushToChannel();
+        if (this.buffer.hasData()) {
+            return 0;
+        }
+
+        final long bytesWritten = src.transferTo(position, count, this.channel);
         if (bytesWritten > 0) {
             this.metrics.incrementBytesTransferred(bytesWritten);
         }
@@ -90,9 +142,9 @@ public class IdentityEncoder extends AbstractContentEncoder
 
     @Override
     public String toString() {
-        StringBuilder buffer = new StringBuilder();
+        final StringBuilder buffer = new StringBuilder();
         buffer.append("[identity; completed: ");
-        buffer.append(this.completed);
+        buffer.append(isCompleted());
         buffer.append("]");
         return buffer.toString();
     }
diff --git a/httpcore-nio/src/main/java/org/apache/http/impl/nio/codecs/LengthDelimitedDecoder.java b/httpcore-nio/src/main/java/org/apache/http/impl/nio/codecs/LengthDelimitedDecoder.java
index 53a1baa..c69874d 100644
--- a/httpcore-nio/src/main/java/org/apache/http/impl/nio/codecs/LengthDelimitedDecoder.java
+++ b/httpcore-nio/src/main/java/org/apache/http/impl/nio/codecs/LengthDelimitedDecoder.java
@@ -37,6 +37,7 @@ import org.apache.http.annotation.NotThreadSafe;
 import org.apache.http.impl.io.HttpTransportMetricsImpl;
 import org.apache.http.nio.FileContentDecoder;
 import org.apache.http.nio.reactor.SessionInputBuffer;
+import org.apache.http.util.Args;
 
 /**
  * Content decoder that cuts off after a defined number of bytes. This class
@@ -63,40 +64,25 @@ public class LengthDelimitedDecoder extends AbstractContentDecoder
             final ReadableByteChannel channel,
             final SessionInputBuffer buffer,
             final HttpTransportMetricsImpl metrics,
-            long contentLength) {
+            final long contentLength) {
         super(channel, buffer, metrics);
-        if (contentLength < 0) {
-            throw new IllegalArgumentException("Content length may not be negative");
-        }
+        Args.notNegative(contentLength, "Content length");
         this.contentLength = contentLength;
     }
 
     public int read(final ByteBuffer dst) throws IOException {
-        if (dst == null) {
-            throw new IllegalArgumentException("Byte buffer may not be null");
-        }
+        Args.notNull(dst, "Byte buffer");
         if (this.completed) {
             return -1;
         }
-        int chunk = (int) Math.min((this.contentLength - this.len), Integer.MAX_VALUE);
+        final int chunk = (int) Math.min((this.contentLength - this.len), Integer.MAX_VALUE);
 
-        int bytesRead;
+        final int bytesRead;
         if (this.buffer.hasData()) {
-            int maxLen = Math.min(chunk, this.buffer.length());
+            final int maxLen = Math.min(chunk, this.buffer.length());
             bytesRead = this.buffer.read(dst, maxLen);
         } else {
-            if (dst.remaining() > chunk) {
-                int oldLimit = dst.limit();
-                int newLimit = oldLimit - (dst.remaining() - chunk);
-                dst.limit(newLimit);
-                bytesRead = this.channel.read(dst);
-                dst.limit(oldLimit);
-            } else {
-                bytesRead = this.channel.read(dst);
-            }
-            if (bytesRead > 0) {
-                this.metrics.incrementBytesTransferred(bytesRead);
-            }
+            bytesRead = readFromChannel(dst, chunk);
         }
         if (bytesRead == -1) {
             this.completed = true;
@@ -119,8 +105,8 @@ public class LengthDelimitedDecoder extends AbstractContentDecoder
 
     public long transfer(
             final FileChannel dst,
-            long position,
-            long count) throws IOException {
+            final long position,
+            final long count) throws IOException {
 
         if (dst == null) {
             return 0;
@@ -129,23 +115,20 @@ public class LengthDelimitedDecoder extends AbstractContentDecoder
             return -1;
         }
 
-        int chunk = (int) Math.min((this.contentLength - this.len), Integer.MAX_VALUE);
+        final int chunk = (int) Math.min((this.contentLength - this.len), Integer.MAX_VALUE);
 
-        long bytesRead;
+        final long bytesRead;
         if (this.buffer.hasData()) {
-            int maxLen = Math.min(chunk, this.buffer.length());
+            final int maxLen = Math.min(chunk, this.buffer.length());
             dst.position(position);
             bytesRead = this.buffer.read(dst, maxLen);
         } else {
-            if (count > chunk) {
-                count = chunk;
-            }
             if (this.channel.isOpen()) {
                 if (position > dst.size()) {
                     throw new IOException("Position past end of file [" + position +
                             " > " + dst.size() + "]");
                 }
-                bytesRead = dst.transferFrom(this.channel, position, count);
+                bytesRead = dst.transferFrom(this.channel, position, count < chunk ? count : chunk);
             } else {
                 bytesRead = -1;
             }
@@ -170,7 +153,7 @@ public class LengthDelimitedDecoder extends AbstractContentDecoder
 
     @Override
     public String toString() {
-        StringBuilder buffer = new StringBuilder();
+        final StringBuilder buffer = new StringBuilder();
         buffer.append("[content length: ");
         buffer.append(this.contentLength);
         buffer.append("; pos: ");
diff --git a/httpcore-nio/src/main/java/org/apache/http/impl/nio/codecs/LengthDelimitedEncoder.java b/httpcore-nio/src/main/java/org/apache/http/impl/nio/codecs/LengthDelimitedEncoder.java
index b8184c8..1955258 100644
--- a/httpcore-nio/src/main/java/org/apache/http/impl/nio/codecs/LengthDelimitedEncoder.java
+++ b/httpcore-nio/src/main/java/org/apache/http/impl/nio/codecs/LengthDelimitedEncoder.java
@@ -36,6 +36,7 @@ import org.apache.http.annotation.NotThreadSafe;
 import org.apache.http.impl.io.HttpTransportMetricsImpl;
 import org.apache.http.nio.FileContentEncoder;
 import org.apache.http.nio.reactor.SessionOutputBuffer;
+import org.apache.http.util.Args;
 
 /**
  * Content encoder that cuts off after a defined number of bytes. This class
@@ -55,20 +56,44 @@ public class LengthDelimitedEncoder extends AbstractContentEncoder
         implements FileContentEncoder {
 
     private final long contentLength;
+    private final int fragHint;
 
-    private long len;
+    private long remaining;
 
+    /**
+     * @since 4.3
+     *
+     * @param channel underlying channel.
+     * @param buffer  session buffer.
+     * @param metrics transport metrics.
+     * @param contentLength content length.
+     * @param fragementSizeHint fragment size hint defining an minimal size of a fragment
+     *   that should be written out directly to the channel bypassing the session buffer.
+     *   Value <code>0</code> disables fragment buffering.
+     */
     public LengthDelimitedEncoder(
             final WritableByteChannel channel,
             final SessionOutputBuffer buffer,
             final HttpTransportMetricsImpl metrics,
-            long contentLength) {
+            final long contentLength,
+            final int fragementSizeHint) {
         super(channel, buffer, metrics);
-        if (contentLength < 0) {
-            throw new IllegalArgumentException("Content length may not be negative");
-        }
+        Args.notNegative(contentLength, "Content length");
         this.contentLength = contentLength;
-        this.len = 0;
+        this.fragHint = fragementSizeHint > 0 ? fragementSizeHint : 0;
+        this.remaining = contentLength;
+    }
+
+    public LengthDelimitedEncoder(
+            final WritableByteChannel channel,
+            final SessionOutputBuffer buffer,
+            final HttpTransportMetricsImpl metrics,
+            final long contentLength) {
+        this(channel, buffer, metrics, contentLength, 0);
+    }
+
+    private int nextChunk(final ByteBuffer src) {
+        return (int) Math.min(Math.min(this.remaining, Integer.MAX_VALUE), src.remaining());
     }
 
     public int write(final ByteBuffer src) throws IOException {
@@ -76,58 +101,84 @@ public class LengthDelimitedEncoder extends AbstractContentEncoder
             return 0;
         }
         assertNotCompleted();
-        int chunk = (int) Math.min((this.contentLength - this.len), Integer.MAX_VALUE);
-
-        int bytesWritten;
-        if (src.remaining() > chunk) {
-            int oldLimit = src.limit();
-            int newLimit = oldLimit - (src.remaining() - chunk);
-            src.limit(newLimit);
-            bytesWritten = this.channel.write(src);
-            src.limit(oldLimit);
-        } else {
-            bytesWritten = this.channel.write(src);
-        }
-        if (bytesWritten > 0) {
-            this.metrics.incrementBytesTransferred(bytesWritten);
+
+        int total = 0;
+        while (src.hasRemaining() && this.remaining > 0) {
+            if (this.buffer.hasData() || this.fragHint > 0) {
+                final int chunk = nextChunk(src);
+                if (chunk <= this.fragHint) {
+                    final int capacity = this.fragHint - this.buffer.length();
+                    if (capacity > 0) {
+                        final int limit = Math.min(capacity, chunk);
+                        final int bytesWritten = writeToBuffer(src, limit);
+                        this.remaining -= bytesWritten;
+                        total += bytesWritten;
+                    }
+                }
+            }
+            if (this.buffer.hasData()) {
+                final int chunk = nextChunk(src);
+                if (this.buffer.length() >= this.fragHint || chunk > 0) {
+                    final int bytesWritten = flushToChannel();
+                    if (bytesWritten == 0) {
+                        break;
+                    }
+                }
+            }
+            if (!this.buffer.hasData()) {
+                final int chunk = nextChunk(src);
+                if (chunk > this.fragHint) {
+                    final int bytesWritten = writeToChannel(src, chunk);
+                    this.remaining -= bytesWritten;
+                    total += bytesWritten;
+                    if (bytesWritten == 0) {
+                        break;
+                    }
+                }
+            }
         }
-        this.len += bytesWritten;
-        if (this.len >= this.contentLength) {
-            this.completed = true;
+        if (this.remaining <= 0) {
+            super.complete();
         }
-        return bytesWritten;
+        return total;
     }
 
     public long transfer(
             final FileChannel src,
-            long position,
-            long count) throws IOException {
+            final long position,
+            final long count) throws IOException {
 
         if (src == null) {
             return 0;
         }
         assertNotCompleted();
-        long chunk = Math.min((this.contentLength - this.len), count);
-        long bytesWritten = src.transferTo(position, chunk, this.channel);
+
+        flushToChannel();
+        if (this.buffer.hasData()) {
+            return 0;
+        }
+
+        final long chunk = Math.min(this.remaining, count);
+        final long bytesWritten = src.transferTo(position, chunk, this.channel);
         if (bytesWritten > 0) {
             this.metrics.incrementBytesTransferred(bytesWritten);
         }
-        this.len += bytesWritten;
-        if (this.len >= this.contentLength) {
-            this.completed = true;
+        this.remaining -= bytesWritten;
+        if (this.remaining <= 0) {
+            super.complete();
         }
         return bytesWritten;
     }
 
     @Override
     public String toString() {
-        StringBuilder buffer = new StringBuilder();
+        final StringBuilder buffer = new StringBuilder();
         buffer.append("[content length: ");
         buffer.append(this.contentLength);
         buffer.append("; pos: ");
-        buffer.append(this.len);
+        buffer.append(this.contentLength - this.remaining);
         buffer.append("; completed: ");
-        buffer.append(this.completed);
+        buffer.append(isCompleted());
         buffer.append("]");
         return buffer.toString();
     }
diff --git a/httpcore-nio/src/main/java/org/apache/http/impl/nio/pool/BasicNIOConnFactory.java b/httpcore-nio/src/main/java/org/apache/http/impl/nio/pool/BasicNIOConnFactory.java
index d04b099..d78fbc7 100644
--- a/httpcore-nio/src/main/java/org/apache/http/impl/nio/pool/BasicNIOConnFactory.java
+++ b/httpcore-nio/src/main/java/org/apache/http/impl/nio/pool/BasicNIOConnFactory.java
@@ -31,13 +31,18 @@ import java.io.IOException;
 import javax.net.ssl.SSLContext;
 
 import org.apache.http.HttpHost;
+import org.apache.http.HttpRequest;
+import org.apache.http.HttpResponse;
 import org.apache.http.HttpResponseFactory;
 import org.apache.http.annotation.Immutable;
+import org.apache.http.config.ConnectionConfig;
 import org.apache.http.impl.DefaultHttpResponseFactory;
 import org.apache.http.impl.nio.DefaultNHttpClientConnectionFactory;
 import org.apache.http.impl.nio.SSLNHttpClientConnectionFactory;
 import org.apache.http.nio.NHttpClientConnection;
 import org.apache.http.nio.NHttpConnectionFactory;
+import org.apache.http.nio.NHttpMessageParserFactory;
+import org.apache.http.nio.NHttpMessageWriterFactory;
 import org.apache.http.nio.pool.NIOConnFactory;
 import org.apache.http.nio.reactor.IOEventDispatch;
 import org.apache.http.nio.reactor.IOSession;
@@ -45,22 +50,15 @@ import org.apache.http.nio.reactor.ssl.SSLSetupHandler;
 import org.apache.http.nio.util.ByteBufferAllocator;
 import org.apache.http.nio.util.HeapByteBufferAllocator;
 import org.apache.http.params.HttpParams;
+import org.apache.http.util.Args;
 
 /**
  * A basic {@link NIOConnFactory} implementation that creates
  * {@link NHttpClientConnection} instances given a {@link HttpHost} instance.
- * <p>
- * The following parameters can be used to customize the behavior of this
- * class:
- * <ul>
- *  <li>{@link org.apache.http.params.CoreProtocolPNames#HTTP_ELEMENT_CHARSET}</li>
- *  <li>{@link org.apache.http.params.CoreConnectionPNames#SOCKET_BUFFER_SIZE}</li>
- *  <li>{@link org.apache.http.params.CoreConnectionPNames#MAX_HEADER_COUNT}</li>
- *  <li>{@link org.apache.http.params.CoreConnectionPNames#MAX_LINE_LENGTH}</li>
- * </ul>
  *
  * @since 4.2
  */
+ at SuppressWarnings("deprecation")
 @Immutable
 public class BasicNIOConnFactory implements NIOConnFactory<HttpHost, NHttpClientConnection> {
 
@@ -71,9 +69,7 @@ public class BasicNIOConnFactory implements NIOConnFactory<HttpHost, NHttpClient
             final NHttpConnectionFactory<? extends NHttpClientConnection> plainFactory,
             final NHttpConnectionFactory<? extends NHttpClientConnection> sslFactory) {
         super();
-        if (plainFactory == null) {
-            throw new IllegalArgumentException("Plain HTTP client connection factory may not be null");
-        }
+        Args.notNull(plainFactory, "Plain HTTP client connection factory");
         this.plainFactory = plainFactory;
         this.sslFactory = sslFactory;
     }
@@ -83,6 +79,12 @@ public class BasicNIOConnFactory implements NIOConnFactory<HttpHost, NHttpClient
         this(plainFactory, null);
     }
 
+    /**
+     * @deprecated (4.3) use {@link BasicNIOConnFactory#BasicNIOConnFactory(SSLContext,
+     *   SSLSetupHandler, NHttpMessageParserFactory, NHttpMessageWriterFactory,
+     *   ByteBufferAllocator, ConnectionConfig)}
+     */
+    @Deprecated
     public BasicNIOConnFactory(
             final SSLContext sslcontext,
             final SSLSetupHandler sslHandler,
@@ -95,20 +97,63 @@ public class BasicNIOConnFactory implements NIOConnFactory<HttpHost, NHttpClient
                         sslcontext, sslHandler, responseFactory, allocator, params));
     }
 
+    /**
+     * @deprecated (4.3) use {@link BasicNIOConnFactory#BasicNIOConnFactory(SSLContext,
+     *   SSLSetupHandler, ConnectionConfig)}
+     */
+    @Deprecated
     public BasicNIOConnFactory(
             final SSLContext sslcontext,
             final SSLSetupHandler sslHandler,
             final HttpParams params) {
         this(sslcontext, sslHandler,
-                new DefaultHttpResponseFactory(), new HeapByteBufferAllocator(), params);
+                DefaultHttpResponseFactory.INSTANCE, HeapByteBufferAllocator.INSTANCE, params);
     }
 
+    /**
+     * @deprecated (4.3) use {@link BasicNIOConnFactory#BasicNIOConnFactory(ConnectionConfig)}
+     */
+    @Deprecated
     public BasicNIOConnFactory(final HttpParams params) {
         this(null, null, params);
     }
 
+    /**
+     * @since 4.3
+     */
+    public BasicNIOConnFactory(
+            final SSLContext sslcontext,
+            final SSLSetupHandler sslHandler,
+            final NHttpMessageParserFactory<HttpResponse> responseParserFactory,
+            final NHttpMessageWriterFactory<HttpRequest> requestWriterFactory,
+            final ByteBufferAllocator allocator,
+            final ConnectionConfig config) {
+        this(new DefaultNHttpClientConnectionFactory(
+                    responseParserFactory, requestWriterFactory, allocator, config),
+                new SSLNHttpClientConnectionFactory(
+                        sslcontext, sslHandler, responseParserFactory, requestWriterFactory,
+                        allocator, config));
+    }
+
+    /**
+     * @since 4.3
+     */
+    public BasicNIOConnFactory(
+            final SSLContext sslcontext,
+            final SSLSetupHandler sslHandler,
+            final ConnectionConfig config) {
+        this(sslcontext, sslHandler, null, null, null, config);
+    }
+
+    /**
+     * @since 4.3
+     */
+    public BasicNIOConnFactory(final ConnectionConfig config) {
+        this(new DefaultNHttpClientConnectionFactory(config), null);
+    }
+
     public NHttpClientConnection create(final HttpHost route, final IOSession session) throws IOException {
-        NHttpClientConnection conn;
+        final NHttpClientConnection conn;
         if (route.getSchemeName().equalsIgnoreCase("https")) {
             if (this.sslFactory == null) {
                 throw new IOException("SSL not supported");
diff --git a/httpcore-nio/src/main/java/org/apache/http/impl/nio/pool/BasicNIOConnPool.java b/httpcore-nio/src/main/java/org/apache/http/impl/nio/pool/BasicNIOConnPool.java
index 7ca1371..1cf4eea 100644
--- a/httpcore-nio/src/main/java/org/apache/http/impl/nio/pool/BasicNIOConnPool.java
+++ b/httpcore-nio/src/main/java/org/apache/http/impl/nio/pool/BasicNIOConnPool.java
@@ -35,63 +35,128 @@ import java.util.concurrent.atomic.AtomicLong;
 import org.apache.http.HttpHost;
 import org.apache.http.annotation.ThreadSafe;
 import org.apache.http.concurrent.FutureCallback;
+import org.apache.http.config.ConnectionConfig;
 import org.apache.http.nio.NHttpClientConnection;
 import org.apache.http.nio.pool.AbstractNIOConnPool;
 import org.apache.http.nio.pool.NIOConnFactory;
+import org.apache.http.nio.pool.SocketAddressResolver;
 import org.apache.http.nio.reactor.ConnectingIOReactor;
-import org.apache.http.params.HttpConnectionParams;
+import org.apache.http.params.CoreConnectionPNames;
 import org.apache.http.params.HttpParams;
-import org.apache.http.pool.ConnPool;
+import org.apache.http.util.Args;
 
 /**
- * A very basic {@link ConnPool} implementation that represents a pool
- * of non-blocking {@link NHttpClientConnection} connections identified by
- * an {@link HttpHost} instance. Please note this pool implementation
- * does not support complex routes via a proxy cannot differentiate between
- * direct and proxied connections.
- * <p>
- * The following parameters can be used to customize the behavior of this
- * class:
- * <ul>
- *  <li>{@link org.apache.http.params.CoreProtocolPNames#HTTP_ELEMENT_CHARSET}</li>
- *  <li>{@link org.apache.http.params.CoreConnectionPNames#SO_TIMEOUT}</li>
- *  <li>{@link org.apache.http.params.CoreConnectionPNames#CONNECTION_TIMEOUT}</li>
- *  <li>{@link org.apache.http.params.CoreConnectionPNames#SOCKET_BUFFER_SIZE}</li>
- *  <li>{@link org.apache.http.params.CoreConnectionPNames#MAX_HEADER_COUNT}</li>
- *  <li>{@link org.apache.http.params.CoreConnectionPNames#MAX_LINE_LENGTH}</li>
- * </ul>
+ * A very basic {@link org.apache.http.pool.ConnPool} implementation that
+ * represents a pool of non-blocking {@link NHttpClientConnection} connections
+ * identified by an {@link HttpHost} instance. Please note this pool
+ * implementation does not support complex routes via a proxy cannot
+ * differentiate between direct and proxied connections.
  *
  * @see HttpHost
  * @since 4.2
  */
+ at SuppressWarnings("deprecation")
 @ThreadSafe
 public class BasicNIOConnPool extends AbstractNIOConnPool<HttpHost, NHttpClientConnection, BasicNIOPoolEntry> {
 
-    private static AtomicLong COUNTER = new AtomicLong();
+    private static final AtomicLong COUNTER = new AtomicLong();
 
-    private final HttpParams params;
+    private final int connectTimeout;
 
+    static class BasicAddressResolver implements SocketAddressResolver<HttpHost> {
+
+        public SocketAddress resolveLocalAddress(final HttpHost host) {
+            return null;
+        }
+
+        public SocketAddress resolveRemoteAddress(final HttpHost host) {
+            final String hostname = host.getHostName();
+            int port = host.getPort();
+            if (port == -1) {
+                if (host.getSchemeName().equalsIgnoreCase("http")) {
+                    port = 80;
+                } else if (host.getSchemeName().equalsIgnoreCase("https")) {
+                    port = 443;
+                }
+            }
+            return new InetSocketAddress(hostname, port);
+        }
+
+    }
+
+    /**
+     * @deprecated (4.3) use {@link BasicNIOConnPool#BasicNIOConnPool(ConnectingIOReactor, NIOConnFactory, int)}
+     */
+    @Deprecated
     public BasicNIOConnPool(
             final ConnectingIOReactor ioreactor,
             final NIOConnFactory<HttpHost, NHttpClientConnection> connFactory,
             final HttpParams params) {
         super(ioreactor, connFactory, 2, 20);
-        if (params == null) {
-            throw new IllegalArgumentException("HTTP parameters may not be null");
-        }
-        this.params = params;
+        Args.notNull(params, "HTTP parameters");
+        this.connectTimeout = params.getIntParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 0);
     }
 
+    /**
+     * @deprecated (4.3) use {@link BasicNIOConnPool#BasicNIOConnPool(ConnectingIOReactor,
+     *   ConnectionConfig)}
+     */
+    @Deprecated
     public BasicNIOConnPool(
             final ConnectingIOReactor ioreactor, final HttpParams params) {
         this(ioreactor, new BasicNIOConnFactory(params), params);
     }
 
+    /**
+     * @since 4.3
+     */
+    public BasicNIOConnPool(
+            final ConnectingIOReactor ioreactor,
+            final NIOConnFactory<HttpHost, NHttpClientConnection> connFactory,
+            final int connectTimeout) {
+        super(ioreactor, connFactory, new BasicAddressResolver(), 2, 20);
+        this.connectTimeout = connectTimeout;
+    }
+
+    /**
+     * @since 4.3
+     */
+    public BasicNIOConnPool(
+            final ConnectingIOReactor ioreactor,
+            final int connectTimeout,
+            final ConnectionConfig config) {
+        this(ioreactor, new BasicNIOConnFactory(config), connectTimeout);
+    }
+
+    /**
+     * @since 4.3
+     */
+    public BasicNIOConnPool(
+            final ConnectingIOReactor ioreactor,
+            final ConnectionConfig config) {
+        this(ioreactor, new BasicNIOConnFactory(config), 0);
+    }
+
+    /**
+     * @since 4.3
+     */
+    public BasicNIOConnPool(final ConnectingIOReactor ioreactor) {
+        this(ioreactor, new BasicNIOConnFactory(ConnectionConfig.DEFAULT), 0);
+    }
+
+    /**
+     * @deprecated (4.3) use {@link SocketAddressResolver}
+     */
+    @Deprecated
     @Override
     protected SocketAddress resolveRemoteAddress(final HttpHost host) {
         return new InetSocketAddress(host.getHostName(), host.getPort());
     }
 
+    /**
+     * @deprecated (4.3) use {@link SocketAddressResolver}
+     */
+    @Deprecated
     @Override
     protected SocketAddress resolveLocalAddress(final HttpHost host) {
         return null;
@@ -99,7 +164,10 @@ public class BasicNIOConnPool extends AbstractNIOConnPool<HttpHost, NHttpClientC
 
     @Override
     protected BasicNIOPoolEntry createEntry(final HttpHost host, final NHttpClientConnection conn) {
-        return new BasicNIOPoolEntry(Long.toString(COUNTER.getAndIncrement()), host, conn);
+        final BasicNIOPoolEntry entry = new BasicNIOPoolEntry(
+                Long.toString(COUNTER.getAndIncrement()), host, conn);
+        entry.setSocketTimeout(conn.getSocketTimeout());
+        return entry;
     }
 
     @Override
@@ -107,16 +175,29 @@ public class BasicNIOConnPool extends AbstractNIOConnPool<HttpHost, NHttpClientC
             final HttpHost route,
             final Object state,
             final FutureCallback<BasicNIOPoolEntry> callback) {
-        int connectTimeout = HttpConnectionParams.getConnectionTimeout(this.params);
-        return super.lease(route, state, connectTimeout, TimeUnit.MILLISECONDS, callback);
+        return super.lease(route, state,
+                this.connectTimeout, TimeUnit.MILLISECONDS, callback);
     }
 
     @Override
     public Future<BasicNIOPoolEntry> lease(
             final HttpHost route,
             final Object state) {
-        int connectTimeout = HttpConnectionParams.getConnectionTimeout(this.params);
-        return super.lease(route, state, connectTimeout, TimeUnit.MILLISECONDS, null);
+        return super.lease(route, state,
+                this.connectTimeout, TimeUnit.MILLISECONDS, null);
+    }
+
+    @Override
+    protected void onLease(final BasicNIOPoolEntry entry) {
+        final NHttpClientConnection conn = entry.getConnection();
+        conn.setSocketTimeout(entry.getSocketTimeout());
+    }
+
+    @Override
+    protected void onRelease(final BasicNIOPoolEntry entry) {
+        final NHttpClientConnection conn = entry.getConnection();
+        entry.setSocketTimeout(conn.getSocketTimeout());
+        conn.setSocketTimeout(0);
     }
 
 }
diff --git a/httpcore-nio/src/main/java/org/apache/http/impl/nio/pool/BasicNIOPoolEntry.java b/httpcore-nio/src/main/java/org/apache/http/impl/nio/pool/BasicNIOPoolEntry.java
index b01c0b9..8f9c600 100644
--- a/httpcore-nio/src/main/java/org/apache/http/impl/nio/pool/BasicNIOPoolEntry.java
+++ b/httpcore-nio/src/main/java/org/apache/http/impl/nio/pool/BasicNIOPoolEntry.java
@@ -44,6 +44,8 @@ import org.apache.http.pool.PoolEntry;
 @ThreadSafe
 public class BasicNIOPoolEntry extends PoolEntry<HttpHost, NHttpClientConnection> {
 
+    private volatile int socketTimeout;
+
     public BasicNIOPoolEntry(final String id, final HttpHost route, final NHttpClientConnection conn) {
         super(id, route, conn);
     }
@@ -52,7 +54,7 @@ public class BasicNIOPoolEntry extends PoolEntry<HttpHost, NHttpClientConnection
     public void close() {
         try {
             getConnection().close();
-        } catch (IOException ignore) {
+        } catch (final IOException ignore) {
         }
     }
 
@@ -61,4 +63,12 @@ public class BasicNIOPoolEntry extends PoolEntry<HttpHost, NHttpClientConnection
         return !getConnection().isOpen();
     }
 
+    int getSocketTimeout() {
+        return socketTimeout;
+    }
+
+    void setSocketTimeout(final int socketTimeout) {
+        this.socketTimeout = socketTimeout;
+    }
+
 }
diff --git a/httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/AbstractIODispatch.java b/httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/AbstractIODispatch.java
index d1e4a8d..301c639 100644
--- a/httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/AbstractIODispatch.java
+++ b/httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/AbstractIODispatch.java
@@ -33,6 +33,7 @@ import org.apache.http.annotation.Immutable;
 import org.apache.http.nio.reactor.IOEventDispatch;
 import org.apache.http.nio.reactor.IOSession;
 import org.apache.http.nio.reactor.ssl.SSLIOSession;
+import org.apache.http.util.Asserts;
 
 /**
  * Abstract {@link IOEventDispatch} implementation that supports both plain (non-encrypted)
@@ -59,9 +60,7 @@ public abstract class AbstractIODispatch<T> implements IOEventDispatch {
     protected abstract void onTimeout(T conn);
 
     private void ensureNotNull(final T conn) {
-        if (conn == null) {
-            throw new IllegalStateException("HTTP connection is null");
-        }
+        Asserts.notNull(conn, "HTTP connection");
     }
 
     public void connected(final IOSession session) {
@@ -73,7 +72,7 @@ public abstract class AbstractIODispatch<T> implements IOEventDispatch {
                 session.setAttribute(IOEventDispatch.CONNECTION_KEY, conn);
             }
             onConnected(conn);
-            SSLIOSession ssliosession = (SSLIOSession) session.getAttribute(
+            final SSLIOSession ssliosession = (SSLIOSession) session.getAttribute(
                     SSLIOSession.SESSION_KEY);
             if (ssliosession != null) {
                 try {
@@ -82,12 +81,12 @@ public abstract class AbstractIODispatch<T> implements IOEventDispatch {
                             ssliosession.initialize();
                         }
                     }
-                } catch (IOException ex) {
+                } catch (final IOException ex) {
                     onException(conn, ex);
                     ssliosession.shutdown();
                 }
             }
-        } catch (RuntimeException ex) {
+        } catch (final RuntimeException ex) {
             session.shutdown();
             throw ex;
         }
@@ -95,6 +94,7 @@ public abstract class AbstractIODispatch<T> implements IOEventDispatch {
 
     public void disconnected(final IOSession session) {
         @SuppressWarnings("unchecked")
+        final
         T conn = (T) session.getAttribute(IOEventDispatch.CONNECTION_KEY);
         if (conn != null) {
             onClosed(conn);
@@ -103,10 +103,11 @@ public abstract class AbstractIODispatch<T> implements IOEventDispatch {
 
     public void inputReady(final IOSession session) {
         @SuppressWarnings("unchecked")
+        final
         T conn = (T) session.getAttribute(IOEventDispatch.CONNECTION_KEY);
         try {
             ensureNotNull(conn);
-            SSLIOSession ssliosession = (SSLIOSession) session.getAttribute(
+            final SSLIOSession ssliosession = (SSLIOSession) session.getAttribute(
                     SSLIOSession.SESSION_KEY);
             if (ssliosession == null) {
                 onInputReady(conn);
@@ -119,12 +120,12 @@ public abstract class AbstractIODispatch<T> implements IOEventDispatch {
                         onInputReady(conn);
                     }
                     ssliosession.inboundTransport();
-                } catch (IOException ex) {
+                } catch (final IOException ex) {
                     onException(conn, ex);
                     ssliosession.shutdown();
                 }
             }
-        } catch (RuntimeException ex) {
+        } catch (final RuntimeException ex) {
             session.shutdown();
             throw ex;
         }
@@ -132,10 +133,11 @@ public abstract class AbstractIODispatch<T> implements IOEventDispatch {
 
     public void outputReady(final IOSession session) {
         @SuppressWarnings("unchecked")
+        final
         T conn = (T) session.getAttribute(IOEventDispatch.CONNECTION_KEY);
         try {
             ensureNotNull(conn);
-            SSLIOSession ssliosession = (SSLIOSession) session.getAttribute(
+            final SSLIOSession ssliosession = (SSLIOSession) session.getAttribute(
                     SSLIOSession.SESSION_KEY);
             if (ssliosession == null) {
                 onOutputReady(conn);
@@ -148,12 +150,12 @@ public abstract class AbstractIODispatch<T> implements IOEventDispatch {
                         onOutputReady(conn);
                     }
                     ssliosession.outboundTransport();
-                } catch (IOException ex) {
+                } catch (final IOException ex) {
                     onException(conn, ex);
                     ssliosession.shutdown();
                 }
             }
-        } catch (RuntimeException ex) {
+        } catch (final RuntimeException ex) {
             session.shutdown();
             throw ex;
         }
@@ -161,9 +163,10 @@ public abstract class AbstractIODispatch<T> implements IOEventDispatch {
 
     public void timeout(final IOSession session) {
         @SuppressWarnings("unchecked")
+        final
         T conn = (T) session.getAttribute(IOEventDispatch.CONNECTION_KEY);
         try {
-            SSLIOSession ssliosession = (SSLIOSession) session.getAttribute(
+            final SSLIOSession ssliosession = (SSLIOSession) session.getAttribute(
                     SSLIOSession.SESSION_KEY);
             ensureNotNull(conn);
             onTimeout(conn);
@@ -175,7 +178,7 @@ public abstract class AbstractIODispatch<T> implements IOEventDispatch {
                     }
                 }
             }
-        } catch (RuntimeException ex) {
+        } catch (final RuntimeException ex) {
             session.shutdown();
             throw ex;
         }
diff --git a/httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/AbstractIOReactor.java b/httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/AbstractIOReactor.java
index b3e7f95..c80a457 100644
--- a/httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/AbstractIOReactor.java
+++ b/httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/AbstractIOReactor.java
@@ -37,7 +37,6 @@ import java.nio.channels.Selector;
 import java.nio.channels.SocketChannel;
 import java.util.Collections;
 import java.util.HashSet;
-import java.util.Iterator;
 import java.util.Queue;
 import java.util.Set;
 import java.util.concurrent.ConcurrentLinkedQueue;
@@ -47,6 +46,8 @@ import org.apache.http.nio.reactor.IOReactor;
 import org.apache.http.nio.reactor.IOReactorException;
 import org.apache.http.nio.reactor.IOReactorStatus;
 import org.apache.http.nio.reactor.IOSession;
+import org.apache.http.util.Args;
+import org.apache.http.util.Asserts;
 
 /**
  * Generic implementation of {@link IOReactor} that can used as a subclass
@@ -75,7 +76,7 @@ public abstract class AbstractIOReactor implements IOReactor {
      * @param selectTimeout the select timeout.
      * @throws IOReactorException in case if a non-recoverable I/O error.
      */
-    public AbstractIOReactor(long selectTimeout) throws IOReactorException {
+    public AbstractIOReactor(final long selectTimeout) throws IOReactorException {
         this(selectTimeout, false);
     }
 
@@ -89,11 +90,9 @@ public abstract class AbstractIOReactor implements IOReactor {
      *
      * @since 4.1
      */
-    public AbstractIOReactor(long selectTimeout, boolean interestOpsQueueing) throws IOReactorException {
+    public AbstractIOReactor(final long selectTimeout, final boolean interestOpsQueueing) throws IOReactorException {
         super();
-        if (selectTimeout <= 0) {
-            throw new IllegalArgumentException("Select timeout may not be negative or zero");
-        }
+        Args.positive(selectTimeout, "Select timeout");
         this.selectTimeout = selectTimeout;
         this.interestOpsQueueing = interestOpsQueueing;
         this.sessions = Collections.synchronizedSet(new HashSet<IOSession>());
@@ -102,7 +101,7 @@ public abstract class AbstractIOReactor implements IOReactor {
         this.newChannels = new ConcurrentLinkedQueue<ChannelEntry>();
         try {
             this.selector = Selector.open();
-        } catch (IOException ex) {
+        } catch (final IOException ex) {
             throw new IOReactorException("Failure opening selector", ex);
         }
         this.statusMutex = new Object();
@@ -219,9 +218,7 @@ public abstract class AbstractIOReactor implements IOReactor {
      * @param channelEntry the channel entry.
      */
     public void addChannel(final ChannelEntry channelEntry) {
-        if (channelEntry == null) {
-            throw new IllegalArgumentException("Channel entry may not be null");
-        }
+        Args.notNull(channelEntry, "Channel entry");
         this.newChannels.add(channelEntry);
         this.selector.wakeup();
     }
@@ -254,12 +251,12 @@ public abstract class AbstractIOReactor implements IOReactor {
         try {
             for (;;) {
 
-                int readyCount;
+                final int readyCount;
                 try {
                     readyCount = this.selector.select(this.selectTimeout);
-                } catch (InterruptedIOException ex) {
+                } catch (final InterruptedIOException ex) {
                     throw ex;
-                } catch (IOException ex) {
+                } catch (final IOException ex) {
                     throw new IOReactorException("Unexpected selector failure", ex);
                 }
 
@@ -304,7 +301,7 @@ public abstract class AbstractIOReactor implements IOReactor {
 
             }
 
-        } catch (ClosedSelectorException ex) {
+        } catch (final ClosedSelectorException ignore) {
         } finally {
             hardShutdown();
             synchronized (this.statusMutex) {
@@ -314,9 +311,8 @@ public abstract class AbstractIOReactor implements IOReactor {
     }
 
     private void processEvents(final Set<SelectionKey> selectedKeys) {
-        for (Iterator<SelectionKey> it = selectedKeys.iterator(); it.hasNext(); ) {
+        for (final SelectionKey key : selectedKeys) {
 
-            SelectionKey key = it.next();
             processEvent(key);
 
         }
@@ -329,7 +325,7 @@ public abstract class AbstractIOReactor implements IOReactor {
      * @param key the selection key that triggered an event.
      */
     protected void processEvent(final SelectionKey key) {
-        IOSessionImpl session = (IOSessionImpl) key.attachment();
+        final IOSessionImpl session = (IOSessionImpl) key.attachment();
         try {
             if (key.isAcceptable()) {
                 acceptable(key);
@@ -345,7 +341,7 @@ public abstract class AbstractIOReactor implements IOReactor {
                 session.resetLastWrite();
                 writable(key);
             }
-        } catch (CancelledKeyException ex) {
+        } catch (final CancelledKeyException ex) {
             queueClosedSession(session);
             key.attach(null);
         }
@@ -366,27 +362,27 @@ public abstract class AbstractIOReactor implements IOReactor {
         ChannelEntry entry;
         while ((entry = this.newChannels.poll()) != null) {
 
-            SocketChannel channel;
-            SelectionKey key;
+            final SocketChannel channel;
+            final SelectionKey key;
             try {
                 channel = entry.getChannel();
                 channel.configureBlocking(false);
                 key = channel.register(this.selector, SelectionKey.OP_READ);
-            } catch (ClosedChannelException ex) {
-                SessionRequestImpl sessionRequest = entry.getSessionRequest();
+            } catch (final ClosedChannelException ex) {
+                final SessionRequestImpl sessionRequest = entry.getSessionRequest();
                 if (sessionRequest != null) {
                     sessionRequest.failed(ex);
                 }
                 return;
 
-            } catch (IOException ex) {
+            } catch (final IOException ex) {
                 throw new IOReactorException("Failure registering channel " +
                         "with the selector", ex);
             }
 
-            SessionClosedCallback sessionClosedCallback = new SessionClosedCallback() {
+            final SessionClosedCallback sessionClosedCallback = new SessionClosedCallback() {
 
-                public void sessionClosed(IOSession session) {
+                public void sessionClosed(final IOSession session) {
                     queueClosedSession(session);
                 }
 
@@ -403,29 +399,32 @@ public abstract class AbstractIOReactor implements IOReactor {
                 };
             }
 
-            IOSession session = new IOSessionImpl(key, interestOpsCallback, sessionClosedCallback);
-
-            int timeout = 0;
+            final IOSession session;
             try {
-                timeout = channel.socket().getSoTimeout();
-            } catch (IOException ex) {
-                // Very unlikely to happen and is not fatal
-                // as the protocol layer is expected to overwrite
-                // this value anyways
-            }
-
-            session.setAttribute(IOSession.ATTACHMENT_KEY, entry.getAttachment());
-            session.setSocketTimeout(timeout);
-            this.sessions.add(session);
+                session = new IOSessionImpl(key, interestOpsCallback, sessionClosedCallback);
+                int timeout = 0;
+                try {
+                    timeout = channel.socket().getSoTimeout();
+                } catch (final IOException ex) {
+                    // Very unlikely to happen and is not fatal
+                    // as the protocol layer is expected to overwrite
+                    // this value anyways
+                }
 
+                session.setAttribute(IOSession.ATTACHMENT_KEY, entry.getAttachment());
+                session.setSocketTimeout(timeout);
+            } catch (final CancelledKeyException ex) {
+                continue;
+            }
             try {
-                SessionRequestImpl sessionRequest = entry.getSessionRequest();
+                this.sessions.add(session);
+                final SessionRequestImpl sessionRequest = entry.getSessionRequest();
                 if (sessionRequest != null) {
                     sessionRequest.completed(session);
                 }
                 key.attach(session);
                 sessionCreated(key, session);
-            } catch (CancelledKeyException ex) {
+            } catch (final CancelledKeyException ex) {
                 queueClosedSession(session);
                 key.attach(null);
             }
@@ -438,7 +437,7 @@ public abstract class AbstractIOReactor implements IOReactor {
             if (this.sessions.remove(session)) {
                 try {
                     sessionClosed(session);
-                } catch (CancelledKeyException ex) {
+                } catch (final CancelledKeyException ex) {
                     // ignore and move on
                 }
             }
@@ -453,8 +452,8 @@ public abstract class AbstractIOReactor implements IOReactor {
         InterestOpEntry entry;
         while ((entry = this.interestOpsQueue.poll()) != null) {
             // obtain the operation's details
-            SelectionKey key = entry.getSelectionKey();
-            int eventMask = entry.getEventMask();
+            final SelectionKey key = entry.getSelectionKey();
+            final int eventMask = entry.getEventMask();
             if (key.isValid()) {
                 key.interestOps(eventMask);
             }
@@ -463,9 +462,7 @@ public abstract class AbstractIOReactor implements IOReactor {
 
     private boolean queueInterestOps(final InterestOpEntry entry) {
         // validity checks
-        if (!this.interestOpsQueueing) {
-            throw new IllegalStateException("Interest ops queueing not enabled");
-        }
+        Asserts.check(this.interestOpsQueueing, "Interest ops queueing not enabled");
         if (entry == null) {
             return false;
         }
@@ -485,10 +482,10 @@ public abstract class AbstractIOReactor implements IOReactor {
      * @param key the selection key.
      * @param now current time as long value.
      */
-    protected void timeoutCheck(final SelectionKey key, long now) {
-        IOSessionImpl session = (IOSessionImpl) key.attachment();
+    protected void timeoutCheck(final SelectionKey key, final long now) {
+        final IOSessionImpl session = (IOSessionImpl) key.attachment();
         if (session != null) {
-            int timeout = session.getSocketTimeout();
+            final int timeout = session.getSocketTimeout();
             if (timeout > 0) {
                 if (session.getLastAccessTime() + timeout < now) {
                     sessionTimedOut(session);
@@ -502,8 +499,7 @@ public abstract class AbstractIOReactor implements IOReactor {
      */
     protected void closeSessions() {
         synchronized (this.sessions) {
-            for (Iterator<IOSession> it = this.sessions.iterator(); it.hasNext(); ) {
-                IOSession session = it.next();
+            for (final IOSession session : this.sessions) {
                 session.close();
             }
         }
@@ -517,14 +513,14 @@ public abstract class AbstractIOReactor implements IOReactor {
     protected void closeNewChannels() throws IOReactorException {
         ChannelEntry entry;
         while ((entry = this.newChannels.poll()) != null) {
-            SessionRequestImpl sessionRequest = entry.getSessionRequest();
+            final SessionRequestImpl sessionRequest = entry.getSessionRequest();
             if (sessionRequest != null) {
                 sessionRequest.cancel();
             }
-            SocketChannel channel = entry.getChannel();
+            final SocketChannel channel = entry.getChannel();
             try {
                 channel.close();
-            } catch (IOException ignore) {
+            } catch (final IOException ignore) {
             }
         }
     }
@@ -536,16 +532,15 @@ public abstract class AbstractIOReactor implements IOReactor {
      */
     protected void closeActiveChannels() throws IOReactorException {
         try {
-            Set<SelectionKey> keys = this.selector.keys();
-            for (Iterator<SelectionKey> it = keys.iterator(); it.hasNext(); ) {
-                SelectionKey key = it.next();
-                IOSession session = getSession(key);
+            final Set<SelectionKey> keys = this.selector.keys();
+            for (final SelectionKey key : keys) {
+                final IOSession session = getSession(key);
                 if (session != null) {
                     session.close();
                 }
             }
             this.selector.close();
-        } catch (IOException ignore) {
+        } catch (final IOException ignore) {
         }
     }
 
@@ -587,9 +582,9 @@ public abstract class AbstractIOReactor implements IOReactor {
      * @param timeout the maximum wait time.
      * @throws InterruptedException if interrupted.
      */
-    public void awaitShutdown(long timeout) throws InterruptedException {
+    public void awaitShutdown(final long timeout) throws InterruptedException {
         synchronized (this.statusMutex) {
-            long deadline = System.currentTimeMillis() + timeout;
+            final long deadline = System.currentTimeMillis() + timeout;
             long remaining = timeout;
             while (this.status != IOReactorStatus.SHUT_DOWN) {
                 this.statusMutex.wait(remaining);
@@ -603,12 +598,12 @@ public abstract class AbstractIOReactor implements IOReactor {
         }
     }
 
-    public void shutdown(long gracePeriod) throws IOReactorException {
+    public void shutdown(final long gracePeriod) throws IOReactorException {
         if (this.status != IOReactorStatus.INACTIVE) {
             gracefulShutdown();
             try {
                 awaitShutdown(gracePeriod);
-            } catch (InterruptedException ignore) {
+            } catch (final InterruptedException ignore) {
             }
         }
         if (this.status != IOReactorStatus.SHUT_DOWN) {
diff --git a/httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/AbstractMultiworkerIOReactor.java b/httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/AbstractMultiworkerIOReactor.java
index 62519c0..b6e4dc7 100644
--- a/httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/AbstractMultiworkerIOReactor.java
+++ b/httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/AbstractMultiworkerIOReactor.java
@@ -38,21 +38,21 @@ import java.nio.channels.SelectionKey;
 import java.nio.channels.Selector;
 import java.util.ArrayList;
 import java.util.Date;
-import java.util.Iterator;
 import java.util.List;
-import java.util.Set;
 import java.util.concurrent.ThreadFactory;
 
 import org.apache.http.annotation.ThreadSafe;
-import org.apache.http.nio.params.NIOReactorParams;
+import org.apache.http.nio.params.NIOReactorPNames;
 import org.apache.http.nio.reactor.IOEventDispatch;
 import org.apache.http.nio.reactor.IOReactor;
 import org.apache.http.nio.reactor.IOReactorException;
 import org.apache.http.nio.reactor.IOReactorExceptionHandler;
 import org.apache.http.nio.reactor.IOReactorStatus;
 import org.apache.http.params.BasicHttpParams;
-import org.apache.http.params.HttpConnectionParams;
+import org.apache.http.params.CoreConnectionPNames;
 import org.apache.http.params.HttpParams;
+import org.apache.http.util.Args;
+import org.apache.http.util.Asserts;
 
 /**
  * Generic implementation of {@link IOReactor} that can run multiple
@@ -91,17 +91,6 @@ import org.apache.http.params.HttpParams;
  * can obtain the audit log using {@link #getAuditLog()}, examine exceptions
  * thrown by the I/O reactor prior and in the course of the reactor shutdown
  * and decide whether it is safe to restart the I/O reactor.
- * <p>
- * The following parameters can be used to customize the behavior of this
- * class:
- * <ul>
- *  <li>{@link org.apache.http.params.CoreConnectionPNames#TCP_NODELAY}</li>
- *  <li>{@link org.apache.http.params.CoreConnectionPNames#SO_TIMEOUT}</li>
- *  <li>{@link org.apache.http.params.CoreConnectionPNames#SO_LINGER}</li>
- *  <li>{@link org.apache.http.nio.params.NIOReactorPNames#SELECT_INTERVAL}</li>
- *  <li>{@link org.apache.http.nio.params.NIOReactorPNames#GRACE_PERIOD}</li>
- *  <li>{@link org.apache.http.nio.params.NIOReactorPNames#INTEREST_OPS_QUEUEING}</li>
- * </ul>
  *
  * @since 4.0
  */
@@ -147,19 +136,11 @@ public abstract class AbstractMultiworkerIOReactor implements IOReactor {
             final IOReactorConfig config,
             final ThreadFactory threadFactory) throws IOReactorException {
         super();
-        if (config != null) {
-            try {
-                this.config = config.clone();
-            } catch (CloneNotSupportedException ex) {
-                throw new IOReactorException("Unable to clone configuration");
-            }
-        } else {
-            this.config = new IOReactorConfig();
-        }
+        this.config = config != null ? config : IOReactorConfig.DEFAULT;
         this.params = new BasicHttpParams();
         try {
             this.selector = Selector.open();
-        } catch (IOException ex) {
+        } catch (final IOException ex) {
             throw new IOReactorException("Failure opening selector", ex);
         }
         this.selectTimeout = this.config.getSelectInterval();
@@ -188,23 +169,22 @@ public abstract class AbstractMultiworkerIOReactor implements IOReactor {
         this(null, null);
     }
 
-    static IOReactorConfig convert(int workerCount, final HttpParams params) {
-        if (params == null) {
-            throw new IllegalArgumentException("HTTP parameters may not be null");
-        }
-        IOReactorConfig config = new IOReactorConfig();
-        config.setSelectInterval(NIOReactorParams.getSelectInterval(params));
-        config.setShutdownGracePeriod(NIOReactorParams.getGracePeriod(params));
-        config.setInterestOpQueued(NIOReactorParams.getInterestOpsQueueing(params));
-        config.setIoThreadCount(workerCount);
-        config.setTcpNoDelay(HttpConnectionParams.getTcpNoDelay(params));
-        config.setSoTimeout(HttpConnectionParams.getSoTimeout(params));
-        config.setSoLinger(HttpConnectionParams.getLinger(params));
-        config.setSoKeepalive(HttpConnectionParams.getSoKeepalive(params));
-        config.setConnectTimeout(HttpConnectionParams.getConnectionTimeout(params));
-        config.setSoReuseAddress(HttpConnectionParams.getSoReuseaddr(params));
-
-        return config;
+    @Deprecated
+    static IOReactorConfig convert(final int workerCount, final HttpParams params) {
+        Args.notNull(params, "HTTP parameters");
+        return IOReactorConfig.custom()
+            .setSelectInterval(params.getLongParameter(NIOReactorPNames.SELECT_INTERVAL, 1000))
+            .setShutdownGracePeriod(params.getLongParameter(NIOReactorPNames.GRACE_PERIOD, 500))
+            .setInterestOpQueued(params.getBooleanParameter(NIOReactorPNames.SELECT_INTERVAL, false))
+            .setIoThreadCount(workerCount)
+            .setSoTimeout(params.getIntParameter(CoreConnectionPNames.SO_TIMEOUT, 0))
+            .setConnectTimeout(params.getIntParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 0))
+            .setSoTimeout(params.getIntParameter(CoreConnectionPNames.SO_TIMEOUT, 0))
+            .setSoReuseAddress(params.getBooleanParameter(CoreConnectionPNames.SO_REUSEADDR, false))
+            .setSoKeepAlive(params.getBooleanParameter(CoreConnectionPNames.SO_KEEPALIVE, false))
+            .setSoLinger(params.getIntParameter(CoreConnectionPNames.SO_LINGER, -1))
+            .setTcpNoDelay(params.getBooleanParameter(CoreConnectionPNames.TCP_NODELAY, true))
+            .build();
     }
 
     /**
@@ -220,7 +200,7 @@ public abstract class AbstractMultiworkerIOReactor implements IOReactor {
      */
     @Deprecated
     public AbstractMultiworkerIOReactor(
-            int workerCount,
+            final int workerCount,
             final ThreadFactory threadFactory,
             final HttpParams params) throws IOReactorException {
         this(convert(workerCount, params), threadFactory);
@@ -252,17 +232,14 @@ public abstract class AbstractMultiworkerIOReactor implements IOReactor {
      * @param timestamp the time stamp of the exception. Can be
      * <code>null</code> in which case the current date / time will be used.
      */
-    protected synchronized void addExceptionEvent(final Throwable ex, Date timestamp) {
+    protected synchronized void addExceptionEvent(final Throwable ex, final Date timestamp) {
         if (ex == null) {
             return;
         }
-        if (timestamp == null) {
-            timestamp = new Date();
-        }
         if (this.auditLog == null) {
             this.auditLog = new ArrayList<ExceptionEvent>();
         }
-        this.auditLog.add(new ExceptionEvent(ex, timestamp));
+        this.auditLog.add(new ExceptionEvent(ex, timestamp != null ? timestamp : new Date()));
     }
 
     /**
@@ -326,27 +303,24 @@ public abstract class AbstractMultiworkerIOReactor implements IOReactor {
      */
     public void execute(
             final IOEventDispatch eventDispatch) throws InterruptedIOException, IOReactorException {
-        if (eventDispatch == null) {
-            throw new IllegalArgumentException("Event dispatcher may not be null");
-        }
+        Args.notNull(eventDispatch, "Event dispatcher");
         synchronized (this.statusLock) {
             if (this.status.compareTo(IOReactorStatus.SHUTDOWN_REQUEST) >= 0) {
                 this.status = IOReactorStatus.SHUT_DOWN;
                 this.statusLock.notifyAll();
                 return;
             }
-            if (this.status.compareTo(IOReactorStatus.INACTIVE) != 0) {
-                throw new IllegalStateException("Illegal state: " + this.status);
-            }
+            Asserts.check(this.status.compareTo(IOReactorStatus.INACTIVE) == 0,
+                    "Illegal state %s", this.status);
             this.status = IOReactorStatus.ACTIVE;
             // Start I/O dispatchers
             for (int i = 0; i < this.dispatchers.length; i++) {
-                BaseIOReactor dispatcher = new BaseIOReactor(this.selectTimeout, this.interestOpsQueueing);
+                final BaseIOReactor dispatcher = new BaseIOReactor(this.selectTimeout, this.interestOpsQueueing);
                 dispatcher.setExceptionHandler(exceptionHandler);
                 this.dispatchers[i] = dispatcher;
             }
             for (int i = 0; i < this.workerCount; i++) {
-                BaseIOReactor dispatcher = this.dispatchers[i];
+                final BaseIOReactor dispatcher = this.dispatchers[i];
                 this.workers[i] = new Worker(dispatcher, eventDispatch);
                 this.threads[i] = this.threadFactory.newThread(this.workers[i]);
             }
@@ -361,12 +335,12 @@ public abstract class AbstractMultiworkerIOReactor implements IOReactor {
             }
 
             for (;;) {
-                int readyCount;
+                final int readyCount;
                 try {
                     readyCount = this.selector.select(this.selectTimeout);
-                } catch (InterruptedIOException ex) {
+                } catch (final InterruptedIOException ex) {
                     throw ex;
-                } catch (IOException ex) {
+                } catch (final IOException ex) {
                     throw new IOReactorException("Unexpected selector failure", ex);
                 }
 
@@ -376,8 +350,8 @@ public abstract class AbstractMultiworkerIOReactor implements IOReactor {
 
                 // Verify I/O dispatchers
                 for (int i = 0; i < this.workerCount; i++) {
-                    Worker worker = this.workers[i];
-                    Exception ex = worker.getException();
+                    final Worker worker = this.workers[i];
+                    final Exception ex = worker.getException();
                     if (ex != null) {
                         throw new IOReactorException(
                                 "I/O dispatch worker terminated abnormally", ex);
@@ -389,9 +363,9 @@ public abstract class AbstractMultiworkerIOReactor implements IOReactor {
                 }
             }
 
-        } catch (ClosedSelectorException ex) {
+        } catch (final ClosedSelectorException ex) {
             addExceptionEvent(ex);
-        } catch (IOReactorException ex) {
+        } catch (final IOReactorException ex) {
             if (ex.getCause() != null) {
                 addExceptionEvent(ex.getCause());
             }
@@ -424,7 +398,7 @@ public abstract class AbstractMultiworkerIOReactor implements IOReactor {
         }
         try {
             cancelRequests();
-        } catch (IOReactorException ex) {
+        } catch (final IOReactorException ex) {
             if (ex.getCause() != null) {
                 addExceptionEvent(ex.getCause());
             }
@@ -433,46 +407,44 @@ public abstract class AbstractMultiworkerIOReactor implements IOReactor {
 
         // Close out all channels
         if (this.selector.isOpen()) {
-            Set<SelectionKey> keys = this.selector.keys();
-            for (Iterator<SelectionKey> it = keys.iterator(); it.hasNext(); ) {
+            for (final SelectionKey key : this.selector.keys()) {
                 try {
-                    SelectionKey key = it.next();
-                    Channel channel = key.channel();
+                    final Channel channel = key.channel();
                     if (channel != null) {
                         channel.close();
                     }
-                } catch (IOException ex) {
+                } catch (final IOException ex) {
                     addExceptionEvent(ex);
                 }
             }
             // Stop dispatching I/O events
             try {
                 this.selector.close();
-            } catch (IOException ex) {
+            } catch (final IOException ex) {
                 addExceptionEvent(ex);
             }
         }
 
         // Attempt to shut down I/O dispatchers gracefully
         for (int i = 0; i < this.workerCount; i++) {
-            BaseIOReactor dispatcher = this.dispatchers[i];
+            final BaseIOReactor dispatcher = this.dispatchers[i];
             dispatcher.gracefulShutdown();
         }
 
-        long gracePeriod = this.config.getShutdownGracePeriod();
+        final long gracePeriod = this.config.getShutdownGracePeriod();
 
         try {
             // Force shut down I/O dispatchers if they fail to terminate
             // in time
             for (int i = 0; i < this.workerCount; i++) {
-                BaseIOReactor dispatcher = this.dispatchers[i];
+                final BaseIOReactor dispatcher = this.dispatchers[i];
                 if (dispatcher.getStatus() != IOReactorStatus.INACTIVE) {
                     dispatcher.awaitShutdown(gracePeriod);
                 }
                 if (dispatcher.getStatus() != IOReactorStatus.SHUT_DOWN) {
                     try {
                         dispatcher.hardShutdown();
-                    } catch (IOReactorException ex) {
+                    } catch (final IOReactorException ex) {
                         if (ex.getCause() != null) {
                             addExceptionEvent(ex.getCause());
                         }
@@ -481,12 +453,12 @@ public abstract class AbstractMultiworkerIOReactor implements IOReactor {
             }
             // Join worker threads
             for (int i = 0; i < this.workerCount; i++) {
-                Thread t = this.threads[i];
+                final Thread t = this.threads[i];
                 if (t != null) {
                     t.join(gracePeriod);
                 }
             }
-        } catch (InterruptedException ex) {
+        } catch (final InterruptedException ex) {
             throw new InterruptedIOException(ex.getMessage());
         }
     }
@@ -498,7 +470,7 @@ public abstract class AbstractMultiworkerIOReactor implements IOReactor {
      */
     protected void addChannel(final ChannelEntry entry) {
         // Distribute new channels among the workers
-        int i = Math.abs(this.currentWorker++ % this.workerCount);
+        final int i = Math.abs(this.currentWorker++ % this.workerCount);
         this.dispatchers[i].addChannel(entry);
     }
 
@@ -511,7 +483,7 @@ public abstract class AbstractMultiworkerIOReactor implements IOReactor {
      * @throws ClosedChannelException if the channel has been already closed.
      */
     protected SelectionKey registerChannel(
-            final SelectableChannel channel, int ops) throws ClosedChannelException {
+            final SelectableChannel channel, final int ops) throws ClosedChannelException {
         return channel.register(this.selector, ops);
     }
 
@@ -524,7 +496,6 @@ public abstract class AbstractMultiworkerIOReactor implements IOReactor {
     protected void prepareSocket(final Socket socket) throws IOException {
         socket.setTcpNoDelay(this.config.isTcpNoDelay());
         socket.setKeepAlive(this.config.isSoKeepalive());
-        socket.setReuseAddress(this.config.isSoReuseAddress());
         if (this.config.getSoTimeout() > 0) {
             socket.setSoTimeout(this.config.getSoTimeout());
         }
@@ -534,7 +505,7 @@ public abstract class AbstractMultiworkerIOReactor implements IOReactor {
         if (this.config.getRcvBufSize() > 0) {
             socket.setReceiveBufferSize(this.config.getRcvBufSize());
         }
-        int linger = this.config.getSoLinger();
+        final int linger = this.config.getSoLinger();
         if (linger >= 0) {
             socket.setSoLinger(linger > 0, linger);
         }
@@ -549,9 +520,9 @@ public abstract class AbstractMultiworkerIOReactor implements IOReactor {
      * @param timeout the maximum wait time.
      * @throws InterruptedException if interrupted.
      */
-    protected void awaitShutdown(long timeout) throws InterruptedException {
+    protected void awaitShutdown(final long timeout) throws InterruptedException {
         synchronized (this.statusLock) {
-            long deadline = System.currentTimeMillis() + timeout;
+            final long deadline = System.currentTimeMillis() + timeout;
             long remaining = timeout;
             while (this.status != IOReactorStatus.SHUT_DOWN) {
                 this.statusLock.wait(remaining);
@@ -569,7 +540,7 @@ public abstract class AbstractMultiworkerIOReactor implements IOReactor {
         shutdown(2000);
     }
 
-    public void shutdown(long waitMs) throws IOException {
+    public void shutdown(final long waitMs) throws IOException {
         synchronized (this.statusLock) {
             if (this.status.compareTo(IOReactorStatus.ACTIVE) > 0) {
                 return;
@@ -584,14 +555,14 @@ public abstract class AbstractMultiworkerIOReactor implements IOReactor {
         this.selector.wakeup();
         try {
             awaitShutdown(waitMs);
-        } catch (InterruptedException ignore) {
+        } catch (final InterruptedException ignore) {
         }
     }
 
     static void closeChannel(final Channel channel) {
         try {
             channel.close();
-        } catch (IOException ignore) {
+        } catch (final IOException ignore) {
         }
     }
 
@@ -611,7 +582,7 @@ public abstract class AbstractMultiworkerIOReactor implements IOReactor {
         public void run() {
             try {
                 this.dispatcher.execute(this.eventDispatch);
-            } catch (Exception ex) {
+            } catch (final Exception ex) {
                 this.exception = ex;
             }
         }
diff --git a/httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/BaseIOReactor.java b/httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/BaseIOReactor.java
index 0501961..b6256a0 100644
--- a/httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/BaseIOReactor.java
+++ b/httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/BaseIOReactor.java
@@ -37,16 +37,17 @@ import java.util.Set;
 import org.apache.http.annotation.ThreadSafe;
 import org.apache.http.nio.reactor.EventMask;
 import org.apache.http.nio.reactor.IOEventDispatch;
-import org.apache.http.nio.reactor.IOReactor;
 import org.apache.http.nio.reactor.IOReactorException;
 import org.apache.http.nio.reactor.IOReactorExceptionHandler;
 import org.apache.http.nio.reactor.IOSession;
+import org.apache.http.util.Args;
 
 /**
  * Default implementation of {@link AbstractIOReactor} that serves as a base
- * for more advanced {@link IOReactor} implementations. This class adds
- * support for the I/O event dispatching using {@link IOEventDispatch},
- * management of buffering sessions, and session timeout handling.
+ * for more advanced {@link org.apache.http.nio.reactor.IOReactor}
+ * implementations. This class adds support for the I/O event dispatching
+ * using {@link IOEventDispatch}, management of buffering sessions, and
+ * session timeout handling.
  *
  * @since 4.0
  */
@@ -67,7 +68,7 @@ public class BaseIOReactor extends AbstractIOReactor {
      * @param selectTimeout the select timeout.
      * @throws IOReactorException in case if a non-recoverable I/O error.
      */
-    public BaseIOReactor(long selectTimeout) throws IOReactorException {
+    public BaseIOReactor(final long selectTimeout) throws IOReactorException {
         this(selectTimeout, false);
     }
 
@@ -82,7 +83,7 @@ public class BaseIOReactor extends AbstractIOReactor {
      * @since 4.1
      */
     public BaseIOReactor(
-            long selectTimeout, boolean interestOpsQueueing) throws IOReactorException {
+            final long selectTimeout, final boolean interestOpsQueueing) throws IOReactorException {
         super(selectTimeout, interestOpsQueueing);
         this.bufferingSessions = new HashSet<IOSession>();
         this.timeoutCheckInterval = selectTimeout;
@@ -99,9 +100,7 @@ public class BaseIOReactor extends AbstractIOReactor {
      */
     public void execute(
             final IOEventDispatch eventDispatch) throws InterruptedIOException, IOReactorException {
-        if (eventDispatch == null) {
-            throw new IllegalArgumentException("Event dispatcher may not be null");
-        }
+        Args.notNull(eventDispatch, "Event dispatcher");
         this.eventDispatch = eventDispatch;
         execute();
     }
@@ -155,16 +154,16 @@ public class BaseIOReactor extends AbstractIOReactor {
      */
     @Override
     protected void readable(final SelectionKey key) {
-        IOSession session = getSession(key);
+        final IOSession session = getSession(key);
         try {
             this.eventDispatch.inputReady(session);
             if (session.hasBufferedInput()) {
                 this.bufferingSessions.add(session);
             }
-        } catch (CancelledKeyException ex) {
+        } catch (final CancelledKeyException ex) {
             queueClosedSession(session);
             key.attach(null);
-        } catch (RuntimeException ex) {
+        } catch (final RuntimeException ex) {
             handleRuntimeException(ex);
         }
     }
@@ -176,13 +175,13 @@ public class BaseIOReactor extends AbstractIOReactor {
      */
     @Override
     protected void writable(final SelectionKey key) {
-        IOSession session = getSession(key);
+        final IOSession session = getSession(key);
         try {
             this.eventDispatch.outputReady(session);
-        } catch (CancelledKeyException ex) {
+        } catch (final CancelledKeyException ex) {
             queueClosedSession(session);
             key.attach(null);
-        } catch (RuntimeException ex) {
+        } catch (final RuntimeException ex) {
             handleRuntimeException(ex);
         }
     }
@@ -198,19 +197,18 @@ public class BaseIOReactor extends AbstractIOReactor {
      */
     @Override
     protected void validate(final Set<SelectionKey> keys) {
-        long currentTime = System.currentTimeMillis();
+        final long currentTime = System.currentTimeMillis();
         if( (currentTime - this.lastTimeoutCheck) >= this.timeoutCheckInterval) {
             this.lastTimeoutCheck = currentTime;
             if (keys != null) {
-                for (Iterator<SelectionKey> it = keys.iterator(); it.hasNext();) {
-                    SelectionKey key = it.next();
+                for (final SelectionKey key : keys) {
                     timeoutCheck(key, currentTime);
                 }
             }
         }
         if (!this.bufferingSessions.isEmpty()) {
-            for (Iterator<IOSession> it = this.bufferingSessions.iterator(); it.hasNext(); ) {
-                IOSession session = it.next();
+            for (final Iterator<IOSession> it = this.bufferingSessions.iterator(); it.hasNext(); ) {
+                final IOSession session = it.next();
                 if (!session.hasBufferedInput()) {
                     it.remove();
                     continue;
@@ -222,10 +220,10 @@ public class BaseIOReactor extends AbstractIOReactor {
                             it.remove();
                         }
                     }
-                } catch (CancelledKeyException ex) {
+                } catch (final CancelledKeyException ex) {
                     it.remove();
                     queueClosedSession(session);
-                } catch (RuntimeException ex) {
+                } catch (final RuntimeException ex) {
                     handleRuntimeException(ex);
                 }
             }
@@ -240,9 +238,9 @@ public class BaseIOReactor extends AbstractIOReactor {
     protected void sessionCreated(final SelectionKey key, final IOSession session) {
         try {
             this.eventDispatch.connected(session);
-        } catch (CancelledKeyException ex) {
+        } catch (final CancelledKeyException ex) {
             queueClosedSession(session);
-        } catch (RuntimeException ex) {
+        } catch (final RuntimeException ex) {
             handleRuntimeException(ex);
         }
     }
@@ -255,9 +253,9 @@ public class BaseIOReactor extends AbstractIOReactor {
     protected void sessionTimedOut(final IOSession session) {
         try {
             this.eventDispatch.timeout(session);
-        } catch (CancelledKeyException ex) {
+        } catch (final CancelledKeyException ex) {
             queueClosedSession(session);
-        } catch (RuntimeException ex) {
+        } catch (final RuntimeException ex) {
             handleRuntimeException(ex);
         }
     }
@@ -271,9 +269,9 @@ public class BaseIOReactor extends AbstractIOReactor {
     protected void sessionClosed(final IOSession session) {
         try {
             this.eventDispatch.disconnected(session);
-        } catch (CancelledKeyException ex) {
+        } catch (final CancelledKeyException ex) {
             // ignore
-        } catch (RuntimeException ex) {
+        } catch (final RuntimeException ex) {
             handleRuntimeException(ex);
         }
     }
diff --git a/httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/ChannelEntry.java b/httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/ChannelEntry.java
index 7f4bb0a..5d76da2 100644
--- a/httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/ChannelEntry.java
+++ b/httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/ChannelEntry.java
@@ -30,6 +30,7 @@ package org.apache.http.impl.nio.reactor;
 import java.nio.channels.SocketChannel;
 
 import org.apache.http.annotation.Immutable;
+import org.apache.http.util.Args;
 
 /**
  * {@link SocketChannel} entry maintained by the I/O reactor. If the channel
@@ -53,9 +54,7 @@ public class ChannelEntry {
      */
     public ChannelEntry(final SocketChannel channel, final SessionRequestImpl sessionRequest) {
         super();
-        if (channel == null) {
-            throw new IllegalArgumentException("Socket channel may not be null");
-        }
+        Args.notNull(channel, "Socket channel");
         this.channel = channel;
         this.sessionRequest = sessionRequest;
     }
diff --git a/httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/DefaultConnectingIOReactor.java b/httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/DefaultConnectingIOReactor.java
index 1bfca1c..7b63c88 100644
--- a/httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/DefaultConnectingIOReactor.java
+++ b/httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/DefaultConnectingIOReactor.java
@@ -35,7 +35,6 @@ import java.net.UnknownHostException;
 import java.nio.channels.CancelledKeyException;
 import java.nio.channels.SelectionKey;
 import java.nio.channels.SocketChannel;
-import java.util.Iterator;
 import java.util.Queue;
 import java.util.Set;
 import java.util.concurrent.ConcurrentLinkedQueue;
@@ -48,6 +47,7 @@ import org.apache.http.nio.reactor.IOReactorStatus;
 import org.apache.http.nio.reactor.SessionRequest;
 import org.apache.http.nio.reactor.SessionRequestCallback;
 import org.apache.http.params.HttpParams;
+import org.apache.http.util.Asserts;
 
 /**
  * Default implementation of {@link ConnectingIOReactor}. This class extends
@@ -56,6 +56,7 @@ import org.apache.http.params.HttpParams;
  *
  * @since 4.0
  */
+ at SuppressWarnings("deprecation")
 @ThreadSafe // public methods only
 public class DefaultConnectingIOReactor extends AbstractMultiworkerIOReactor
         implements ConnectingIOReactor {
@@ -111,7 +112,7 @@ public class DefaultConnectingIOReactor extends AbstractMultiworkerIOReactor
      */
     @Deprecated
     public DefaultConnectingIOReactor(
-            int workerCount,
+            final int workerCount,
             final ThreadFactory threadFactory,
             final HttpParams params) throws IOReactorException {
         this(convert(workerCount, params), threadFactory);
@@ -122,7 +123,7 @@ public class DefaultConnectingIOReactor extends AbstractMultiworkerIOReactor
      */
     @Deprecated
     public DefaultConnectingIOReactor(
-            int workerCount,
+            final int workerCount,
             final HttpParams params) throws IOReactorException {
         this(convert(workerCount, params), null);
     }
@@ -136,24 +137,23 @@ public class DefaultConnectingIOReactor extends AbstractMultiworkerIOReactor
     }
 
     @Override
-    protected void processEvents(int readyCount) throws IOReactorException {
+    protected void processEvents(final int readyCount) throws IOReactorException {
         processSessionRequests();
 
         if (readyCount > 0) {
-            Set<SelectionKey> selectedKeys = this.selector.selectedKeys();
-            for (Iterator<SelectionKey> it = selectedKeys.iterator(); it.hasNext(); ) {
+            final Set<SelectionKey> selectedKeys = this.selector.selectedKeys();
+            for (final SelectionKey key : selectedKeys) {
 
-                SelectionKey key = it.next();
                 processEvent(key);
 
             }
             selectedKeys.clear();
         }
 
-        long currentTime = System.currentTimeMillis();
+        final long currentTime = System.currentTimeMillis();
         if ((currentTime - this.lastTimeoutCheck) >= this.selectTimeout) {
             this.lastTimeoutCheck = currentTime;
-            Set<SelectionKey> keys = this.selector.keys();
+            final Set<SelectionKey> keys = this.selector.keys();
             processTimeouts(keys);
         }
     }
@@ -163,15 +163,15 @@ public class DefaultConnectingIOReactor extends AbstractMultiworkerIOReactor
 
             if (key.isConnectable()) {
 
-                SocketChannel channel = (SocketChannel) key.channel();
+                final SocketChannel channel = (SocketChannel) key.channel();
                 // Get request handle
-                SessionRequestHandle requestHandle = (SessionRequestHandle) key.attachment();
-                SessionRequestImpl sessionRequest = requestHandle.getSessionRequest();
+                final SessionRequestHandle requestHandle = (SessionRequestHandle) key.attachment();
+                final SessionRequestImpl sessionRequest = requestHandle.getSessionRequest();
 
                 // Finish connection process
                 try {
                     channel.finishConnect();
-                } catch (IOException ex) {
+                } catch (final IOException ex) {
                     sessionRequest.failed(ex);
                 }
                 key.cancel();
@@ -179,36 +179,35 @@ public class DefaultConnectingIOReactor extends AbstractMultiworkerIOReactor
                     try {
                         try {
                             prepareSocket(channel.socket());
-                        } catch (IOException ex) {
+                        } catch (final IOException ex) {
                             if (this.exceptionHandler == null
                                     || !this.exceptionHandler.handle(ex)) {
                                 throw new IOReactorException(
                                         "Failure initalizing socket", ex);
                             }
                         }
-                        ChannelEntry entry = new ChannelEntry(channel, sessionRequest);
+                        final ChannelEntry entry = new ChannelEntry(channel, sessionRequest);
                         addChannel(entry);
-                    } catch (IOException ex) {
+                    } catch (final IOException ex) {
                         sessionRequest.failed(ex);
                     }
                 }
             }
 
-        } catch (CancelledKeyException ex) {
+        } catch (final CancelledKeyException ex) {
             key.attach(null);
         }
     }
 
     private void processTimeouts(final Set<SelectionKey> keys) {
-        long now = System.currentTimeMillis();
-        for (Iterator<SelectionKey> it = keys.iterator(); it.hasNext();) {
-            SelectionKey key = it.next();
-            Object attachment = key.attachment();
+        final long now = System.currentTimeMillis();
+        for (final SelectionKey key : keys) {
+            final Object attachment = key.attachment();
 
             if (attachment instanceof SessionRequestHandle) {
-                SessionRequestHandle handle = (SessionRequestHandle) key.attachment();
-                SessionRequestImpl sessionRequest = handle.getSessionRequest();
-                int timeout = sessionRequest.getConnectTimeout();
+                final SessionRequestHandle handle = (SessionRequestHandle) key.attachment();
+                final SessionRequestImpl sessionRequest = handle.getSessionRequest();
+                final int timeout = sessionRequest.getConnectTimeout();
                 if (timeout > 0) {
                     if (handle.getRequestTime() + timeout < now) {
                         sessionRequest.timeout();
@@ -224,11 +223,9 @@ public class DefaultConnectingIOReactor extends AbstractMultiworkerIOReactor
             final SocketAddress localAddress,
             final Object attachment,
             final SessionRequestCallback callback) {
-
-        if (this.status.compareTo(IOReactorStatus.ACTIVE) > 0) {
-            throw new IllegalStateException("I/O reactor has been shut down");
-        }
-        SessionRequestImpl sessionRequest = new SessionRequestImpl(
+        Asserts.check(this.status.compareTo(IOReactorStatus.ACTIVE) <= 0,
+            "I/O reactor has been shut down");
+        final SessionRequestImpl sessionRequest = new SessionRequestImpl(
                 remoteAddress, localAddress, attachment, callback);
         sessionRequest.setConnectTimeout(this.config.getConnectTimeout());
 
@@ -243,7 +240,7 @@ public class DefaultConnectingIOReactor extends AbstractMultiworkerIOReactor
             return;
         }
         if (address instanceof InetSocketAddress) {
-            InetSocketAddress endpoint = (InetSocketAddress) address;
+            final InetSocketAddress endpoint = (InetSocketAddress) address;
             if (endpoint.isUnresolved()) {
                 throw new UnknownHostException(endpoint.getHostName());
             }
@@ -256,10 +253,10 @@ public class DefaultConnectingIOReactor extends AbstractMultiworkerIOReactor
             if (request.isCompleted()) {
                 continue;
             }
-            SocketChannel socketChannel;
+            final SocketChannel socketChannel;
             try {
                 socketChannel = SocketChannel.open();
-            } catch (IOException ex) {
+            } catch (final IOException ex) {
                 throw new IOReactorException("Failure opening socket", ex);
             }
             try {
@@ -268,29 +265,29 @@ public class DefaultConnectingIOReactor extends AbstractMultiworkerIOReactor
                 validateAddress(request.getRemoteAddress());
 
                 if (request.getLocalAddress() != null) {
-                    Socket sock = socketChannel.socket();
+                    final Socket sock = socketChannel.socket();
                     sock.setReuseAddress(this.config.isSoReuseAddress());
                     sock.bind(request.getLocalAddress());
                 }
-                boolean connected = socketChannel.connect(request.getRemoteAddress());
+                final boolean connected = socketChannel.connect(request.getRemoteAddress());
                 if (connected) {
                     prepareSocket(socketChannel.socket());
-                    ChannelEntry entry = new ChannelEntry(socketChannel, request);
+                    final ChannelEntry entry = new ChannelEntry(socketChannel, request);
                     addChannel(entry);
                     return;
                 }
-            } catch (IOException ex) {
+            } catch (final IOException ex) {
                 closeChannel(socketChannel);
                 request.failed(ex);
                 return;
             }
 
-            SessionRequestHandle requestHandle = new SessionRequestHandle(request);
+            final SessionRequestHandle requestHandle = new SessionRequestHandle(request);
             try {
-                SelectionKey key = socketChannel.register(this.selector, SelectionKey.OP_CONNECT,
+                final SelectionKey key = socketChannel.register(this.selector, SelectionKey.OP_CONNECT,
                         requestHandle);
                 request.setKey(key);
-            } catch (IOException ex) {
+            } catch (final IOException ex) {
                 closeChannel(socketChannel);
                 throw new IOReactorException("Failure registering channel " +
                         "with the selector", ex);
diff --git a/httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/DefaultListeningIOReactor.java b/httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/DefaultListeningIOReactor.java
index b1a2ac6..2509507 100644
--- a/httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/DefaultListeningIOReactor.java
+++ b/httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/DefaultListeningIOReactor.java
@@ -48,6 +48,7 @@ import org.apache.http.nio.reactor.IOReactorStatus;
 import org.apache.http.nio.reactor.ListenerEndpoint;
 import org.apache.http.nio.reactor.ListeningIOReactor;
 import org.apache.http.params.HttpParams;
+import org.apache.http.util.Asserts;
 
 /**
  * Default implementation of {@link ListeningIOReactor}. This class extends
@@ -56,6 +57,7 @@ import org.apache.http.params.HttpParams;
  *
  * @since 4.0
  */
+ at SuppressWarnings("deprecation")
 @ThreadSafe // public methods only
 public class DefaultListeningIOReactor extends AbstractMultiworkerIOReactor
         implements ListeningIOReactor {
@@ -114,7 +116,7 @@ public class DefaultListeningIOReactor extends AbstractMultiworkerIOReactor
      */
     @Deprecated
     public DefaultListeningIOReactor(
-            int workerCount,
+            final int workerCount,
             final ThreadFactory threadFactory,
             final HttpParams params) throws IOReactorException {
         this(convert(workerCount, params), threadFactory);
@@ -125,7 +127,7 @@ public class DefaultListeningIOReactor extends AbstractMultiworkerIOReactor
      */
     @Deprecated
     public DefaultListeningIOReactor(
-            int workerCount,
+            final int workerCount,
             final HttpParams params) throws IOReactorException {
         this(convert(workerCount, params), null);
     }
@@ -139,16 +141,15 @@ public class DefaultListeningIOReactor extends AbstractMultiworkerIOReactor
     }
 
     @Override
-    protected void processEvents(int readyCount) throws IOReactorException {
+    protected void processEvents(final int readyCount) throws IOReactorException {
         if (!this.paused) {
             processSessionRequests();
         }
 
         if (readyCount > 0) {
-            Set<SelectionKey> selectedKeys = this.selector.selectedKeys();
-            for (Iterator<SelectionKey> it = selectedKeys.iterator(); it.hasNext(); ) {
+            final Set<SelectionKey> selectedKeys = this.selector.selectedKeys();
+            for (final SelectionKey key : selectedKeys) {
 
-                SelectionKey key = it.next();
                 processEvent(key);
 
             }
@@ -162,12 +163,12 @@ public class DefaultListeningIOReactor extends AbstractMultiworkerIOReactor
 
             if (key.isAcceptable()) {
 
-                ServerSocketChannel serverChannel = (ServerSocketChannel) key.channel();
+                final ServerSocketChannel serverChannel = (ServerSocketChannel) key.channel();
                 for (;;) {
                     SocketChannel socketChannel = null;
                     try {
                         socketChannel = serverChannel.accept();
-                    } catch (IOException ex) {
+                    } catch (final IOException ex) {
                         if (this.exceptionHandler == null ||
                                 !this.exceptionHandler.handle(ex)) {
                             throw new IOReactorException(
@@ -179,27 +180,27 @@ public class DefaultListeningIOReactor extends AbstractMultiworkerIOReactor
                     }
                     try {
                         prepareSocket(socketChannel.socket());
-                    } catch (IOException ex) {
+                    } catch (final IOException ex) {
                         if (this.exceptionHandler == null ||
                                 !this.exceptionHandler.handle(ex)) {
                             throw new IOReactorException(
                                     "Failure initalizing socket", ex);
                         }
                     }
-                    ChannelEntry entry = new ChannelEntry(socketChannel);
+                    final ChannelEntry entry = new ChannelEntry(socketChannel);
                     addChannel(entry);
                 }
             }
 
-        } catch (CancelledKeyException ex) {
-            ListenerEndpoint endpoint = (ListenerEndpoint) key.attachment();
+        } catch (final CancelledKeyException ex) {
+            final ListenerEndpoint endpoint = (ListenerEndpoint) key.attachment();
             this.endpoints.remove(endpoint);
             key.attach(null);
         }
     }
 
     private ListenerEndpointImpl createEndpoint(final SocketAddress address) {
-        ListenerEndpointImpl endpoint = new ListenerEndpointImpl(
+        return new ListenerEndpointImpl(
                 address,
                 new ListenerEndpointClosedCallback() {
 
@@ -208,14 +209,12 @@ public class DefaultListeningIOReactor extends AbstractMultiworkerIOReactor
                     }
 
                 });
-        return endpoint;
     }
 
     public ListenerEndpoint listen(final SocketAddress address) {
-        if (this.status.compareTo(IOReactorStatus.ACTIVE) > 0) {
-            throw new IllegalStateException("I/O reactor has been shut down");
-        }
-        ListenerEndpointImpl request = createEndpoint(address);
+        Asserts.check(this.status.compareTo(IOReactorStatus.ACTIVE) <= 0,
+                "I/O reactor has been shut down");
+        final ListenerEndpointImpl request = createEndpoint(address);
         this.requestQueue.add(request);
         this.selector.wakeup();
         return request;
@@ -224,19 +223,19 @@ public class DefaultListeningIOReactor extends AbstractMultiworkerIOReactor
     private void processSessionRequests() throws IOReactorException {
         ListenerEndpointImpl request;
         while ((request = this.requestQueue.poll()) != null) {
-            SocketAddress address = request.getAddress();
-            ServerSocketChannel serverChannel;
+            final SocketAddress address = request.getAddress();
+            final ServerSocketChannel serverChannel;
             try {
                 serverChannel = ServerSocketChannel.open();
-            } catch (IOException ex) {
+            } catch (final IOException ex) {
                 throw new IOReactorException("Failure opening server socket", ex);
             }
             try {
-                ServerSocket socket = serverChannel.socket();
+                final ServerSocket socket = serverChannel.socket();
                 socket.setReuseAddress(this.config.isSoReuseAddress());
                 serverChannel.configureBlocking(false);
                 socket.bind(address);
-            } catch (IOException ex) {
+            } catch (final IOException ex) {
                 closeChannel(serverChannel);
                 request.failed(ex);
                 if (this.exceptionHandler == null || !this.exceptionHandler.handle(ex)) {
@@ -247,10 +246,10 @@ public class DefaultListeningIOReactor extends AbstractMultiworkerIOReactor
                 }
             }
             try {
-                SelectionKey key = serverChannel.register(this.selector, SelectionKey.OP_ACCEPT);
+                final SelectionKey key = serverChannel.register(this.selector, SelectionKey.OP_ACCEPT);
                 key.attach(request);
                 request.setKey(key);
-            } catch (IOException ex) {
+            } catch (final IOException ex) {
                 closeChannel(serverChannel);
                 throw new IOReactorException("Failure registering channel " +
                         "with the selector", ex);
@@ -262,11 +261,11 @@ public class DefaultListeningIOReactor extends AbstractMultiworkerIOReactor
     }
 
     public Set<ListenerEndpoint> getEndpoints() {
-        Set<ListenerEndpoint> set = new HashSet<ListenerEndpoint>();
+        final Set<ListenerEndpoint> set = new HashSet<ListenerEndpoint>();
         synchronized (this.endpoints) {
-            Iterator<ListenerEndpointImpl> it = this.endpoints.iterator();
+            final Iterator<ListenerEndpointImpl> it = this.endpoints.iterator();
             while (it.hasNext()) {
-                ListenerEndpoint endpoint = it.next();
+                final ListenerEndpoint endpoint = it.next();
                 if (!endpoint.isClosed()) {
                     set.add(endpoint);
                 } else {
@@ -283,9 +282,7 @@ public class DefaultListeningIOReactor extends AbstractMultiworkerIOReactor
         }
         this.paused = true;
         synchronized (this.endpoints) {
-            Iterator<ListenerEndpointImpl> it = this.endpoints.iterator();
-            while (it.hasNext()) {
-                ListenerEndpoint endpoint = it.next();
+            for (final ListenerEndpointImpl endpoint : this.endpoints) {
                 if (!endpoint.isClosed()) {
                     endpoint.close();
                     this.pausedEndpoints.add(endpoint.getAddress());
@@ -300,8 +297,8 @@ public class DefaultListeningIOReactor extends AbstractMultiworkerIOReactor
             return;
         }
         this.paused = false;
-        for (SocketAddress address: this.pausedEndpoints) {
-            ListenerEndpointImpl request = createEndpoint(address);
+        for (final SocketAddress address: this.pausedEndpoints) {
+            final ListenerEndpointImpl request = createEndpoint(address);
             this.requestQueue.add(request);
         }
         this.pausedEndpoints.clear();
diff --git a/httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/ExceptionEvent.java b/httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/ExceptionEvent.java
index 2190945..0b18dba 100644
--- a/httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/ExceptionEvent.java
+++ b/httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/ExceptionEvent.java
@@ -66,7 +66,7 @@ public class ExceptionEvent {
 
     @Override
     public String toString() {
-        StringBuilder buffer = new StringBuilder();
+        final StringBuilder buffer = new StringBuilder();
         buffer.append(new Date(this.time));
         buffer.append(" ");
         buffer.append(this.ex);
diff --git a/httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/IOReactorConfig.java b/httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/IOReactorConfig.java
index f555b39..6372962 100644
--- a/httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/IOReactorConfig.java
+++ b/httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/IOReactorConfig.java
@@ -27,10 +27,8 @@
 
 package org.apache.http.impl.nio.reactor;
 
-import java.net.SocketOptions;
-import java.nio.channels.SelectionKey;
-
 import org.apache.http.annotation.NotThreadSafe;
+import org.apache.http.util.Args;
 
 /**
  * I/O reactor configuration parameters.
@@ -42,6 +40,9 @@ public final class IOReactorConfig implements Cloneable {
 
     private static final int AVAIL_PROCS = Runtime.getRuntime().availableProcessors();
 
+    public static final IOReactorConfig DEFAULT = new Builder().build();
+
+    // TODO: make final
     private long selectInterval;
     private long shutdownGracePeriod;
     private boolean interestOpQueued;
@@ -55,6 +56,7 @@ public final class IOReactorConfig implements Cloneable {
     private int sndBufSize;
     private int rcvBufSize;
 
+    @Deprecated
     public IOReactorConfig() {
         super();
         this.selectInterval = 1000;
@@ -67,6 +69,36 @@ public final class IOReactorConfig implements Cloneable {
         this.soKeepAlive = false;
         this.tcpNoDelay = true;
         this.connectTimeout = 0;
+        this.sndBufSize = 0;
+        this.rcvBufSize = 0;
+    }
+
+    IOReactorConfig(
+            final long selectInterval,
+            final long shutdownGracePeriod,
+            final boolean interestOpQueued,
+            final int ioThreadCount,
+            final int soTimeout,
+            final boolean soReuseAddress,
+            final int soLinger,
+            final boolean soKeepAlive,
+            final boolean tcpNoDelay,
+            final int connectTimeout,
+            final int sndBufSize,
+            final int rcvBufSize) {
+        super();
+        this.selectInterval = selectInterval;
+        this.shutdownGracePeriod = shutdownGracePeriod;
+        this.interestOpQueued = interestOpQueued;
+        this.ioThreadCount = ioThreadCount;
+        this.soTimeout = soTimeout;
+        this.soReuseAddress = soReuseAddress;
+        this.soLinger = soLinger;
+        this.soKeepAlive = soKeepAlive;
+        this.tcpNoDelay = tcpNoDelay;
+        this.connectTimeout = connectTimeout;
+        this.sndBufSize = sndBufSize;
+        this.rcvBufSize = rcvBufSize;
     }
 
     /**
@@ -80,13 +112,11 @@ public final class IOReactorConfig implements Cloneable {
     }
 
     /**
-     * Defines time interval in milliseconds at which the I/O reactor wakes up to check for
-     * timed out sessions and session requests. May not be negative or zero.
+     * @deprecated (4.3) use {@link Builder#setSelectInterval(long)}
      */
-    public void setSelectInterval(long selectInterval) {
-        if (selectInterval <= 0) {
-            throw new IllegalArgumentException("Select internal may not be negative or zero");
-        }
+    @Deprecated
+    public void setSelectInterval(final long selectInterval) {
+        Args.positive(selectInterval, "Select internal");
         this.selectInterval = selectInterval;
     }
 
@@ -101,41 +131,34 @@ public final class IOReactorConfig implements Cloneable {
     }
 
     /**
-     * Defines grace period in milliseconds the I/O reactors are expected to block waiting
-     * for individual worker threads to terminate cleanly. May not be negative or zero.
+     * @deprecated (4.3) use {@link Builder#setShutdownGracePeriod(long)}
      */
-    public void setShutdownGracePeriod(long gracePeriod) {
-        if (gracePeriod <= 0) {
-            throw new IllegalArgumentException("Shutdown grace period may not be negative or zero");
-        }
+    @Deprecated
+    public void setShutdownGracePeriod(final long gracePeriod) {
+        Args.positive(gracePeriod, "Shutdown grace period");
         this.shutdownGracePeriod = gracePeriod;
     }
 
     /**
      * Determines whether or not I/O interest operations are to be queued and executed
      * asynchronously by the I/O reactor thread or to be applied to the underlying
-     * {@link SelectionKey} immediately.
+     * {@link java.nio.channels.SelectionKey} immediately.
      * <p/>
      * Default: <code>false</code>
      *
-     * @see SelectionKey
-     * @see SelectionKey#interestOps()
-     * @see SelectionKey#interestOps(int)
+     * @see java.nio.channels.SelectionKey
+     * @see java.nio.channels.SelectionKey#interestOps()
+     * @see java.nio.channels.SelectionKey#interestOps(int)
      */
     public boolean isInterestOpQueued() {
         return this.interestOpQueued;
     }
 
     /**
-     * Defines whether or not I/O interest operations are to be queued and executed
-     * asynchronously by the I/O reactor thread or to be applied to the underlying
-     * {@link SelectionKey} immediately.
-     *
-     * @see SelectionKey
-     * @see SelectionKey#interestOps()
-     * @see SelectionKey#interestOps(int)
+     * @deprecated (4.3) use {@link Builder#setInterestOpQueued(boolean)}
      */
-    public void setInterestOpQueued(boolean interestOpQueued) {
+    @Deprecated
+    public void setInterestOpQueued(final boolean interestOpQueued) {
         this.interestOpQueued = interestOpQueued;
     }
 
@@ -149,13 +172,11 @@ public final class IOReactorConfig implements Cloneable {
     }
 
     /**
-     * Defines the number of I/O dispatch threads to be used by the I/O reactor.
-     * May not be negative or zero.
+     * @deprecated (4.3) use {@link Builder#setIoThreadCount(int)}
      */
-    public void setIoThreadCount(int ioThreadCount) {
-        if (ioThreadCount <= 0) {
-            throw new IllegalArgumentException("I/O thread count may not be negative or zero");
-        }
+    @Deprecated
+    public void setIoThreadCount(final int ioThreadCount) {
+        Args.positive(ioThreadCount, "I/O thread count");
         this.ioThreadCount = ioThreadCount;
     }
 
@@ -164,110 +185,97 @@ public final class IOReactorConfig implements Cloneable {
      * <p/>
      * Default: <code>0</code> (no timeout)
      *
-     * @see SocketOptions#SO_TIMEOUT
+     * @see java.net.SocketOptions#SO_TIMEOUT
      */
     public int getSoTimeout() {
         return soTimeout;
     }
 
     /**
-     * Defines the default socket timeout value for non-blocking I/O operations.
-     * <p/>
-     * Default: <code>0</code> (no timeout)
-     *
-     * @see SocketOptions#SO_TIMEOUT
+     * @deprecated (4.3) use {@link Builder#setSoTimeout(int)}
      */
-    public void setSoTimeout(int soTimeout) {
+    @Deprecated
+    public void setSoTimeout(final int soTimeout) {
         this.soTimeout = soTimeout;
     }
 
     /**
-     * Determines the default value of the {@link SocketOptions#SO_REUSEADDR} parameter
+     * Determines the default value of the {@link java.net.SocketOptions#SO_REUSEADDR} parameter
      * for newly created sockets.
      * <p/>
      * Default: <code>false</code>
      *
-     * @see SocketOptions#SO_REUSEADDR
+     * @see java.net.SocketOptions#SO_REUSEADDR
      */
     public boolean isSoReuseAddress() {
         return soReuseAddress;
     }
 
     /**
-     * Defines the default value of the {@link SocketOptions#SO_REUSEADDR} parameter
-     * for newly created sockets.
-     *
-     * @see SocketOptions#SO_REUSEADDR
+     * @deprecated (4.3) use {@link Builder#setSoReuseAddress(boolean)}
      */
-    public void setSoReuseAddress(boolean soReuseAddress) {
+    @Deprecated
+    public void setSoReuseAddress(final boolean soReuseAddress) {
         this.soReuseAddress = soReuseAddress;
     }
 
     /**
-     * Determines the default value of the {@link SocketOptions#SO_LINGER} parameter
+     * Determines the default value of the {@link java.net.SocketOptions#SO_LINGER} parameter
      * for newly created sockets.
      * <p/>
      * Default: <code>-1</code>
      *
-     * @see SocketOptions#SO_LINGER
+     * @see java.net.SocketOptions#SO_LINGER
      */
     public int getSoLinger() {
         return soLinger;
     }
 
     /**
-     * Defines the default value of the {@link SocketOptions#SO_LINGER} parameter
-     * for newly created sockets.
-     *
-     * @see SocketOptions#SO_LINGER
+     * @deprecated (4.3) use {@link Builder#setSoLinger(int)}
      */
-    public void setSoLinger(int soLinger) {
+    @Deprecated
+    public void setSoLinger(final int soLinger) {
         this.soLinger = soLinger;
     }
 
     /**
-     * Determines the default value of the {@link SocketOptions#SO_KEEPALIVE} parameter
+     * Determines the default value of the {@link java.net.SocketOptions#SO_KEEPALIVE} parameter
      * for newly created sockets.
      * <p/>
      * Default: <code>-1</code>
      *
-     * @see SocketOptions#SO_KEEPALIVE
+     * @see java.net.SocketOptions#SO_KEEPALIVE
      */
     public boolean isSoKeepalive() {
         return this.soKeepAlive;
     }
 
     /**
-     * Defines the default value of the {@link SocketOptions#SO_KEEPALIVE} parameter
-     * for newly created sockets.
-     * <p/>
-     * Default: <code>-1</code>
-     *
-     * @see SocketOptions#SO_KEEPALIVE
+     * @deprecated (4.3) use {@link Builder#setSoKeepAlive(boolean)}
      */
-    public void setSoKeepalive(boolean soKeepAlive) {
+    @Deprecated
+    public void setSoKeepalive(final boolean soKeepAlive) {
         this.soKeepAlive = soKeepAlive;
     }
 
     /**
-     * Determines the default value of the {@link SocketOptions#TCP_NODELAY} parameter
+     * Determines the default value of the {@link java.net.SocketOptions#TCP_NODELAY} parameter
      * for newly created sockets.
      * <p/>
      * Default: <code>false</code>
      *
-     * @see SocketOptions#TCP_NODELAY
+     * @see java.net.SocketOptions#TCP_NODELAY
      */
     public boolean isTcpNoDelay() {
         return tcpNoDelay;
     }
 
     /**
-     * Defines the default value of the {@link SocketOptions#TCP_NODELAY} parameter
-     * for newly created sockets.
-     *
-     * @see SocketOptions#TCP_NODELAY
+     * @deprecated (4.3) use {@link Builder#setTcpNoDelay(boolean)}
      */
-    public void setTcpNoDelay(boolean tcpNoDelay) {
+    @Deprecated
+    public void setTcpNoDelay(final boolean tcpNoDelay) {
         this.tcpNoDelay = tcpNoDelay;
     }
 
@@ -281,53 +289,50 @@ public final class IOReactorConfig implements Cloneable {
     }
 
     /**
-     * Defines the default connect timeout value for non-blocking connection requests.
+     * @deprecated (4.3) use {@link Builder#setConnectTimeout(int)}
      */
-    public void setConnectTimeout(int connectTimeout) {
+    @Deprecated
+    public void setConnectTimeout(final int connectTimeout) {
         this.connectTimeout = connectTimeout;
     }
 
     /**
-     * Determines the default value of the {@link SocketOptions#SO_SNDBUF} parameter
+     * Determines the default value of the {@link java.net.SocketOptions#SO_SNDBUF} parameter
      * for newly created sockets.
      * <p/>
      * Default: <code>0</code> (system default)
      *
-     * @see SocketOptions#SO_SNDBUF
+     * @see java.net.SocketOptions#SO_SNDBUF
      */
     public int getSndBufSize() {
         return sndBufSize;
     }
 
     /**
-     * Defines the default value of the {@link SocketOptions#SO_SNDBUF} parameter
-     * for newly created sockets.
-     *
-     * @see SocketOptions#SO_SNDBUF
+     * @deprecated (4.3) use {@link Builder#setSndBufSize(int)}
      */
-    public void setSndBufSize(int sndBufSize) {
+    @Deprecated
+    public void setSndBufSize(final int sndBufSize) {
         this.sndBufSize = sndBufSize;
     }
 
     /**
-     * Determines the default value of the {@link SocketOptions#SO_RCVBUF} parameter
+     * Determines the default value of the {@link java.net.SocketOptions#SO_RCVBUF} parameter
      * for newly created sockets.
      * <p/>
      * Default: <code>0</code> (system default)
      *
-     * @see SocketOptions#SO_RCVBUF
+     * @see java.net.SocketOptions#SO_RCVBUF
      */
     public int getRcvBufSize() {
         return rcvBufSize;
     }
 
     /**
-     * Defines the default value of the {@link SocketOptions#SO_RCVBUF} parameter
-     * for newly created sockets.
-     *
-     * @see SocketOptions#SO_RCVBUF
+     * @deprecated (4.3) use {@link Builder#setRcvBufSize(int)}
      */
-    public void setRcvBufSize(int rcvBufSize) {
+    @Deprecated
+    public void setRcvBufSize(final int rcvBufSize) {
         this.rcvBufSize = rcvBufSize;
     }
 
@@ -336,9 +341,127 @@ public final class IOReactorConfig implements Cloneable {
         return (IOReactorConfig) super.clone();
     }
 
+    public static Builder custom() {
+        return new Builder();
+    }
+
+    public static Builder copy(final IOReactorConfig config) {
+        Args.notNull(config, "I/O reactor config");
+        return new Builder()
+            .setSelectInterval(config.getSelectInterval())
+            .setShutdownGracePeriod(config.getShutdownGracePeriod())
+            .setInterestOpQueued(config.isInterestOpQueued())
+            .setIoThreadCount(config.getIoThreadCount())
+            .setSoTimeout(config.getSoTimeout())
+            .setSoReuseAddress(config.isSoReuseAddress())
+            .setSoLinger(config.getSoLinger())
+            .setSoKeepAlive(config.isSoKeepalive())
+            .setTcpNoDelay(config.isTcpNoDelay())
+            .setConnectTimeout(config.getConnectTimeout());
+    }
+
+    public static class Builder {
+
+        private long selectInterval;
+        private long shutdownGracePeriod;
+        private boolean interestOpQueued;
+        private int ioThreadCount;
+        private int soTimeout;
+        private boolean soReuseAddress;
+        private int soLinger;
+        private boolean soKeepAlive;
+        private boolean tcpNoDelay;
+        private int connectTimeout;
+        private int sndBufSize;
+        private int rcvBufSize;
+
+        Builder() {
+            this.selectInterval = 1000;
+            this.shutdownGracePeriod = 500;
+            this.interestOpQueued = false;
+            this.ioThreadCount = AVAIL_PROCS;
+            this.soTimeout = 0;
+            this.soReuseAddress = false;
+            this.soLinger = -1;
+            this.soKeepAlive = false;
+            this.tcpNoDelay = true;
+            this.connectTimeout = 0;
+            this.sndBufSize = 0;
+            this.rcvBufSize = 0;
+        }
+
+        public Builder setSelectInterval(final long selectInterval) {
+            this.selectInterval = selectInterval;
+            return this;
+        }
+
+        public Builder setShutdownGracePeriod(final long shutdownGracePeriod) {
+            this.shutdownGracePeriod = shutdownGracePeriod;
+            return this;
+        }
+
+        public Builder setInterestOpQueued(final boolean interestOpQueued) {
+            this.interestOpQueued = interestOpQueued;
+            return this;
+        }
+
+        public Builder setIoThreadCount(final int ioThreadCount) {
+            this.ioThreadCount = ioThreadCount;
+            return this;
+        }
+
+        public Builder setSoTimeout(final int soTimeout) {
+            this.soTimeout = soTimeout;
+            return this;
+        }
+
+        public Builder setSoReuseAddress(final boolean soReuseAddress) {
+            this.soReuseAddress = soReuseAddress;
+            return this;
+        }
+
+        public Builder setSoLinger(final int soLinger) {
+            this.soLinger = soLinger;
+            return this;
+        }
+
+        public Builder setSoKeepAlive(final boolean soKeepAlive) {
+            this.soKeepAlive = soKeepAlive;
+            return this;
+        }
+
+        public Builder setTcpNoDelay(final boolean tcpNoDelay) {
+            this.tcpNoDelay = tcpNoDelay;
+            return this;
+        }
+
+        public Builder setConnectTimeout(final int connectTimeout) {
+            this.connectTimeout = connectTimeout;
+            return this;
+        }
+
+        public Builder setSndBufSize(final int sndBufSize) {
+            this.sndBufSize = sndBufSize;
+            return this;
+        }
+
+        public Builder setRcvBufSize(final int rcvBufSize) {
+            this.rcvBufSize = rcvBufSize;
+            return this;
+        }
+
+        public IOReactorConfig build() {
+            return new IOReactorConfig(
+                    selectInterval, shutdownGracePeriod, interestOpQueued, ioThreadCount,
+                    soTimeout, soReuseAddress, soLinger, soKeepAlive, tcpNoDelay,
+                    connectTimeout, sndBufSize, rcvBufSize);
+        }
+
+    }
+
     @Override
     public String toString() {
-        StringBuilder builder = new StringBuilder();
+        final StringBuilder builder = new StringBuilder();
         builder.append("[selectInterval=").append(this.selectInterval)
                 .append(", shutdownGracePeriod=").append(this.shutdownGracePeriod)
                 .append(", interestOpQueued=").append(this.interestOpQueued)
diff --git a/httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/IOSessionImpl.java b/httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/IOSessionImpl.java
index 764eb37..1921275 100644
--- a/httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/IOSessionImpl.java
+++ b/httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/IOSessionImpl.java
@@ -43,6 +43,7 @@ import org.apache.http.annotation.ThreadSafe;
 import org.apache.http.nio.reactor.IOSession;
 import org.apache.http.nio.reactor.SessionBufferStatus;
 import org.apache.http.nio.reactor.SocketAccessor;
+import org.apache.http.util.Args;
 
 /**
  * Default implementation of {@link IOSession}.
@@ -83,9 +84,7 @@ public class IOSessionImpl implements IOSession, SocketAccessor {
             final InterestOpsCallback interestOpsCallback,
             final SessionClosedCallback sessionClosedCallback) {
         super();
-        if (key == null) {
-            throw new IllegalArgumentException("Selection key may not be null");
-        }
+        Args.notNull(key, "Selection key");
         this.key = key;
         this.channel = (ByteChannel) this.key.channel();
         this.interestOpsCallback = interestOpsCallback;
@@ -94,7 +93,7 @@ public class IOSessionImpl implements IOSession, SocketAccessor {
         this.currentEventMask = key.interestOps();
         this.socketTimeout = 0;
         this.status = ACTIVE;
-        long now = System.currentTimeMillis();
+        final long now = System.currentTimeMillis();
         this.startedTime = now;
         this.lastReadTime = now;
         this.lastWriteTime = now;
@@ -118,7 +117,7 @@ public class IOSessionImpl implements IOSession, SocketAccessor {
     }
 
     public SocketAddress getLocalAddress() {
-        Channel channel = this.channel;
+        final Channel channel = this.channel;
         if (channel instanceof SocketChannel) {
             return ((SocketChannel)channel).socket().getLocalSocketAddress();
         } else {
@@ -127,7 +126,7 @@ public class IOSessionImpl implements IOSession, SocketAccessor {
     }
 
     public SocketAddress getRemoteAddress() {
-        Channel channel = this.channel;
+        final Channel channel = this.channel;
         if (channel instanceof SocketChannel) {
             return ((SocketChannel)channel).socket().getRemoteSocketAddress();
         } else {
@@ -139,7 +138,7 @@ public class IOSessionImpl implements IOSession, SocketAccessor {
         return this.interestOpsCallback != null ? this.currentEventMask : this.key.interestOps();
     }
 
-    public synchronized void setEventMask(int ops) {
+    public synchronized void setEventMask(final int ops) {
         if (this.status == CLOSED) {
             return;
         }
@@ -148,7 +147,7 @@ public class IOSessionImpl implements IOSession, SocketAccessor {
             this.currentEventMask = ops;
 
             // local variable
-            InterestOpEntry entry = new InterestOpEntry(this.key, this.currentEventMask);
+            final InterestOpEntry entry = new InterestOpEntry(this.key, this.currentEventMask);
 
             // add this operation to the interestOps() queue
             this.interestOpsCallback.addInterestOps(entry);
@@ -158,7 +157,7 @@ public class IOSessionImpl implements IOSession, SocketAccessor {
         this.key.selector().wakeup();
     }
 
-    public synchronized void setEvent(int op) {
+    public synchronized void setEvent(final int op) {
         if (this.status == CLOSED) {
             return;
         }
@@ -167,18 +166,18 @@ public class IOSessionImpl implements IOSession, SocketAccessor {
             this.currentEventMask |= op;
 
             // local variable
-            InterestOpEntry entry = new InterestOpEntry(this.key, this.currentEventMask);
+            final InterestOpEntry entry = new InterestOpEntry(this.key, this.currentEventMask);
 
             // add this operation to the interestOps() queue
             this.interestOpsCallback.addInterestOps(entry);
         } else {
-            int ops = this.key.interestOps();
+            final int ops = this.key.interestOps();
             this.key.interestOps(ops | op);
         }
         this.key.selector().wakeup();
     }
 
-    public synchronized void clearEvent(int op) {
+    public synchronized void clearEvent(final int op) {
         if (this.status == CLOSED) {
             return;
         }
@@ -187,12 +186,12 @@ public class IOSessionImpl implements IOSession, SocketAccessor {
             this.currentEventMask &= ~op;
 
             // local variable
-            InterestOpEntry entry = new InterestOpEntry(this.key, this.currentEventMask);
+            final InterestOpEntry entry = new InterestOpEntry(this.key, this.currentEventMask);
 
             // add this operation to the interestOps() queue
             this.interestOpsCallback.addInterestOps(entry);
         } else {
-            int ops = this.key.interestOps();
+            final int ops = this.key.interestOps();
             this.key.interestOps(ops & ~op);
         }
         this.key.selector().wakeup();
@@ -202,7 +201,7 @@ public class IOSessionImpl implements IOSession, SocketAccessor {
         return this.socketTimeout;
     }
 
-    public synchronized void setSocketTimeout(int timeout) {
+    public synchronized void setSocketTimeout(final int timeout) {
         this.socketTimeout = timeout;
         this.lastAccessTime = System.currentTimeMillis();
     }
@@ -215,7 +214,7 @@ public class IOSessionImpl implements IOSession, SocketAccessor {
         this.key.cancel();
         try {
             this.key.channel().close();
-        } catch (IOException ex) {
+        } catch (final IOException ex) {
             // Munching exceptions is not nice
             // but in this case it is justified
         }
@@ -242,12 +241,12 @@ public class IOSessionImpl implements IOSession, SocketAccessor {
     }
 
     public boolean hasBufferedInput() {
-        SessionBufferStatus bufferStatus = this.bufferStatus;
+        final SessionBufferStatus bufferStatus = this.bufferStatus;
         return bufferStatus != null && bufferStatus.hasBufferedInput();
     }
 
     public boolean hasBufferedOutput() {
-        SessionBufferStatus bufferStatus = this.bufferStatus;
+        final SessionBufferStatus bufferStatus = this.bufferStatus;
         return bufferStatus != null && bufferStatus.hasBufferedOutput();
     }
 
@@ -284,18 +283,18 @@ public class IOSessionImpl implements IOSession, SocketAccessor {
     }
 
     synchronized void resetLastRead() {
-        long now = System.currentTimeMillis();
+        final long now = System.currentTimeMillis();
         this.lastReadTime = now;
         this.lastAccessTime = now;
     }
 
     synchronized void resetLastWrite() {
-        long now = System.currentTimeMillis();
+        final long now = System.currentTimeMillis();
         this.lastWriteTime = now;
         this.lastAccessTime = now;
     }
 
-    private static void formatOps(final StringBuilder buffer, int ops) {
+    private static void formatOps(final StringBuilder buffer, final int ops) {
         if ((ops & SelectionKey.OP_READ) > 0) {
             buffer.append('r');
         }
@@ -312,7 +311,7 @@ public class IOSessionImpl implements IOSession, SocketAccessor {
 
     private static void formatAddress(final StringBuilder buffer, final SocketAddress socketAddress) {
         if (socketAddress instanceof InetSocketAddress) {
-            InetSocketAddress addr = ((InetSocketAddress) socketAddress);
+            final InetSocketAddress addr = ((InetSocketAddress) socketAddress);
             buffer.append(addr.getAddress() != null ? addr.getAddress().getHostAddress() :
                 addr.getAddress())
             .append(':')
@@ -324,9 +323,9 @@ public class IOSessionImpl implements IOSession, SocketAccessor {
 
     @Override
     public synchronized String toString() {
-        StringBuilder buffer = new StringBuilder();
-        SocketAddress remoteAddress = getRemoteAddress();
-        SocketAddress localAddress = getLocalAddress();
+        final StringBuilder buffer = new StringBuilder();
+        final SocketAddress remoteAddress = getRemoteAddress();
+        final SocketAddress localAddress = getLocalAddress();
         if (remoteAddress != null && localAddress != null) {
             formatAddress(buffer, localAddress);
             buffer.append("<->");
@@ -354,9 +353,9 @@ public class IOSessionImpl implements IOSession, SocketAccessor {
         buffer.append("]");
         return buffer.toString();
     }
-    
+
     public Socket getSocket() {
-        Channel channel = this.channel;
+        final Channel channel = this.channel;
         if (channel instanceof SocketChannel) {
             return ((SocketChannel) channel).socket();
         } else {
diff --git a/httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/InterestOpEntry.java b/httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/InterestOpEntry.java
index e8bb30e..d41682a 100644
--- a/httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/InterestOpEntry.java
+++ b/httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/InterestOpEntry.java
@@ -29,6 +29,8 @@ package org.apache.http.impl.nio.reactor;
 
 import java.nio.channels.SelectionKey;
 
+import org.apache.http.util.Args;
+
 /**
  * Helper class, representing an entry on an {@link java.nio.channels.SelectionKey#interestOps(int)
  * interestOps(int)} queue.
@@ -40,11 +42,9 @@ class InterestOpEntry {
     private final SelectionKey key;
     private final int eventMask;
 
-    public InterestOpEntry(final SelectionKey key, int eventMask) {
+    public InterestOpEntry(final SelectionKey key, final int eventMask) {
         super();
-        if (key == null) {
-            throw new IllegalArgumentException("Selection key may not be null");
-        }
+        Args.notNull(key, "Selection key");
         this.key = key;
         this.eventMask = eventMask;
     }
@@ -58,8 +58,16 @@ class InterestOpEntry {
     }
 
     @Override
-    public boolean equals(Object obj) {
-        return this.key.equals(obj);
+    public boolean equals(final Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof InterestOpEntry) {
+            final InterestOpEntry that = (InterestOpEntry) obj;
+            return this.key.equals(that.key);
+        } else {
+            return false;
+        }
     }
 
     @Override
diff --git a/httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/ListenerEndpointImpl.java b/httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/ListenerEndpointImpl.java
index 3760790..9dc4151 100644
--- a/httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/ListenerEndpointImpl.java
+++ b/httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/ListenerEndpointImpl.java
@@ -34,6 +34,7 @@ import java.nio.channels.SelectionKey;
 
 import org.apache.http.annotation.ThreadSafe;
 import org.apache.http.nio.reactor.ListenerEndpoint;
+import org.apache.http.util.Args;
 
 /**
  * Default implementation of {@link ListenerEndpoint}.
@@ -55,9 +56,7 @@ public class ListenerEndpointImpl implements ListenerEndpoint {
             final SocketAddress address,
             final ListenerEndpointClosedCallback callback) {
         super();
-        if (address == null) {
-            throw new IllegalArgumentException("Address may not be null");
-        }
+        Args.notNull(address, "Address");
         this.address = address;
         this.callback = callback;
     }
@@ -86,9 +85,7 @@ public class ListenerEndpointImpl implements ListenerEndpoint {
     }
 
     public void completed(final SocketAddress address) {
-        if (address == null) {
-            throw new IllegalArgumentException("Address may not be null");
-        }
+        Args.notNull(address, "Address");
         if (this.completed) {
             return;
         }
@@ -140,11 +137,11 @@ public class ListenerEndpointImpl implements ListenerEndpoint {
         this.closed = true;
         if (this.key != null) {
             this.key.cancel();
-            Channel channel = this.key.channel();
+            final Channel channel = this.key.channel();
             if (channel.isOpen()) {
                 try {
                     channel.close();
-                } catch (IOException ignore) {}
+                } catch (final IOException ignore) {}
             }
         }
         if (this.callback != null) {
diff --git a/httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/SessionInputBufferImpl.java b/httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/SessionInputBufferImpl.java
index 12f01d8..20ff179 100644
--- a/httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/SessionInputBufferImpl.java
+++ b/httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/SessionInputBufferImpl.java
@@ -36,66 +36,132 @@ import java.nio.charset.CharacterCodingException;
 import java.nio.charset.Charset;
 import java.nio.charset.CharsetDecoder;
 import java.nio.charset.CoderResult;
+import java.nio.charset.CodingErrorAction;
 
 import org.apache.http.annotation.NotThreadSafe;
 import org.apache.http.nio.reactor.SessionInputBuffer;
 import org.apache.http.nio.util.ByteBufferAllocator;
 import org.apache.http.nio.util.ExpandableBuffer;
 import org.apache.http.nio.util.HeapByteBufferAllocator;
+import org.apache.http.params.CoreProtocolPNames;
 import org.apache.http.params.HttpParams;
-import org.apache.http.params.HttpProtocolParams;
 import org.apache.http.protocol.HTTP;
+import org.apache.http.util.Args;
 import org.apache.http.util.CharArrayBuffer;
+import org.apache.http.util.CharsetUtils;
 
 /**
  * Default implementation of {@link SessionInputBuffer} based on
  * the {@link ExpandableBuffer} class.
- * <p>
- * The following parameters can be used to customize the behavior of this
- * class:
- * <ul>
- *  <li>{@link org.apache.http.params.CoreProtocolPNames#HTTP_ELEMENT_CHARSET}</li>
- * </ul>
  *
  * @since 4.0
  */
+ at SuppressWarnings("deprecation")
 @NotThreadSafe
 public class SessionInputBufferImpl extends ExpandableBuffer implements SessionInputBuffer {
 
-    private CharBuffer charbuffer = null;
-    private Charset charset = null;
-    private CharsetDecoder chardecoder = null;
+    private final CharsetDecoder chardecoder;
+    private final int lineBuffersize;
 
+    private CharBuffer charbuffer;
+
+    /**
+     *  Creates SessionInputBufferImpl instance.
+     *
+     * @param buffersize input buffer size
+     * @param lineBuffersize buffer size for line operations. Has effect only if
+     *   <code>chardecoder</code> is not <code>null</code>.
+     * @param chardecoder chardecoder to be used for decoding HTTP protocol elements.
+     *   If <code>null</code> simple type cast will be used for byte to char conversion.
+     * @param allocator memory allocator.
+     *   If <code>null</code> {@link HeapByteBufferAllocator#INSTANCE} will be used.
+     *
+     * @since 4.3
+     */
+    public SessionInputBufferImpl(
+            final int buffersize,
+            final int lineBuffersize,
+            final CharsetDecoder chardecoder,
+            final ByteBufferAllocator allocator) {
+        super(buffersize, allocator != null ? allocator : HeapByteBufferAllocator.INSTANCE);
+        this.lineBuffersize = Args.positive(lineBuffersize, "Line buffer size");
+        this.chardecoder = chardecoder;
+    }
+
+    /**
+     * @deprecated (4.3) use
+     *   {@link SessionInputBufferImpl#SessionInputBufferImpl(int, int, CharsetDecoder,
+     *     ByteBufferAllocator)}
+     */
+    @Deprecated
     public SessionInputBufferImpl(
-            int buffersize,
-            int linebuffersize,
+            final int buffersize,
+            final int lineBuffersize,
             final ByteBufferAllocator allocator,
             final HttpParams params) {
         super(buffersize, allocator);
-        this.charbuffer = CharBuffer.allocate(linebuffersize);
-        this.charset = Charset.forName(HttpProtocolParams.getHttpElementCharset(params));
-        this.chardecoder = this.charset.newDecoder();
-        this.chardecoder.onMalformedInput(HttpProtocolParams.getMalformedInputAction(params));
-        this.chardecoder.onUnmappableCharacter(HttpProtocolParams.getUnmappableInputAction(params));
+        this.lineBuffersize = Args.positive(lineBuffersize, "Line buffer size");
+        final String charsetName = (String) params.getParameter(CoreProtocolPNames.HTTP_ELEMENT_CHARSET);
+        final Charset charset = CharsetUtils.lookup(charsetName);
+        if (charset != null) {
+            this.chardecoder = charset.newDecoder();
+            final CodingErrorAction a1 = (CodingErrorAction) params.getParameter(
+                    CoreProtocolPNames.HTTP_MALFORMED_INPUT_ACTION);
+            this.chardecoder.onMalformedInput(a1 != null ? a1 : CodingErrorAction.REPORT);
+            final CodingErrorAction a2 = (CodingErrorAction) params.getParameter(
+                    CoreProtocolPNames.HTTP_UNMAPPABLE_INPUT_ACTION);
+            this.chardecoder.onUnmappableCharacter(a2 != null? a2 : CodingErrorAction.REPORT);
+        } else {
+            this.chardecoder = null;
+        }
     }
 
+    /**
+     * @deprecated (4.3) use
+     *   {@link SessionInputBufferImpl#SessionInputBufferImpl(int, int, Charset)}
+     */
+    @Deprecated
     public SessionInputBufferImpl(
-            int buffersize,
-            int linebuffersize,
+            final int buffersize,
+            final int linebuffersize,
             final HttpParams params) {
-        this(buffersize, linebuffersize, new HeapByteBufferAllocator(), params);
+        this(buffersize, linebuffersize, HeapByteBufferAllocator.INSTANCE, params);
+    }
+
+    /**
+     * @since 4.3
+     */
+    public SessionInputBufferImpl(
+            final int buffersize,
+            final int lineBuffersize,
+            final Charset charset) {
+        this(buffersize, lineBuffersize,
+                charset != null ? charset.newDecoder() : null, HeapByteBufferAllocator.INSTANCE);
+    }
+
+    /**
+     * @since 4.3
+     */
+    public SessionInputBufferImpl(
+            final int buffersize,
+            final int lineBuffersize) {
+        this(buffersize, lineBuffersize, null, HeapByteBufferAllocator.INSTANCE);
+    }
+
+    /**
+     * @since 4.3
+     */
+    public SessionInputBufferImpl(final int buffersize) {
+        this(buffersize, 256, null, HeapByteBufferAllocator.INSTANCE);
     }
 
     public int fill(final ReadableByteChannel channel) throws IOException {
-        if (channel == null) {
-            throw new IllegalArgumentException("Channel may not be null");
-        }
+        Args.notNull(channel, "Channel");
         setInputMode();
         if (!this.buffer.hasRemaining()) {
             expand();
         }
-        int readNo = channel.read(this.buffer);
-        return readNo;
+        return channel.read(this.buffer);
     }
 
     public int read() {
@@ -103,15 +169,22 @@ public class SessionInputBufferImpl extends ExpandableBuffer implements SessionI
         return this.buffer.get() & 0xff;
     }
 
-    public int read(final ByteBuffer dst, int maxLen) {
+    public int read(final ByteBuffer dst, final int maxLen) {
         if (dst == null) {
             return 0;
         }
         setOutputMode();
-        int len = Math.min(dst.remaining(), maxLen);
-        int chunk = Math.min(this.buffer.remaining(), len);
-        for (int i = 0; i < chunk; i++) {
-            dst.put(this.buffer.get());
+        final int len = Math.min(dst.remaining(), maxLen);
+        final int chunk = Math.min(this.buffer.remaining(), len);
+        if (this.buffer.remaining() > chunk) {
+            final int oldLimit = this.buffer.limit();
+            final int newLimit = this.buffer.position() + chunk;
+            this.buffer.limit(newLimit);
+            dst.put(this.buffer);
+            this.buffer.limit(oldLimit);
+            return len;
+        } else {
+            dst.put(this.buffer);
         }
         return chunk;
     }
@@ -123,15 +196,15 @@ public class SessionInputBufferImpl extends ExpandableBuffer implements SessionI
         return read(dst, dst.remaining());
     }
 
-    public int read(final WritableByteChannel dst, int maxLen) throws IOException {
+    public int read(final WritableByteChannel dst, final int maxLen) throws IOException {
         if (dst == null) {
             return 0;
         }
         setOutputMode();
-        int bytesRead;
+        final int bytesRead;
         if (this.buffer.remaining() > maxLen) {
-            int oldLimit = this.buffer.limit();
-            int newLimit = oldLimit - (this.buffer.remaining() - maxLen);
+            final int oldLimit = this.buffer.limit();
+            final int newLimit = oldLimit - (this.buffer.remaining() - maxLen);
             this.buffer.limit(newLimit);
             bytesRead = dst.write(this.buffer);
             this.buffer.limit(oldLimit);
@@ -151,14 +224,14 @@ public class SessionInputBufferImpl extends ExpandableBuffer implements SessionI
 
     public boolean readLine(
             final CharArrayBuffer linebuffer,
-            boolean endOfStream) throws CharacterCodingException {
+            final boolean endOfStream) throws CharacterCodingException {
 
         setOutputMode();
         // See if there is LF char present in the buffer
         int pos = -1;
         boolean hasLine = false;
         for (int i = this.buffer.position(); i < this.buffer.limit(); i++) {
-            int b = this.buffer.get(i);
+            final int b = this.buffer.get(i);
             if (b == HTTP.LF) {
                 hasLine = true;
                 pos = i + 1;
@@ -175,47 +248,65 @@ public class SessionInputBufferImpl extends ExpandableBuffer implements SessionI
                 return false;
             }
         }
-        int origLimit = this.buffer.limit();
+        final int origLimit = this.buffer.limit();
         this.buffer.limit(pos);
 
-        int len = this.buffer.limit() - this.buffer.position();
+        final int requiredCapacity = this.buffer.limit() - this.buffer.position();
         // Ensure capacity of len assuming ASCII as the most likely charset
-        linebuffer.ensureCapacity(len);
+        linebuffer.ensureCapacity(requiredCapacity);
 
-        this.chardecoder.reset();
+        if (this.chardecoder == null) {
+            if (this.buffer.hasArray()) {
+                final byte[] b = this.buffer.array();
+                final int off = this.buffer.position();
+                final int len = this.buffer.remaining();
+                linebuffer.append(b, off, len);
+                this.buffer.position(off + len);
+            } else {
+                while (this.buffer.hasRemaining()) {
+                    linebuffer.append((char) (this.buffer.get() & 0xff));
+                }
+            }
+        } else {
+            if (this.charbuffer == null) {
+                this.charbuffer = CharBuffer.allocate(this.lineBuffersize);
+            }
+            this.chardecoder.reset();
 
-        for (;;) {
-            CoderResult result = this.chardecoder.decode(
-                    this.buffer,
-                    this.charbuffer,
-                    true);
-            if (result.isError()) {
-                result.throwException();
+            for (;;) {
+                final CoderResult result = this.chardecoder.decode(
+                        this.buffer,
+                        this.charbuffer,
+                        true);
+                if (result.isError()) {
+                    result.throwException();
+                }
+                if (result.isOverflow()) {
+                    this.charbuffer.flip();
+                    linebuffer.append(
+                            this.charbuffer.array(),
+                            this.charbuffer.position(),
+                            this.charbuffer.remaining());
+                    this.charbuffer.clear();
+                }
+                if (result.isUnderflow()) {
+                    break;
+                }
             }
-            if (result.isOverflow()) {
-                this.charbuffer.flip();
+
+            // flush the decoder
+            this.chardecoder.flush(this.charbuffer);
+            this.charbuffer.flip();
+            // append the decoded content to the line buffer
+            if (this.charbuffer.hasRemaining()) {
                 linebuffer.append(
                         this.charbuffer.array(),
                         this.charbuffer.position(),
                         this.charbuffer.remaining());
-                this.charbuffer.clear();
-            }
-            if (result.isUnderflow()) {
-                break;
             }
-        }
-        this.buffer.limit(origLimit);
 
-        // flush the decoder
-        this.chardecoder.flush(this.charbuffer);
-        this.charbuffer.flip();
-        // append the decoded content to the line buffer
-        if (this.charbuffer.hasRemaining()) {
-            linebuffer.append(
-                    this.charbuffer.array(),
-                    this.charbuffer.position(),
-                    this.charbuffer.remaining());
         }
+        this.buffer.limit(origLimit);
 
         // discard LF if found
         int l = linebuffer.length();
@@ -235,9 +326,9 @@ public class SessionInputBufferImpl extends ExpandableBuffer implements SessionI
         return true;
     }
 
-    public String readLine(boolean endOfStream) throws CharacterCodingException {
-        CharArrayBuffer charbuffer = new CharArrayBuffer(64);
-        boolean found = readLine(charbuffer, endOfStream);
+    public String readLine(final boolean endOfStream) throws CharacterCodingException {
+        final CharArrayBuffer charbuffer = new CharArrayBuffer(64);
+        final boolean found = readLine(charbuffer, endOfStream);
         if (found) {
             return charbuffer.toString();
         } else {
diff --git a/httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/SessionOutputBufferImpl.java b/httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/SessionOutputBufferImpl.java
index 1786131..84e2760 100644
--- a/httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/SessionOutputBufferImpl.java
+++ b/httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/SessionOutputBufferImpl.java
@@ -36,56 +36,125 @@ import java.nio.charset.CharacterCodingException;
 import java.nio.charset.Charset;
 import java.nio.charset.CharsetEncoder;
 import java.nio.charset.CoderResult;
+import java.nio.charset.CodingErrorAction;
 
 import org.apache.http.annotation.NotThreadSafe;
 import org.apache.http.nio.reactor.SessionOutputBuffer;
 import org.apache.http.nio.util.ByteBufferAllocator;
 import org.apache.http.nio.util.ExpandableBuffer;
 import org.apache.http.nio.util.HeapByteBufferAllocator;
+import org.apache.http.params.CoreProtocolPNames;
 import org.apache.http.params.HttpParams;
-import org.apache.http.params.HttpProtocolParams;
 import org.apache.http.protocol.HTTP;
+import org.apache.http.util.Args;
 import org.apache.http.util.CharArrayBuffer;
+import org.apache.http.util.CharsetUtils;
 
 /**
  * Default implementation of {@link SessionOutputBuffer} based on
  * the {@link ExpandableBuffer} class.
- * <p>
- * The following parameters can be used to customize the behavior of this
- * class:
- * <ul>
- *  <li>{@link org.apache.http.params.CoreProtocolPNames#HTTP_ELEMENT_CHARSET}</li>
- * </ul>
  *
  * @since 4.0
  */
+ at SuppressWarnings("deprecation")
 @NotThreadSafe
 public class SessionOutputBufferImpl extends ExpandableBuffer implements SessionOutputBuffer {
 
     private static final byte[] CRLF = new byte[] {HTTP.CR, HTTP.LF};
 
-    private CharBuffer charbuffer = null;
-    private Charset charset = null;
-    private CharsetEncoder charencoder = null;
+    private final CharsetEncoder charencoder;
+    private final int lineBuffersize;
 
+    private CharBuffer charbuffer;
+
+    /**
+     *  Creates SessionOutputBufferImpl instance.
+     *
+     * @param buffersize input buffer size
+     * @param lineBuffersize buffer size for line operations. Has effect only if
+     *   <code>charencoder</code> is not <code>null</code>.
+     * @param charencoder charencoder to be used for encoding HTTP protocol elements.
+     *   If <code>null</code> simple type cast will be used for char to byte conversion.
+     * @param allocator memory allocator.
+     *   If <code>null</code> {@link HeapByteBufferAllocator#INSTANCE} will be used.
+     *
+     * @since 4.3
+     */
+    public SessionOutputBufferImpl(
+            final int buffersize,
+            final int lineBuffersize,
+            final CharsetEncoder charencoder,
+            final ByteBufferAllocator allocator) {
+        super(buffersize, allocator != null ? allocator : HeapByteBufferAllocator.INSTANCE);
+        this.lineBuffersize = Args.positive(lineBuffersize, "Line buffer size");
+        this.charencoder = charencoder;
+    }
+
+    /**
+     * @deprecated (4.3) use
+     *   {@link SessionOutputBufferImpl#SessionOutputBufferImpl(int, int, CharsetEncoder,
+     *     ByteBufferAllocator)}
+     */
+    @Deprecated
     public SessionOutputBufferImpl(
-            int buffersize,
-            int linebuffersize,
+            final int buffersize,
+            final int lineBuffersize,
             final ByteBufferAllocator allocator,
             final HttpParams params) {
         super(buffersize, allocator);
-        this.charbuffer = CharBuffer.allocate(linebuffersize);
-        this.charset = Charset.forName(HttpProtocolParams.getHttpElementCharset(params));
-        this.charencoder = this.charset.newEncoder();
-        this.charencoder.onMalformedInput(HttpProtocolParams.getMalformedInputAction(params));
-        this.charencoder.onUnmappableCharacter(HttpProtocolParams.getUnmappableInputAction(params));
+        this.lineBuffersize = Args.positive(lineBuffersize, "Line buffer size");
+        final String charsetName = (String) params.getParameter(CoreProtocolPNames.HTTP_ELEMENT_CHARSET);
+        final Charset charset = CharsetUtils.lookup(charsetName);
+        if (charset != null) {
+            this.charencoder = charset.newEncoder();
+            final CodingErrorAction a1 = (CodingErrorAction) params.getParameter(
+                    CoreProtocolPNames.HTTP_MALFORMED_INPUT_ACTION);
+            this.charencoder.onMalformedInput(a1 != null ? a1 : CodingErrorAction.REPORT);
+            final CodingErrorAction a2 = (CodingErrorAction) params.getParameter(
+                    CoreProtocolPNames.HTTP_UNMAPPABLE_INPUT_ACTION);
+            this.charencoder.onUnmappableCharacter(a2 != null? a2 : CodingErrorAction.REPORT);
+        } else {
+            this.charencoder = null;
+        }
     }
 
+    /**
+     * @deprecated (4.3) use
+     *   {@link SessionOutputBufferImpl#SessionOutputBufferImpl(int, int, Charset)}
+     */
+    @Deprecated
     public SessionOutputBufferImpl(
-            int buffersize,
-            int linebuffersize,
+            final int buffersize,
+            final int linebuffersize,
             final HttpParams params) {
-        this(buffersize, linebuffersize, new HeapByteBufferAllocator(), params);
+        this(buffersize, linebuffersize, HeapByteBufferAllocator.INSTANCE, params);
+    }
+
+    /**
+     * @since 4.3
+     */
+    public SessionOutputBufferImpl(final int buffersize) {
+        this(buffersize, 256, null, HeapByteBufferAllocator.INSTANCE);
+    }
+
+    /**
+     * @since 4.3
+     */
+    public SessionOutputBufferImpl(
+            final int buffersize,
+            final int linebuffersize,
+            final Charset charset) {
+        this(buffersize, linebuffersize,
+                charset != null ? charset.newEncoder() : null, HeapByteBufferAllocator.INSTANCE);
+    }
+
+    /**
+     * @since 4.3
+     */
+    public SessionOutputBufferImpl(
+            final int buffersize,
+            final int linebuffersize) {
+        this(buffersize, linebuffersize, null, HeapByteBufferAllocator.INSTANCE);
     }
 
     public void reset(final HttpParams params) {
@@ -93,12 +162,9 @@ public class SessionOutputBufferImpl extends ExpandableBuffer implements Session
     }
 
     public int flush(final WritableByteChannel channel) throws IOException {
-        if (channel == null) {
-            throw new IllegalArgumentException("Channel may not be null");
-        }
+        Args.notNull(channel, "Channel");
         setOutputMode();
-        int noWritten = channel.write(this.buffer);
-        return noWritten;
+        return channel.write(this.buffer);
     }
 
     public void write(final ByteBuffer src) {
@@ -106,7 +172,7 @@ public class SessionOutputBufferImpl extends ExpandableBuffer implements Session
             return;
         }
         setInputMode();
-        int requiredCapacity = this.buffer.position() + src.remaining();
+        final int requiredCapacity = this.buffer.position() + src.remaining();
         ensureCapacity(requiredCapacity);
         this.buffer.put(src);
     }
@@ -124,9 +190,9 @@ public class SessionOutputBufferImpl extends ExpandableBuffer implements Session
             return;
         }
         setInputMode();
-        int off = 0;
-        int len = b.length;
-        int requiredCapacity = this.buffer.position() + len;
+        final int off = 0;
+        final int len = b.length;
+        final int requiredCapacity = this.buffer.position() + len;
         ensureCapacity(requiredCapacity);
         this.buffer.put(b, off, len);
     }
@@ -139,27 +205,63 @@ public class SessionOutputBufferImpl extends ExpandableBuffer implements Session
         if (linebuffer == null) {
             return;
         }
+        setInputMode();
         // Do not bother if the buffer is empty
         if (linebuffer.length() > 0 ) {
-            setInputMode();
-            this.charencoder.reset();
-            // transfer the string in small chunks
-            int remaining = linebuffer.length();
-            int offset = 0;
-            while (remaining > 0) {
-                int l = this.charbuffer.remaining();
-                boolean eol = false;
-                if (remaining <= l) {
-                    l = remaining;
-                    // terminate the encoding process
-                    eol = true;
+            if (this.charencoder == null) {
+                final int requiredCapacity = this.buffer.position() + linebuffer.length();
+                ensureCapacity(requiredCapacity);
+                if (this.buffer.hasArray()) {
+                    final byte[] b = this.buffer.array();
+                    final int len = linebuffer.length();
+                    final int off = this.buffer.position();
+                    for (int i = 0; i < len; i++) {
+                        b[off + i]  = (byte) linebuffer.charAt(i);
+                    }
+                    this.buffer.position(off + len);
+                } else {
+                    for (int i = 0; i < linebuffer.length(); i++) {
+                        this.buffer.put((byte) linebuffer.charAt(i));
+                    }
+                }
+            } else {
+                if (this.charbuffer == null) {
+                    this.charbuffer = CharBuffer.allocate(this.lineBuffersize);
                 }
-                this.charbuffer.put(linebuffer.buffer(), offset, l);
-                this.charbuffer.flip();
+                this.charencoder.reset();
+                // transfer the string in small chunks
+                int remaining = linebuffer.length();
+                int offset = 0;
+                while (remaining > 0) {
+                    int l = this.charbuffer.remaining();
+                    boolean eol = false;
+                    if (remaining <= l) {
+                        l = remaining;
+                        // terminate the encoding process
+                        eol = true;
+                    }
+                    this.charbuffer.put(linebuffer.buffer(), offset, l);
+                    this.charbuffer.flip();
 
+                    boolean retry = true;
+                    while (retry) {
+                        final CoderResult result = this.charencoder.encode(this.charbuffer, this.buffer, eol);
+                        if (result.isError()) {
+                            result.throwException();
+                        }
+                        if (result.isOverflow()) {
+                            expand();
+                        }
+                        retry = !result.isUnderflow();
+                    }
+                    this.charbuffer.compact();
+                    offset += l;
+                    remaining -= l;
+                }
+                // flush the encoder
                 boolean retry = true;
                 while (retry) {
-                    CoderResult result = this.charencoder.encode(this.charbuffer, this.buffer, eol);
+                    final CoderResult result = this.charencoder.flush(this.buffer);
                     if (result.isError()) {
                         result.throwException();
                     }
@@ -168,21 +270,6 @@ public class SessionOutputBufferImpl extends ExpandableBuffer implements Session
                     }
                     retry = !result.isUnderflow();
                 }
-                this.charbuffer.compact();
-                offset += l;
-                remaining -= l;
-            }
-            // flush the encoder
-            boolean retry = true;
-            while (retry) {
-                CoderResult result = this.charencoder.flush(this.buffer);
-                if (result.isError()) {
-                    result.throwException();
-                }
-                if (result.isOverflow()) {
-                    expand();
-                }
-                retry = !result.isUnderflow();
             }
         }
         writeCRLF();
@@ -193,7 +280,7 @@ public class SessionOutputBufferImpl extends ExpandableBuffer implements Session
             return;
         }
         if (s.length() > 0) {
-            CharArrayBuffer tmp = new CharArrayBuffer(s.length());
+            final CharArrayBuffer tmp = new CharArrayBuffer(s.length());
             tmp.append(s);
             writeLine(tmp);
         } else {
diff --git a/httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/SessionRequestHandle.java b/httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/SessionRequestHandle.java
index 228f539..199187d 100644
--- a/httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/SessionRequestHandle.java
+++ b/httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/SessionRequestHandle.java
@@ -28,12 +28,12 @@
 package org.apache.http.impl.nio.reactor;
 
 import org.apache.http.annotation.Immutable;
-import org.apache.http.nio.reactor.SessionRequest;
+import org.apache.http.util.Args;
 
 /**
  * Session request handle class used by I/O reactor implementations to keep
- * a reference to a {@link SessionRequest} along with the time the request
- * was made.
+ * a reference to a {@link org.apache.http.nio.reactor.SessionRequest} along
+ * with the time the request was made.
  *
  * @since 4.0
  */
@@ -45,9 +45,7 @@ public class SessionRequestHandle {
 
     public SessionRequestHandle(final SessionRequestImpl sessionRequest) {
         super();
-        if (sessionRequest == null) {
-            throw new IllegalArgumentException("Session request may not be null");
-        }
+        Args.notNull(sessionRequest, "Session request");
         this.sessionRequest = sessionRequest;
         this.requestTime = System.currentTimeMillis();
     }
diff --git a/httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/SessionRequestImpl.java b/httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/SessionRequestImpl.java
index a060c1a..c84f2eb 100644
--- a/httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/SessionRequestImpl.java
+++ b/httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/SessionRequestImpl.java
@@ -36,6 +36,7 @@ import org.apache.http.annotation.ThreadSafe;
 import org.apache.http.nio.reactor.IOSession;
 import org.apache.http.nio.reactor.SessionRequest;
 import org.apache.http.nio.reactor.SessionRequestCallback;
+import org.apache.http.util.Args;
 
 /**
  * Default implementation of {@link SessionRequest}.
@@ -63,9 +64,7 @@ public class SessionRequestImpl implements SessionRequest {
             final Object attachment,
             final SessionRequestCallback callback) {
         super();
-        if (remoteAddress == null) {
-            throw new IllegalArgumentException("Remote address may not be null");
-        }
+        Args.notNull(remoteAddress, "Remote address");
         this.remoteAddress = remoteAddress;
         this.localAddress = localAddress;
         this.attachment = attachment;
@@ -117,9 +116,7 @@ public class SessionRequestImpl implements SessionRequest {
     }
 
     public void completed(final IOSession session) {
-        if (session == null) {
-            throw new IllegalArgumentException("Session may not be null");
-        }
+        Args.notNull(session, "Session");
         if (this.completed) {
             return;
         }
@@ -141,14 +138,14 @@ public class SessionRequestImpl implements SessionRequest {
             return;
         }
         this.completed = true;
-        SelectionKey key = this.key;
+        final SelectionKey key = this.key;
         if (key != null) {
             key.cancel();
-            Channel channel = key.channel();
+            final Channel channel = key.channel();
             if (channel.isOpen()) {
                 try {
                     channel.close();
-                } catch (IOException ignore) {}
+                } catch (final IOException ignore) {}
             }
         }
         synchronized (this) {
@@ -165,14 +162,14 @@ public class SessionRequestImpl implements SessionRequest {
             return;
         }
         this.completed = true;
-        SelectionKey key = this.key;
+        final SelectionKey key = this.key;
         if (key != null) {
             key.cancel();
-            Channel channel = key.channel();
+            final Channel channel = key.channel();
             if (channel.isOpen()) {
                 try {
                     channel.close();
-                } catch (IOException ignore) {}
+                } catch (final IOException ignore) {}
             }
         }
         synchronized (this) {
@@ -186,10 +183,10 @@ public class SessionRequestImpl implements SessionRequest {
         return this.connectTimeout;
     }
 
-    public void setConnectTimeout(int timeout) {
+    public void setConnectTimeout(final int timeout) {
         if (this.connectTimeout != timeout) {
             this.connectTimeout = timeout;
-            SelectionKey key = this.key;
+            final SelectionKey key = this.key;
             if (key != null) {
                 key.selector().wakeup();
             }
@@ -201,14 +198,14 @@ public class SessionRequestImpl implements SessionRequest {
             return;
         }
         this.completed = true;
-        SelectionKey key = this.key;
+        final SelectionKey key = this.key;
         if (key != null) {
             key.cancel();
-            Channel channel = key.channel();
+            final Channel channel = key.channel();
             if (channel.isOpen()) {
                 try {
                     channel.close();
-                } catch (IOException ignore) {}
+                } catch (final IOException ignore) {}
             }
         }
         synchronized (this) {
diff --git a/httpcore-nio/src/main/java/org/apache/http/nio/ContentDecoderChannel.java b/httpcore-nio/src/main/java/org/apache/http/nio/ContentDecoderChannel.java
index a1271e1..d1de9d7 100644
--- a/httpcore-nio/src/main/java/org/apache/http/nio/ContentDecoderChannel.java
+++ b/httpcore-nio/src/main/java/org/apache/http/nio/ContentDecoderChannel.java
@@ -42,11 +42,11 @@ public class ContentDecoderChannel implements ReadableByteChannel {
 
     private final ContentDecoder decoder;
 
-    public ContentDecoderChannel(ContentDecoder decoder) {
+    public ContentDecoderChannel(final ContentDecoder decoder) {
         this.decoder = decoder;
     }
 
-    public int read(ByteBuffer dst) throws IOException {
+    public int read(final ByteBuffer dst) throws IOException {
         return decoder.read(dst);
     }
 
diff --git a/httpcore-nio/src/main/java/org/apache/http/nio/ContentEncoderChannel.java b/httpcore-nio/src/main/java/org/apache/http/nio/ContentEncoderChannel.java
index 4ca5514..47c1a70 100644
--- a/httpcore-nio/src/main/java/org/apache/http/nio/ContentEncoderChannel.java
+++ b/httpcore-nio/src/main/java/org/apache/http/nio/ContentEncoderChannel.java
@@ -31,8 +31,6 @@ import java.io.IOException;
 import java.nio.ByteBuffer;
 import java.nio.channels.WritableByteChannel;
 
-import org.apache.http.nio.ContentEncoder;
-
 /**
  * A {@link WritableByteChannel} that delegates to a {@link ContentEncoder}.
  * Attempts to close this channel are ignored, and {@link #isOpen} always
@@ -44,11 +42,11 @@ public class ContentEncoderChannel implements WritableByteChannel {
 
     private final ContentEncoder contentEncoder;
 
-    public ContentEncoderChannel(ContentEncoder contentEncoder) {
+    public ContentEncoderChannel(final ContentEncoder contentEncoder) {
         this.contentEncoder = contentEncoder;
     }
 
-    public int write(ByteBuffer src) throws IOException {
+    public int write(final ByteBuffer src) throws IOException {
         return contentEncoder.write(src);
     }
 
diff --git a/httpcore-nio/src/main/java/org/apache/http/nio/FileContentEncoder.java b/httpcore-nio/src/main/java/org/apache/http/nio/FileContentEncoder.java
index e6df139..4dc396f 100644
--- a/httpcore-nio/src/main/java/org/apache/http/nio/FileContentEncoder.java
+++ b/httpcore-nio/src/main/java/org/apache/http/nio/FileContentEncoder.java
@@ -29,7 +29,6 @@ package org.apache.http.nio;
 
 import java.io.IOException;
 import java.nio.channels.FileChannel;
-import org.apache.http.nio.ContentEncoder;
 
 /**
  * A content encoder capable of transferring data directly from a {@link FileChannel}
diff --git a/httpcore-nio/src/main/java/org/apache/http/nio/NHttpClientIOTarget.java b/httpcore-nio/src/main/java/org/apache/http/nio/NHttpClientIOTarget.java
index 6a10cb4..0aad9e0 100644
--- a/httpcore-nio/src/main/java/org/apache/http/nio/NHttpClientIOTarget.java
+++ b/httpcore-nio/src/main/java/org/apache/http/nio/NHttpClientIOTarget.java
@@ -27,12 +27,10 @@
 
 package org.apache.http.nio;
 
-import org.apache.http.nio.reactor.IOEventDispatch;
-
 /**
  * Extended version of the {@link NHttpClientConnection} used by
- * {@link IOEventDispatch} implementations to inform client-side connection
- * objects of I/O events.
+ * {@link org.apache.http.nio.reactor.IOEventDispatch} implementations
+ * to inform client-side connection objects of I/O events.
  *
  * @since 4.0
  *
diff --git a/httpcore/src/main/java/org/apache/http/concurrent/FutureCallback.java b/httpcore-nio/src/main/java/org/apache/http/nio/NHttpMessageParserFactory.java
similarity index 75%
copy from httpcore/src/main/java/org/apache/http/concurrent/FutureCallback.java
copy to httpcore-nio/src/main/java/org/apache/http/nio/NHttpMessageParserFactory.java
index 228c659..5f06843 100644
--- a/httpcore/src/main/java/org/apache/http/concurrent/FutureCallback.java
+++ b/httpcore-nio/src/main/java/org/apache/http/nio/NHttpMessageParserFactory.java
@@ -24,22 +24,20 @@
  * <http://www.apache.org/>.
  *
  */
-package org.apache.http.concurrent;
 
-import java.util.concurrent.Future;
+package org.apache.http.nio;
+
+import org.apache.http.HttpMessage;
+import org.apache.http.config.MessageConstraints;
+import org.apache.http.nio.reactor.SessionInputBuffer;
 
 /**
- * A callback interface that gets invoked upon completion of a {@link Future}.
+ * Factory for {@link NHttpMessageParser} instances.
  *
- * @param <T> the future result type returned by this callback.
- * @since 4.2
+ * @since 4.3
  */
-public interface FutureCallback<T> {
-
-    void completed(T result);
-
-    void failed(Exception ex);
+public interface NHttpMessageParserFactory<T extends HttpMessage> {
 
-    void cancelled();
+    NHttpMessageParser<T> create(SessionInputBuffer buffer, MessageConstraints constraints);
 
 }
diff --git a/httpcore/src/main/java/org/apache/http/io/EofSensor.java b/httpcore-nio/src/main/java/org/apache/http/nio/NHttpMessageWriterFactory.java
similarity index 79%
copy from httpcore/src/main/java/org/apache/http/io/EofSensor.java
copy to httpcore-nio/src/main/java/org/apache/http/nio/NHttpMessageWriterFactory.java
index b1ec82e..51de89d 100644
--- a/httpcore/src/main/java/org/apache/http/io/EofSensor.java
+++ b/httpcore-nio/src/main/java/org/apache/http/nio/NHttpMessageWriterFactory.java
@@ -25,15 +25,18 @@
  *
  */
 
-package org.apache.http.io;
+package org.apache.http.nio;
+
+import org.apache.http.HttpMessage;
+import org.apache.http.nio.reactor.SessionOutputBuffer;
 
 /**
- * EOF sensor.
+ * Factory for {@link NHttpMessageWriter} instances.
  *
- * @since 4.0
+ * @since 4.3
  */
-public interface EofSensor {
+public interface NHttpMessageWriterFactory<T extends HttpMessage> {
 
-    boolean isEof();
+    NHttpMessageWriter<T> create(SessionOutputBuffer buffer);
 
 }
diff --git a/httpcore-nio/src/main/java/org/apache/http/nio/NHttpServerIOTarget.java b/httpcore-nio/src/main/java/org/apache/http/nio/NHttpServerIOTarget.java
index 7cdf687..9cf2222 100644
--- a/httpcore-nio/src/main/java/org/apache/http/nio/NHttpServerIOTarget.java
+++ b/httpcore-nio/src/main/java/org/apache/http/nio/NHttpServerIOTarget.java
@@ -27,12 +27,10 @@
 
 package org.apache.http.nio;
 
-import org.apache.http.nio.reactor.IOEventDispatch;
-
 /**
  * Extended version of the {@link NHttpServerConnection} used by
- * {@link IOEventDispatch} implementations to inform server-side connection
- * objects of I/O events.
+ * {@link org.apache.http.nio.reactor.IOEventDispatch } implementations
+ * to inform server-side connection objects of I/O events.
  *
  * @since 4.0
  *
diff --git a/httpcore-nio/src/main/java/org/apache/http/nio/entity/BufferingNHttpEntity.java b/httpcore-nio/src/main/java/org/apache/http/nio/entity/BufferingNHttpEntity.java
index 9dd3da1..d323030 100644
--- a/httpcore-nio/src/main/java/org/apache/http/nio/entity/BufferingNHttpEntity.java
+++ b/httpcore-nio/src/main/java/org/apache/http/nio/entity/BufferingNHttpEntity.java
@@ -36,10 +36,10 @@ import org.apache.http.annotation.NotThreadSafe;
 import org.apache.http.entity.HttpEntityWrapper;
 import org.apache.http.nio.ContentDecoder;
 import org.apache.http.nio.IOControl;
-import org.apache.http.nio.protocol.BasicAsyncRequestConsumer;
-import org.apache.http.nio.protocol.BasicAsyncResponseConsumer;
 import org.apache.http.nio.util.ByteBufferAllocator;
 import org.apache.http.nio.util.SimpleInputBuffer;
+import org.apache.http.util.Args;
+import org.apache.http.util.Asserts;
 
 /**
  * A {@link ConsumingNHttpEntity} that consumes content into a buffer. The
@@ -49,7 +49,9 @@ import org.apache.http.nio.util.SimpleInputBuffer;
  *
  * @since 4.0
  *
- * @deprecated (4.2) use {@link BasicAsyncRequestConsumer} or {@link BasicAsyncResponseConsumer}
+ * @deprecated use (4.2)
+ *  {@link org.apache.http.nio.protocol.BasicAsyncRequestProducer}
+ *  or {@link org.apache.http.nio.protocol.BasicAsyncResponseProducer}
  */
 @NotThreadSafe
 @Deprecated
@@ -82,10 +84,6 @@ public class BufferingNHttpEntity extends HttpEntityWrapper implements
         this.finished = true;
     }
 
-    @Override
-    public void consumeContent() throws IOException {
-    }
-
     /**
      * Obtains entity's content as {@link InputStream}.
      *
@@ -94,12 +92,8 @@ public class BufferingNHttpEntity extends HttpEntityWrapper implements
      */
     @Override
     public InputStream getContent() throws IOException {
-        if (!this.finished) {
-            throw new IllegalStateException("Entity content has not been fully received");
-        }
-        if (this.consumed) {
-            throw new IllegalStateException("Entity content has been consumed");
-        }
+        Asserts.check(this.finished, "Entity content has not been fully received");
+        Asserts.check(!this.consumed, "Entity content has been consumed");
         this.consumed = true;
         return new ContentInputStream(this.buffer);
     }
@@ -116,11 +110,9 @@ public class BufferingNHttpEntity extends HttpEntityWrapper implements
 
     @Override
     public void writeTo(final OutputStream outstream) throws IOException {
-        if (outstream == null) {
-            throw new IllegalArgumentException("Output stream may not be null");
-        }
-        InputStream instream = getContent();
-        byte[] buffer = new byte[BUFFER_SIZE];
+        Args.notNull(outstream, "Output stream");
+        final InputStream instream = getContent();
+        final byte[] buffer = new byte[BUFFER_SIZE];
         int l;
         // consume until EOF
         while ((l = instream.read(buffer)) != -1) {
diff --git a/httpcore-nio/src/main/java/org/apache/http/nio/entity/ConsumingNHttpEntity.java b/httpcore-nio/src/main/java/org/apache/http/nio/entity/ConsumingNHttpEntity.java
index bf8df44..ff10764 100644
--- a/httpcore-nio/src/main/java/org/apache/http/nio/entity/ConsumingNHttpEntity.java
+++ b/httpcore-nio/src/main/java/org/apache/http/nio/entity/ConsumingNHttpEntity.java
@@ -32,8 +32,6 @@ import java.io.IOException;
 import org.apache.http.HttpEntity;
 import org.apache.http.nio.ContentDecoder;
 import org.apache.http.nio.IOControl;
-import org.apache.http.nio.protocol.BasicAsyncRequestConsumer;
-import org.apache.http.nio.protocol.BasicAsyncResponseConsumer;
 
 /**
  * A non-blocking {@link HttpEntity} that allows content to be streamed from a
@@ -41,7 +39,9 @@ import org.apache.http.nio.protocol.BasicAsyncResponseConsumer;
  *
  * @since 4.0
  *
- * @deprecated (4.2) use {@link BasicAsyncRequestConsumer} or {@link BasicAsyncResponseConsumer}
+ * @deprecated use (4.2)
+ *  {@link org.apache.http.nio.protocol.BasicAsyncRequestProducer}
+ *  or {@link org.apache.http.nio.protocol.BasicAsyncResponseProducer}
  */
 @Deprecated
 public interface ConsumingNHttpEntity extends HttpEntity {
diff --git a/httpcore-nio/src/main/java/org/apache/http/nio/entity/ConsumingNHttpEntityTemplate.java b/httpcore-nio/src/main/java/org/apache/http/nio/entity/ConsumingNHttpEntityTemplate.java
index 5a390bf..6695319 100644
--- a/httpcore-nio/src/main/java/org/apache/http/nio/entity/ConsumingNHttpEntityTemplate.java
+++ b/httpcore-nio/src/main/java/org/apache/http/nio/entity/ConsumingNHttpEntityTemplate.java
@@ -35,8 +35,6 @@ import org.apache.http.HttpEntity;
 import org.apache.http.entity.HttpEntityWrapper;
 import org.apache.http.nio.ContentDecoder;
 import org.apache.http.nio.IOControl;
-import org.apache.http.nio.protocol.BasicAsyncRequestConsumer;
-import org.apache.http.nio.protocol.BasicAsyncResponseConsumer;
 
 /**
  * A {@link ConsumingNHttpEntity} that forwards available content to a
@@ -44,7 +42,9 @@ import org.apache.http.nio.protocol.BasicAsyncResponseConsumer;
  *
  * @since 4.0
  *
- * @deprecated (4.2) use {@link BasicAsyncRequestConsumer} or {@link BasicAsyncResponseConsumer}
+ * @deprecated use (4.2)
+ *  {@link org.apache.http.nio.protocol.BasicAsyncRequestProducer}
+ *  or {@link org.apache.http.nio.protocol.BasicAsyncResponseProducer}
  */
 @Deprecated
 public class ConsumingNHttpEntityTemplate
@@ -74,21 +74,10 @@ public class ConsumingNHttpEntityTemplate
     }
 
     @Override
-    public void writeTo(OutputStream out) throws IOException, UnsupportedOperationException {
+    public void writeTo(final OutputStream out) throws IOException, UnsupportedOperationException {
         throw new UnsupportedOperationException("Does not support blocking methods");
     }
 
-    /**
-     * This method is equivalent to the {@link #finish()} method.
-     * <br/>
-     * TODO: The name of this method is misnomer. It will be renamed to
-     * #finish() in the next major release.
-     */
-    @Override
-    public void consumeContent() throws IOException {
-        finish();
-    }
-
     public void consumeContent(
             final ContentDecoder decoder,
             final IOControl ioctrl) throws IOException {
diff --git a/httpcore-nio/src/main/java/org/apache/http/nio/entity/ContentBufferEntity.java b/httpcore-nio/src/main/java/org/apache/http/nio/entity/ContentBufferEntity.java
index a889df4..bc4cfb9 100644
--- a/httpcore-nio/src/main/java/org/apache/http/nio/entity/ContentBufferEntity.java
+++ b/httpcore-nio/src/main/java/org/apache/http/nio/entity/ContentBufferEntity.java
@@ -32,6 +32,7 @@ import org.apache.http.HttpEntity;
 import org.apache.http.annotation.NotThreadSafe;
 import org.apache.http.entity.BasicHttpEntity;
 import org.apache.http.nio.util.ContentInputBuffer;
+import org.apache.http.util.Args;
 
 /**
  * HTTP entity wrapper whose content is provided by a
@@ -42,7 +43,7 @@ import org.apache.http.nio.util.ContentInputBuffer;
 @NotThreadSafe
 public class ContentBufferEntity extends BasicHttpEntity {
 
-    private HttpEntity wrappedEntity;
+    private final HttpEntity wrappedEntity;
 
     /**
      * Creates new instance of ContentBufferEntity.
@@ -52,9 +53,7 @@ public class ContentBufferEntity extends BasicHttpEntity {
      */
     public ContentBufferEntity(final HttpEntity entity, final ContentInputBuffer buffer) {
         super();
-        if (entity == null) {
-            throw new IllegalArgumentException("HTTP entity may not be null");
-        }
+        Args.notNull(entity, "HTTP entity");
         this.wrappedEntity = entity;
         setContent(new ContentInputStream(buffer));
     }
diff --git a/httpcore-nio/src/main/java/org/apache/http/nio/entity/ContentInputStream.java b/httpcore-nio/src/main/java/org/apache/http/nio/entity/ContentInputStream.java
index 1cb063b..5e92c16 100644
--- a/httpcore-nio/src/main/java/org/apache/http/nio/entity/ContentInputStream.java
+++ b/httpcore-nio/src/main/java/org/apache/http/nio/entity/ContentInputStream.java
@@ -33,6 +33,7 @@ import java.io.InputStream;
 import org.apache.http.annotation.NotThreadSafe;
 import org.apache.http.io.BufferInfo;
 import org.apache.http.nio.util.ContentInputBuffer;
+import org.apache.http.util.Args;
 
 /**
  * {@link InputStream} adaptor for {@link ContentInputBuffer}.
@@ -46,9 +47,7 @@ public class ContentInputStream extends InputStream {
 
     public ContentInputStream(final ContentInputBuffer buffer) {
         super();
-        if (buffer == null) {
-            throw new IllegalArgumentException("Input buffer may not be null");
-        }
+        Args.notNull(buffer, "Input buffer");
         this.buffer = buffer;
     }
 
@@ -62,7 +61,7 @@ public class ContentInputStream extends InputStream {
     }
 
     @Override
-    public int read(final byte[] b, int off, int len) throws IOException {
+    public int read(final byte[] b, final int off, final int len) throws IOException {
         return this.buffer.read(b, off, len);
     }
 
@@ -82,7 +81,7 @@ public class ContentInputStream extends InputStream {
     @Override
     public void close() throws IOException {
         // read and discard the remainder of the message
-        byte tmp[] = new byte[1024];
+        final byte tmp[] = new byte[1024];
         while (this.buffer.read(tmp, 0, tmp.length) >= 0) {
         }
         super.close();
diff --git a/httpcore-nio/src/main/java/org/apache/http/nio/entity/ContentListener.java b/httpcore-nio/src/main/java/org/apache/http/nio/entity/ContentListener.java
index 90ae516..8063bee 100644
--- a/httpcore-nio/src/main/java/org/apache/http/nio/entity/ContentListener.java
+++ b/httpcore-nio/src/main/java/org/apache/http/nio/entity/ContentListener.java
@@ -36,7 +36,7 @@ import org.apache.http.nio.IOControl;
  * A listener for available data on a non-blocking {@link ConsumingNHttpEntity}.
  *
  * @since 4.0
- * 
+ *
  * @deprecated (4.2)
  */
 @Deprecated
diff --git a/httpcore-nio/src/main/java/org/apache/http/nio/entity/ContentOutputStream.java b/httpcore-nio/src/main/java/org/apache/http/nio/entity/ContentOutputStream.java
index 9aef182..ee30468 100644
--- a/httpcore-nio/src/main/java/org/apache/http/nio/entity/ContentOutputStream.java
+++ b/httpcore-nio/src/main/java/org/apache/http/nio/entity/ContentOutputStream.java
@@ -32,6 +32,7 @@ import java.io.OutputStream;
 
 import org.apache.http.annotation.NotThreadSafe;
 import org.apache.http.nio.util.ContentOutputBuffer;
+import org.apache.http.util.Args;
 
 /**
  * {@link OutputStream} adaptor for {@link ContentOutputBuffer}.
@@ -45,9 +46,7 @@ public class ContentOutputStream extends OutputStream {
 
     public ContentOutputStream(final ContentOutputBuffer buffer) {
         super();
-        if (buffer == null) {
-            throw new IllegalArgumentException("Output buffer may not be null");
-        }
+        Args.notNull(buffer, "Output buffer");
         this.buffer = buffer;
     }
 
@@ -61,12 +60,12 @@ public class ContentOutputStream extends OutputStream {
     }
 
     @Override
-    public void write(byte[] b, int off, int len) throws IOException {
+    public void write(final byte[] b, final int off, final int len) throws IOException {
         this.buffer.write(b, off, len);
     }
 
     @Override
-    public void write(byte[] b) throws IOException {
+    public void write(final byte[] b) throws IOException {
         if (b == null) {
             return;
         }
@@ -74,7 +73,7 @@ public class ContentOutputStream extends OutputStream {
     }
 
     @Override
-    public void write(int b) throws IOException {
+    public void write(final int b) throws IOException {
         this.buffer.write(b);
     }
 
diff --git a/httpcore-nio/src/main/java/org/apache/http/nio/entity/EntityAsyncContentProducer.java b/httpcore-nio/src/main/java/org/apache/http/nio/entity/EntityAsyncContentProducer.java
index 35d0cf0..f7e0624 100644
--- a/httpcore-nio/src/main/java/org/apache/http/nio/entity/EntityAsyncContentProducer.java
+++ b/httpcore-nio/src/main/java/org/apache/http/nio/entity/EntityAsyncContentProducer.java
@@ -28,6 +28,7 @@
 package org.apache.http.nio.entity;
 
 import java.io.IOException;
+import java.io.InputStream;
 import java.nio.ByteBuffer;
 import java.nio.channels.Channels;
 import java.nio.channels.ReadableByteChannel;
@@ -36,6 +37,7 @@ import org.apache.http.HttpEntity;
 import org.apache.http.annotation.NotThreadSafe;
 import org.apache.http.nio.ContentEncoder;
 import org.apache.http.nio.IOControl;
+import org.apache.http.util.Args;
 
 /**
  * Basic implementation of {@link HttpAsyncContentProducer} that relies on
@@ -53,9 +55,7 @@ public class EntityAsyncContentProducer implements HttpAsyncContentProducer {
 
     public EntityAsyncContentProducer(final HttpEntity entity) {
         super();
-        if (entity == null) {
-            throw new IllegalArgumentException("HTTP entity may not be null");
-        }
+        Args.notNull(entity, "HTTP entity");
         this.entity = entity;
         this.buffer = ByteBuffer.allocate(4096);
     }
@@ -65,10 +65,10 @@ public class EntityAsyncContentProducer implements HttpAsyncContentProducer {
         if (this.channel == null) {
             this.channel = Channels.newChannel(this.entity.getContent());
         }
-        int i = this.channel.read(this.buffer);
+        final int i = this.channel.read(this.buffer);
         this.buffer.flip();
         encoder.write(this.buffer);
-        boolean buffering = this.buffer.hasRemaining();
+        final boolean buffering = this.buffer.hasRemaining();
         this.buffer.compact();
         if (i == -1 && !buffering) {
             encoder.complete();
@@ -81,11 +81,15 @@ public class EntityAsyncContentProducer implements HttpAsyncContentProducer {
     }
 
     public void close() throws IOException {
-        ReadableByteChannel local = this.channel;
+        final ReadableByteChannel local = this.channel;
         this.channel = null;
         if (local != null) {
             local.close();
         }
+        if (this.entity.isStreaming()) {
+            final InputStream instream = this.entity.getContent();
+            instream.close();
+        }
     }
 
 }
diff --git a/httpcore-nio/src/main/java/org/apache/http/nio/entity/NByteArrayEntity.java b/httpcore-nio/src/main/java/org/apache/http/nio/entity/NByteArrayEntity.java
index 737bc52..16ae6b4 100644
--- a/httpcore-nio/src/main/java/org/apache/http/nio/entity/NByteArrayEntity.java
+++ b/httpcore-nio/src/main/java/org/apache/http/nio/entity/NByteArrayEntity.java
@@ -38,6 +38,7 @@ import org.apache.http.entity.AbstractHttpEntity;
 import org.apache.http.entity.ContentType;
 import org.apache.http.nio.ContentEncoder;
 import org.apache.http.nio.IOControl;
+import org.apache.http.util.Args;
 
 /**
  * A simple self contained, repeatable non-blocking entity that retrieves
@@ -69,9 +70,7 @@ public class NByteArrayEntity extends AbstractHttpEntity
      */
     public NByteArrayEntity(final byte[] b, final ContentType contentType) {
         super();
-        if (b == null) {
-            throw new IllegalArgumentException("Source byte array may not be null");
-        }
+        Args.notNull(b, "Source byte array");
         this.b = b;
         this.off = 0;
         this.len = b.length;
@@ -86,11 +85,9 @@ public class NByteArrayEntity extends AbstractHttpEntity
     /**
      * @since 4.2
      */
-    public NByteArrayEntity(final byte[] b, int off, int len, final ContentType contentType) {
+    public NByteArrayEntity(final byte[] b, final int off, final int len, final ContentType contentType) {
         super();
-        if (b == null) {
-            throw new IllegalArgumentException("Source byte array may not be null");
-        }
+        Args.notNull(b, "Source byte array");
         if ((off < 0) || (off > b.length) || (len < 0) ||
                 ((off + len) < 0) || ((off + len) > b.length)) {
             throw new IndexOutOfBoundsException("off: " + off + " len: " + len + " b.length: " + b.length);
@@ -110,7 +107,7 @@ public class NByteArrayEntity extends AbstractHttpEntity
         this(b, null);
     }
 
-    public NByteArrayEntity(final byte[] b, int off, int len) {
+    public NByteArrayEntity(final byte[] b, final int off, final int len) {
         this(b, off, len, null);
     }
 
@@ -128,6 +125,7 @@ public class NByteArrayEntity extends AbstractHttpEntity
      *
      * @deprecated (4.2) use {@link #close()}
      */
+    @Deprecated
     public void finish() {
         close();
     }
@@ -157,9 +155,7 @@ public class NByteArrayEntity extends AbstractHttpEntity
     }
 
     public void writeTo(final OutputStream outstream) throws IOException {
-        if (outstream == null) {
-            throw new IllegalArgumentException("Output stream may not be null");
-        }
+        Args.notNull(outstream, "Output stream");
         outstream.write(this.b, this.off, this.len);
         outstream.flush();
     }
diff --git a/httpcore-nio/src/main/java/org/apache/http/nio/entity/NFileEntity.java b/httpcore-nio/src/main/java/org/apache/http/nio/entity/NFileEntity.java
index 396315a..a29b7d3 100644
--- a/httpcore-nio/src/main/java/org/apache/http/nio/entity/NFileEntity.java
+++ b/httpcore-nio/src/main/java/org/apache/http/nio/entity/NFileEntity.java
@@ -32,6 +32,7 @@ import java.io.FileInputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
+import java.io.RandomAccessFile;
 import java.nio.channels.FileChannel;
 
 import org.apache.http.annotation.NotThreadSafe;
@@ -41,6 +42,7 @@ import org.apache.http.nio.ContentEncoder;
 import org.apache.http.nio.ContentEncoderChannel;
 import org.apache.http.nio.FileContentEncoder;
 import org.apache.http.nio.IOControl;
+import org.apache.http.util.Args;
 
 /**
  * A self contained, repeatable non-blocking entity that retrieves its content
@@ -56,6 +58,7 @@ public class NFileEntity extends AbstractHttpEntity
                          implements HttpAsyncContentProducer, ProducingNHttpEntity {
 
     private final File file;
+    private RandomAccessFile accessfile;
     private FileChannel fileChannel;
     private long idx = -1;
     private boolean useFileChannels;
@@ -73,10 +76,8 @@ public class NFileEntity extends AbstractHttpEntity
      *
      * @since 4.2
      */
-    public NFileEntity(final File file, final ContentType contentType, boolean useFileChannels) {
-        if (file == null) {
-            throw new IllegalArgumentException("File may not be null");
-        }
+    public NFileEntity(final File file, final ContentType contentType, final boolean useFileChannels) {
+        Args.notNull(file, "File");
         this.file = file;
         this.useFileChannels = useFileChannels;
         if (contentType != null) {
@@ -88,9 +89,7 @@ public class NFileEntity extends AbstractHttpEntity
      * @since 4.2
      */
     public NFileEntity(final File file) {
-        if (file == null) {
-            throw new IllegalArgumentException("File may not be null");
-        }
+        Args.notNull(file, "File");
         this.file = file;
     }
     /**
@@ -110,10 +109,8 @@ public class NFileEntity extends AbstractHttpEntity
      * @deprecated (4.2) use {@link #NFileEntity(File, ContentType, boolean)}
      */
     @Deprecated
-    public NFileEntity(final File file, final String contentType, boolean useFileChannels) {
-        if (file == null) {
-            throw new IllegalArgumentException("File may not be null");
-        }
+    public NFileEntity(final File file, final String contentType, final boolean useFileChannels) {
+        Args.notNull(file, "File");
         this.file = file;
         this.useFileChannels = useFileChannels;
         setContentType(contentType);
@@ -133,11 +130,11 @@ public class NFileEntity extends AbstractHttpEntity
      * @since 4.2
      */
     public void close() throws IOException {
-        FileChannel local = fileChannel;
-        fileChannel = null;
-        if (local != null) {
-            local.close();
+        if (accessfile != null) {
+            accessfile.close();
         }
+        accessfile = null;
+        fileChannel = null;
     }
 
     /**
@@ -145,6 +142,7 @@ public class NFileEntity extends AbstractHttpEntity
      *
      * @deprecated (4.2) use {@link #close()}
      */
+    @Deprecated
     public void finish() throws IOException {
         close();
     }
@@ -157,15 +155,17 @@ public class NFileEntity extends AbstractHttpEntity
         return true;
     }
 
-    public void produceContent(ContentEncoder encoder, IOControl ioctrl)
+    public void produceContent(final ContentEncoder encoder, final IOControl ioctrl)
             throws IOException {
+        if (accessfile == null) {
+            accessfile = new RandomAccessFile(this.file, "r");
+        }
         if (fileChannel == null) {
-            FileInputStream in = new FileInputStream(file);
-            fileChannel = in.getChannel();
+            fileChannel = accessfile.getChannel();
             idx = 0;
         }
 
-        long transferred;
+        final long transferred;
         if (useFileChannels && encoder instanceof FileContentEncoder) {
             transferred = ((FileContentEncoder)encoder)
                 .transfer(fileChannel, idx, Long.MAX_VALUE);
@@ -191,12 +191,10 @@ public class NFileEntity extends AbstractHttpEntity
     }
 
     public void writeTo(final OutputStream outstream) throws IOException {
-        if (outstream == null) {
-            throw new IllegalArgumentException("Output stream may not be null");
-        }
-        InputStream instream = new FileInputStream(this.file);
+        Args.notNull(outstream, "Output stream");
+        final InputStream instream = new FileInputStream(this.file);
         try {
-            byte[] tmp = new byte[4096];
+            final byte[] tmp = new byte[4096];
             int l;
             while ((l = instream.read(tmp)) != -1) {
                 outstream.write(tmp, 0, l);
diff --git a/httpcore-nio/src/main/java/org/apache/http/nio/entity/NHttpEntityWrapper.java b/httpcore-nio/src/main/java/org/apache/http/nio/entity/NHttpEntityWrapper.java
index 90d88a8..44bc1be 100644
--- a/httpcore-nio/src/main/java/org/apache/http/nio/entity/NHttpEntityWrapper.java
+++ b/httpcore-nio/src/main/java/org/apache/http/nio/entity/NHttpEntityWrapper.java
@@ -79,28 +79,17 @@ public class NHttpEntityWrapper
      * This method throws {@link UnsupportedOperationException}.
      */
     @Override
-    public void writeTo(OutputStream out) throws IOException, UnsupportedOperationException {
+    public void writeTo(final OutputStream out) throws IOException, UnsupportedOperationException {
         throw new UnsupportedOperationException("Does not support blocking methods");
     }
 
-    /**
-     * This method is equivalent to the {@link #finish()} method.
-     * <br/>
-     * TODO: The name of this method is misnomer. It will be renamed to
-     * #finish() in the next major release.
-     */
-    @Override
-    public void consumeContent() throws IOException {
-        finish();
-    }
-
     public void produceContent(
             final ContentEncoder encoder,
             final IOControl ioctrl) throws IOException {
-        int i = this.channel.read(this.buffer);
+        final int i = this.channel.read(this.buffer);
         this.buffer.flip();
         encoder.write(this.buffer);
-        boolean buffering = this.buffer.hasRemaining();
+        final boolean buffering = this.buffer.hasRemaining();
         this.buffer.compact();
         if (i == -1 && !buffering) {
             encoder.complete();
@@ -111,7 +100,7 @@ public class NHttpEntityWrapper
     public void finish() {
         try {
             this.channel.close();
-        } catch (IOException ignore) {
+        } catch (final IOException ignore) {
         }
     }
 
diff --git a/httpcore-nio/src/main/java/org/apache/http/nio/entity/NStringEntity.java b/httpcore-nio/src/main/java/org/apache/http/nio/entity/NStringEntity.java
index c218693..9999306 100644
--- a/httpcore-nio/src/main/java/org/apache/http/nio/entity/NStringEntity.java
+++ b/httpcore-nio/src/main/java/org/apache/http/nio/entity/NStringEntity.java
@@ -42,6 +42,7 @@ import org.apache.http.entity.ContentType;
 import org.apache.http.nio.ContentEncoder;
 import org.apache.http.nio.IOControl;
 import org.apache.http.protocol.HTTP;
+import org.apache.http.util.Args;
 
 /**
  * A simple, self contained, repeatable non-blocking entity that retrieves
@@ -72,7 +73,7 @@ public class NStringEntity extends AbstractHttpEntity
      * Creates a NStringEntity with the specified content and content type.
      *
      * @param s content to be used. Not {@code null}.
-     * @param contentType content type to be used. May be {@code null}, in which case 
+     * @param contentType content type to be used. May be {@code null}, in which case
      * {@link ContentType#TEXT_PLAIN} is assumed.
      *
      * @throws IllegalArgumentException if the string parameter is null
@@ -80,16 +81,14 @@ public class NStringEntity extends AbstractHttpEntity
      * @since 4.2
      */
     public NStringEntity(final String s, final ContentType contentType) {
-        if (s == null) {
-            throw new IllegalArgumentException("Source string may not be null");
-        }
+        Args.notNull(s, "Source string");
         Charset charset = contentType != null ? contentType.getCharset() : null;
         if (charset == null) {
             charset = HTTP.DEF_CONTENT_CHARSET;
         }
         try {
             this.b = s.getBytes(charset.name());
-        } catch (UnsupportedEncodingException ex) {
+        } catch (final UnsupportedEncodingException ex) {
             // should never happen
             throw new UnsupportedCharsetException(charset.name());
         }
@@ -110,7 +109,8 @@ public class NStringEntity extends AbstractHttpEntity
      *   is {@link HTTP#DEF_CONTENT_CHARSET} is assumed
      *
      * @throws IllegalArgumentException if the string parameter is null
-     * @throws UnsupportedEncodingException if the charset is not supported.
+     * @throws UnsupportedCharsetException Thrown when the named charset is not available in
+     * this instance of the Java virtual machine
      */
     public NStringEntity(final String s, final String charset)
             throws UnsupportedEncodingException {
@@ -126,7 +126,7 @@ public class NStringEntity extends AbstractHttpEntity
      *   is {@link HTTP#DEF_CONTENT_CHARSET} is assumed
      *
      * @throws IllegalArgumentException if the string parameter is null
-     * 
+     *
      * @since 4.2
      */
     public NStringEntity(final String s, final Charset charset) {
@@ -168,6 +168,7 @@ public class NStringEntity extends AbstractHttpEntity
      *
      * @deprecated (4.2) use {@link #close()}
      */
+    @Deprecated
     public void finish() {
         close();
     }
@@ -189,9 +190,7 @@ public class NStringEntity extends AbstractHttpEntity
     }
 
     public void writeTo(final OutputStream outstream) throws IOException {
-        if (outstream == null) {
-            throw new IllegalArgumentException("Output stream may not be null");
-        }
+        Args.notNull(outstream, "Output stream");
         outstream.write(this.b);
         outstream.flush();
     }
diff --git a/httpcore-nio/src/main/java/org/apache/http/nio/entity/ProducingNHttpEntity.java b/httpcore-nio/src/main/java/org/apache/http/nio/entity/ProducingNHttpEntity.java
index 48f4865..44579f1 100644
--- a/httpcore-nio/src/main/java/org/apache/http/nio/entity/ProducingNHttpEntity.java
+++ b/httpcore-nio/src/main/java/org/apache/http/nio/entity/ProducingNHttpEntity.java
@@ -32,8 +32,6 @@ import java.io.IOException;
 import org.apache.http.HttpEntity;
 import org.apache.http.nio.ContentEncoder;
 import org.apache.http.nio.IOControl;
-import org.apache.http.nio.protocol.BasicAsyncRequestProducer;
-import org.apache.http.nio.protocol.BasicAsyncResponseProducer;
 
 /**
  * An {@link HttpEntity} that can stream content out into a
@@ -41,7 +39,9 @@ import org.apache.http.nio.protocol.BasicAsyncResponseProducer;
  *
  * @since 4.0
  *
- * @deprecated use (4.2) {@link BasicAsyncRequestProducer} or {@link BasicAsyncResponseProducer}
+ * @deprecated use (4.2)
+ *  {@link org.apache.http.nio.protocol.BasicAsyncRequestProducer}
+ *  or {@link org.apache.http.nio.protocol.BasicAsyncResponseProducer}
  */
 @Deprecated
 public interface ProducingNHttpEntity extends HttpEntity {
diff --git a/httpcore-nio/src/main/java/org/apache/http/nio/entity/SkipContentListener.java b/httpcore-nio/src/main/java/org/apache/http/nio/entity/SkipContentListener.java
index b937999..ca6e93d 100644
--- a/httpcore-nio/src/main/java/org/apache/http/nio/entity/SkipContentListener.java
+++ b/httpcore-nio/src/main/java/org/apache/http/nio/entity/SkipContentListener.java
@@ -33,6 +33,7 @@ import java.nio.ByteBuffer;
 import org.apache.http.nio.ContentDecoder;
 import org.apache.http.nio.IOControl;
 import org.apache.http.nio.util.ByteBufferAllocator;
+import org.apache.http.util.Args;
 
 /**
  * A simple {@link ContentListener} that reads and ignores all content.
@@ -48,9 +49,7 @@ public class SkipContentListener implements ContentListener {
 
     public SkipContentListener(final ByteBufferAllocator allocator) {
         super();
-        if (allocator == null) {
-            throw new IllegalArgumentException("ByteBuffer allocator may not be null");
-        }
+        Args.notNull(allocator, "ByteBuffer allocator");
         this.buffer = allocator.allocate(2048);
     }
 
diff --git a/httpcore-nio/src/main/java/org/apache/http/nio/entity/package.html b/httpcore-nio/src/main/java/org/apache/http/nio/entity/package.html
index f22b0b7..be123b9 100644
--- a/httpcore-nio/src/main/java/org/apache/http/nio/entity/package.html
+++ b/httpcore-nio/src/main/java/org/apache/http/nio/entity/package.html
@@ -30,7 +30,7 @@
 -->
 </head>
 <body>
-Common HTTP entity implementations with extensions for 
+Common HTTP entity implementations with extensions for
 asynchronous (non-blocking) data transfer.
 
 This package provides a basic selection of entity implementations
diff --git a/httpcore-nio/src/main/java/org/apache/http/nio/params/NIOReactorPNames.java b/httpcore-nio/src/main/java/org/apache/http/nio/params/NIOReactorPNames.java
index 9a53a62..615bd08 100644
--- a/httpcore-nio/src/main/java/org/apache/http/nio/params/NIOReactorPNames.java
+++ b/httpcore-nio/src/main/java/org/apache/http/nio/params/NIOReactorPNames.java
@@ -27,14 +27,12 @@
 
 package org.apache.http.nio.params;
 
-import org.apache.http.impl.nio.reactor.IOReactorConfig;
-
 /**
  * Parameter names for I/O reactors.
  *
  * @since 4.0
  *
- * @deprecated (4.2) use {@link IOReactorConfig}
+ * @deprecated (4.2) use {@link org.apache.http.impl.nio.reactor.IOReactorConfig}
  */
 @Deprecated
 public interface NIOReactorPNames {
diff --git a/httpcore-nio/src/main/java/org/apache/http/nio/pool/AbstractNIOConnPool.java b/httpcore-nio/src/main/java/org/apache/http/nio/pool/AbstractNIOConnPool.java
index 4754c26..5d1eb12 100644
--- a/httpcore-nio/src/main/java/org/apache/http/nio/pool/AbstractNIOConnPool.java
+++ b/httpcore-nio/src/main/java/org/apache/http/nio/pool/AbstractNIOConnPool.java
@@ -35,9 +35,11 @@ import java.util.LinkedList;
 import java.util.ListIterator;
 import java.util.Map;
 import java.util.Set;
+import java.util.concurrent.ConcurrentLinkedQueue;
 import java.util.concurrent.Future;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
+import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.locks.Lock;
 import java.util.concurrent.locks.ReentrantLock;
 
@@ -51,7 +53,10 @@ import org.apache.http.nio.reactor.SessionRequestCallback;
 import org.apache.http.pool.ConnPool;
 import org.apache.http.pool.ConnPoolControl;
 import org.apache.http.pool.PoolEntry;
+import org.apache.http.pool.PoolEntryCallback;
 import org.apache.http.pool.PoolStats;
+import org.apache.http.util.Args;
+import org.apache.http.util.Asserts;
 
 /**
  * Abstract non-blocking connection pool.
@@ -68,88 +73,155 @@ public abstract class AbstractNIOConnPool<T, C, E extends PoolEntry<T, C>>
 
     private final ConnectingIOReactor ioreactor;
     private final NIOConnFactory<T, C> connFactory;
+    private final SocketAddressResolver<T> addressResolver;
     private final SessionRequestCallback sessionRequestCallback;
     private final Map<T, RouteSpecificPool<T, C, E>> routeToPool;
     private final LinkedList<LeaseRequest<T, C, E>> leasingRequests;
     private final Set<SessionRequest> pending;
     private final Set<E> leased;
     private final LinkedList<E> available;
+    private final ConcurrentLinkedQueue<LeaseRequest<T, C, E>> completedRequests;
     private final Map<T, Integer> maxPerRoute;
     private final Lock lock;
+    private final AtomicBoolean isShutDown;
 
-    private volatile boolean isShutDown;
     private volatile int defaultMaxPerRoute;
     private volatile int maxTotal;
 
+    /**
+     * @deprecated use {@link AbstractNIOConnPool#AbstractNIOConnPool(ConnectingIOReactor,
+     *   NIOConnFactory, SocketAddressResolver, int, int)}
+     */
+    @Deprecated
     public AbstractNIOConnPool(
             final ConnectingIOReactor ioreactor,
             final NIOConnFactory<T, C> connFactory,
-            int defaultMaxPerRoute,
-            int maxTotal) {
+            final int defaultMaxPerRoute,
+            final int maxTotal) {
         super();
-        if (ioreactor == null) {
-            throw new IllegalArgumentException("I/O reactor may not be null");
-        }
-        if (connFactory == null) {
-            throw new IllegalArgumentException("Connection factory may not null");
-        }
-        if (defaultMaxPerRoute <= 0) {
-            throw new IllegalArgumentException("Max per route value may not be negative or zero");
-        }
-        if (maxTotal <= 0) {
-            throw new IllegalArgumentException("Max total value may not be negative or zero");
-        }
+        Args.notNull(ioreactor, "I/O reactor");
+        Args.notNull(connFactory, "Connection factory");
+        Args.positive(defaultMaxPerRoute, "Max per route value");
+        Args.positive(maxTotal, "Max total value");
+        this.ioreactor = ioreactor;
+        this.connFactory = connFactory;
+        this.addressResolver = new SocketAddressResolver<T>() {
+
+            public SocketAddress resolveLocalAddress(final T route) throws IOException {
+                return AbstractNIOConnPool.this.resolveLocalAddress(route);
+            }
+
+            public SocketAddress resolveRemoteAddress(final T route) throws IOException {
+                return AbstractNIOConnPool.this.resolveRemoteAddress(route);
+            }
+
+        };
+        this.sessionRequestCallback = new InternalSessionRequestCallback();
+        this.routeToPool = new HashMap<T, RouteSpecificPool<T, C, E>>();
+        this.leasingRequests = new LinkedList<LeaseRequest<T, C, E>>();
+        this.pending = new HashSet<SessionRequest>();
+        this.leased = new HashSet<E>();
+        this.available = new LinkedList<E>();
+        this.maxPerRoute = new HashMap<T, Integer>();
+        this.completedRequests = new ConcurrentLinkedQueue<LeaseRequest<T, C, E>>();
+        this.lock = new ReentrantLock();
+        this.isShutDown = new AtomicBoolean(false);
+        this.defaultMaxPerRoute = defaultMaxPerRoute;
+        this.maxTotal = maxTotal;
+    }
+
+    /**
+     * @since 4.3
+     */
+    public AbstractNIOConnPool(
+            final ConnectingIOReactor ioreactor,
+            final NIOConnFactory<T, C> connFactory,
+            final SocketAddressResolver<T> addressResolver,
+            final int defaultMaxPerRoute,
+            final int maxTotal) {
+        super();
+        Args.notNull(ioreactor, "I/O reactor");
+        Args.notNull(connFactory, "Connection factory");
+        Args.notNull(addressResolver, "Address resolver");
+        Args.positive(defaultMaxPerRoute, "Max per route value");
+        Args.positive(maxTotal, "Max total value");
         this.ioreactor = ioreactor;
         this.connFactory = connFactory;
+        this.addressResolver = addressResolver;
         this.sessionRequestCallback = new InternalSessionRequestCallback();
         this.routeToPool = new HashMap<T, RouteSpecificPool<T, C, E>>();
         this.leasingRequests = new LinkedList<LeaseRequest<T, C, E>>();
         this.pending = new HashSet<SessionRequest>();
         this.leased = new HashSet<E>();
         this.available = new LinkedList<E>();
+        this.completedRequests = new ConcurrentLinkedQueue<LeaseRequest<T, C, E>>();
         this.maxPerRoute = new HashMap<T, Integer>();
         this.lock = new ReentrantLock();
+        this.isShutDown = new AtomicBoolean(false);
         this.defaultMaxPerRoute = defaultMaxPerRoute;
         this.maxTotal = maxTotal;
     }
 
-    protected abstract SocketAddress resolveRemoteAddress(T route);
+    /**
+     * @deprecated (4.3) use {@link SocketAddressResolver}
+     */
+    @Deprecated
+    protected SocketAddress resolveRemoteAddress(final T route) {
+        return null;
+    }
 
-    protected abstract SocketAddress resolveLocalAddress(T route);
+    /**
+     * @deprecated (4.3) use {@link SocketAddressResolver}
+     */
+    @Deprecated
+    protected SocketAddress resolveLocalAddress(final T route) {
+        return null;
+    }
 
     protected abstract E createEntry(T route, C conn);
 
+    /**
+     * @since 4.3
+     */
+    protected void onLease(final E entry) {
+    }
+
+    /**
+     * @since 4.3
+     */
+    protected void onRelease(final E entry) {
+    }
+
     public boolean isShutdown() {
-        return this.isShutDown;
+        return this.isShutDown.get();
     }
 
-    public void shutdown(long waitMs) throws IOException {
-        if (this.isShutDown) {
-            return ;
-        }
-        this.isShutDown = true;
-        this.lock.lock();
-        try {
-            for (SessionRequest sessionRequest: this.pending) {
-                sessionRequest.cancel();
-            }
-            for (E entry: this.available) {
-                entry.close();
-            }
-            for (E entry: this.leased) {
-                entry.close();
-            }
-            for (RouteSpecificPool<T, C, E> pool: this.routeToPool.values()) {
-                pool.shutdown();
+    public void shutdown(final long waitMs) throws IOException {
+        if (this.isShutDown.compareAndSet(false, true)) {
+            fireCallbacks();
+            this.lock.lock();
+            try {
+                for (final SessionRequest sessionRequest: this.pending) {
+                    sessionRequest.cancel();
+                }
+                for (final E entry: this.available) {
+                    entry.close();
+                }
+                for (final E entry: this.leased) {
+                    entry.close();
+                }
+                for (final RouteSpecificPool<T, C, E> pool: this.routeToPool.values()) {
+                    pool.shutdown();
+                }
+                this.routeToPool.clear();
+                this.leased.clear();
+                this.pending.clear();
+                this.available.clear();
+                this.leasingRequests.clear();
+                this.ioreactor.shutdown(waitMs);
+            } finally {
+                this.lock.unlock();
             }
-            this.routeToPool.clear();
-            this.leased.clear();
-            this.pending.clear();
-            this.available.clear();
-            this.leasingRequests.clear();
-            this.ioreactor.shutdown(waitMs);
-        } finally {
-            this.lock.unlock();
         }
     }
 
@@ -173,27 +245,36 @@ public abstract class AbstractNIOConnPool<T, C, E extends PoolEntry<T, C>>
             final T route, final Object state,
             final long connectTimeout, final TimeUnit tunit,
             final FutureCallback<E> callback) {
-        if (route == null) {
-            throw new IllegalArgumentException("Route may not be null");
-        }
-        if (tunit == null) {
-            throw new IllegalArgumentException("Time unit may not be null.");
-        }
-        if (this.isShutDown) {
-            throw new IllegalStateException("Session pool has been shut down");
-        }
+        return this.lease(route, state, connectTimeout, connectTimeout, tunit, callback);
+    }
+
+    /**
+     * @since 4.3
+     */
+    public Future<E> lease(
+            final T route, final Object state,
+            final long connectTimeout, final long leaseTimeout, final TimeUnit tunit,
+            final FutureCallback<E> callback) {
+        Args.notNull(route, "Route");
+        Args.notNull(tunit, "Time unit");
+        Asserts.check(!this.isShutDown.get(), "Connection pool shut down");
+        final BasicFuture<E> future = new BasicFuture<E>(callback);
         this.lock.lock();
         try {
-            long timeout = connectTimeout > 0 ? tunit.toMillis(connectTimeout) : 0;
-            BasicFuture<E> future = new BasicFuture<E>(callback);
-            LeaseRequest<T, C, E> request = new LeaseRequest<T, C, E>(route, state, timeout, future);
-            this.leasingRequests.add(request);
-
-            processPendingRequests();
-            return future;
+            final long timeout = connectTimeout > 0 ? tunit.toMillis(connectTimeout) : 0;
+            final LeaseRequest<T, C, E> request = new LeaseRequest<T, C, E>(route, state, timeout, leaseTimeout, future);
+            final boolean completed = processPendingRequest(request);
+            if (!request.isDone() && !completed) {
+                this.leasingRequests.add(request);
+            }
+            if (request.isDone()) {
+                this.completedRequests.add(request);
+            }
         } finally {
             this.lock.unlock();
         }
+        fireCallbacks();
+        return future;
     }
 
     public Future<E> lease(final T route, final Object state, final FutureCallback<E> callback) {
@@ -204,112 +285,164 @@ public abstract class AbstractNIOConnPool<T, C, E extends PoolEntry<T, C>>
         return lease(route, state, -1, TimeUnit.MICROSECONDS, null);
     }
 
-    public void release(final E entry, boolean reusable) {
+    public void release(final E entry, final boolean reusable) {
         if (entry == null) {
             return;
         }
-        if (this.isShutDown) {
+        if (this.isShutDown.get()) {
             return;
         }
         this.lock.lock();
         try {
             if (this.leased.remove(entry)) {
-                RouteSpecificPool<T, C, E> pool = getPool(entry.getRoute());
+                final RouteSpecificPool<T, C, E> pool = getPool(entry.getRoute());
                 pool.free(entry, reusable);
                 if (reusable) {
                     this.available.addFirst(entry);
+                    onRelease(entry);
                 } else {
                     entry.close();
                 }
-                processPendingRequests();
+                processNextPendingRequest();
             }
         } finally {
             this.lock.unlock();
         }
+        fireCallbacks();
     }
 
     private void processPendingRequests() {
-        ListIterator<LeaseRequest<T, C, E>> it = this.leasingRequests.listIterator();
+        final ListIterator<LeaseRequest<T, C, E>> it = this.leasingRequests.listIterator();
         while (it.hasNext()) {
-            LeaseRequest<T, C, E> request = it.next();
-
-            T route = request.getRoute();
-            Object state = request.getState();
-            long deadline = request.getDeadline();
-            BasicFuture<E> future = request.getFuture();
+            final LeaseRequest<T, C, E> request = it.next();
+            final boolean completed = processPendingRequest(request);
+            if (request.isDone() || completed) {
+                it.remove();
+            }
+            if (request.isDone()) {
+                this.completedRequests.add(request);
+            }
+        }
+    }
 
-            long now = System.currentTimeMillis();
-            if (now > deadline) {
+    private void processNextPendingRequest() {
+        final ListIterator<LeaseRequest<T, C, E>> it = this.leasingRequests.listIterator();
+        while (it.hasNext()) {
+            final LeaseRequest<T, C, E> request = it.next();
+            final boolean completed = processPendingRequest(request);
+            if (request.isDone() || completed) {
                 it.remove();
-                future.failed(new TimeoutException());
-                continue;
             }
+            if (request.isDone()) {
+                this.completedRequests.add(request);
+            }
+            if (completed) {
+                return;
+            }
+        }
+    }
 
-            RouteSpecificPool<T, C, E> pool = getPool(route);
-            E entry = null;
-            for (;;) {
-                entry = pool.getFree(state);
-                if (entry == null) {
-                    break;
-                }
-                if (entry.isClosed() || entry.isExpired(System.currentTimeMillis())) {
-                    entry.close();
-                    this.available.remove(entry);
-                    pool.free(entry, false);
-                } else {
-                    break;
-                }
+    private boolean processPendingRequest(final LeaseRequest<T, C, E> request) {
+        final T route = request.getRoute();
+        final Object state = request.getState();
+        final long deadline = request.getDeadline();
+
+        final long now = System.currentTimeMillis();
+        if (now > deadline) {
+            request.failed(new TimeoutException());
+            return false;
+        }
+
+        final RouteSpecificPool<T, C, E> pool = getPool(route);
+        E entry;
+        for (;;) {
+            entry = pool.getFree(state);
+            if (entry == null) {
+                break;
             }
-            if (entry != null) {
-                it.remove();
+            if (entry.isClosed() || entry.isExpired(System.currentTimeMillis())) {
+                entry.close();
                 this.available.remove(entry);
-                this.leased.add(entry);
-                future.completed(entry);
-                continue;
+                pool.free(entry, false);
+            } else {
+                break;
             }
+        }
+        if (entry != null) {
+            this.available.remove(entry);
+            this.leased.add(entry);
+            request.completed(entry);
+            onLease(entry);
+            return true;
+        }
+
+        // New connection is needed
+        final int maxPerRoute = getMax(route);
+        // Shrink the pool prior to allocating a new connection
+        final int excess = Math.max(0, pool.getAllocatedCount() + 1 - maxPerRoute);
+        if (excess > 0) {
+            for (int i = 0; i < excess; i++) {
+                final E lastUsed = pool.getLastUsed();
+                if (lastUsed == null) {
+                    break;
+                }
+                lastUsed.close();
+                this.available.remove(lastUsed);
+                pool.remove(lastUsed);
+            }
+        }
 
-            // New connection is needed
-            int maxPerRoute = getMax(route);
-            // Shrink the pool prior to allocating a new connection
-            int excess = Math.max(0, pool.getAllocatedCount() + 1 - maxPerRoute);
-            if (excess > 0) {
-                for (int i = 0; i < excess; i++) {
-                    E lastUsed = pool.getLastUsed();
-                    if (lastUsed == null) {
-                        break;
-                    }
+        if (pool.getAllocatedCount() < maxPerRoute) {
+            final int totalUsed = this.pending.size() + this.leased.size();
+            final int freeCapacity = Math.max(this.maxTotal - totalUsed, 0);
+            if (freeCapacity == 0) {
+                return false;
+            }
+            final int totalAvailable = this.available.size();
+            if (totalAvailable > freeCapacity - 1) {
+                if (!this.available.isEmpty()) {
+                    final E lastUsed = this.available.removeLast();
                     lastUsed.close();
-                    this.available.remove(lastUsed);
-                    pool.remove(lastUsed);
+                    final RouteSpecificPool<T, C, E> otherpool = getPool(lastUsed.getRoute());
+                    otherpool.remove(lastUsed);
                 }
             }
 
-            if (pool.getAllocatedCount() < maxPerRoute) {
-                int totalUsed = this.pending.size() + this.leased.size();
-                int freeCapacity = Math.max(this.maxTotal - totalUsed, 0);
-                if (freeCapacity == 0) {
-                    continue;
-                }
-                int totalAvailable = this.available.size();
-                if (totalAvailable > freeCapacity - 1) {
-                    if (!this.available.isEmpty()) {
-                        E lastUsed = this.available.removeLast();
-                        lastUsed.close();
-                        RouteSpecificPool<T, C, E> otherpool = getPool(lastUsed.getRoute());
-                        otherpool.remove(lastUsed);
-                    }
-                }
-                it.remove();
-                SessionRequest sessionRequest = this.ioreactor.connect(
-                        resolveRemoteAddress(route),
-                        resolveLocalAddress(route),
-                        route,
-                        this.sessionRequestCallback);
-                int timout = request.getConnectTimeout() < Integer.MAX_VALUE ?
-                        (int) request.getConnectTimeout() : Integer.MAX_VALUE;
-                sessionRequest.setConnectTimeout(timout);
-                this.pending.add(sessionRequest);
-                pool.addPending(sessionRequest, future);
+            final SocketAddress localAddress;
+            final SocketAddress remoteAddress;
+            try {
+                remoteAddress = this.addressResolver.resolveRemoteAddress(route);
+                localAddress = this.addressResolver.resolveLocalAddress(route);
+            } catch (final IOException ex) {
+                request.failed(ex);
+                return false;
+            }
+
+            final SessionRequest sessionRequest = this.ioreactor.connect(
+                    remoteAddress, localAddress, route, this.sessionRequestCallback);
+            final int timout = request.getConnectTimeout() < Integer.MAX_VALUE ?
+                    (int) request.getConnectTimeout() : Integer.MAX_VALUE;
+            sessionRequest.setConnectTimeout(timout);
+            this.pending.add(sessionRequest);
+            pool.addPending(sessionRequest, request.getFuture());
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    private void fireCallbacks() {
+        LeaseRequest<T, C, E> request;
+        while ((request = this.completedRequests.poll()) != null) {
+            final BasicFuture<E> future = request.getFuture();
+            final Exception ex = request.getException();
+            final E result = request.getResult();
+            if (ex != null) {
+                future.failed(ex);
+            } else if (result != null) {
+                future.completed(result);
+            } else {
+                future.cancel();
             }
         }
     }
@@ -317,100 +450,109 @@ public abstract class AbstractNIOConnPool<T, C, E extends PoolEntry<T, C>>
     public void validatePendingRequests() {
         this.lock.lock();
         try {
-            long now = System.currentTimeMillis();
-            ListIterator<LeaseRequest<T, C, E>> it = this.leasingRequests.listIterator();
+            final long now = System.currentTimeMillis();
+            final ListIterator<LeaseRequest<T, C, E>> it = this.leasingRequests.listIterator();
             while (it.hasNext()) {
-                LeaseRequest<T, C, E> request = it.next();
-                long deadline = request.getDeadline();
+                final LeaseRequest<T, C, E> request = it.next();
+                final long deadline = request.getDeadline();
                 if (now > deadline) {
                     it.remove();
-                    BasicFuture<E> future = request.getFuture();
-                    future.failed(new TimeoutException());
+                    request.failed(new TimeoutException());
+                    this.completedRequests.add(request);
                 }
             }
         } finally {
             this.lock.unlock();
         }
+        fireCallbacks();
     }
 
     protected void requestCompleted(final SessionRequest request) {
-        if (this.isShutDown) {
+        if (this.isShutDown.get()) {
             return;
         }
         @SuppressWarnings("unchecked")
+        final
         T route = (T) request.getAttachment();
         this.lock.lock();
         try {
             this.pending.remove(request);
-            RouteSpecificPool<T, C, E> pool = getPool(route);
-            IOSession session = request.getSession();
+            final RouteSpecificPool<T, C, E> pool = getPool(route);
+            final IOSession session = request.getSession();
             try {
-                C conn = this.connFactory.create(route, session);
-                E entry = pool.createEntry(request, conn);
+                final C conn = this.connFactory.create(route, session);
+                final E entry = pool.createEntry(request, conn);
                 this.leased.add(entry);
                 pool.completed(request, entry);
-
-            } catch (IOException ex) {
+                onLease(entry);
+            } catch (final IOException ex) {
                 pool.failed(request, ex);
             }
         } finally {
             this.lock.unlock();
         }
+        fireCallbacks();
     }
 
     protected void requestCancelled(final SessionRequest request) {
-        if (this.isShutDown) {
+        if (this.isShutDown.get()) {
             return;
         }
         @SuppressWarnings("unchecked")
+        final
         T route = (T) request.getAttachment();
         this.lock.lock();
         try {
             this.pending.remove(request);
-            RouteSpecificPool<T, C, E> pool = getPool(route);
+            final RouteSpecificPool<T, C, E> pool = getPool(route);
             pool.cancelled(request);
-            processPendingRequests();
+            processNextPendingRequest();
         } finally {
             this.lock.unlock();
         }
+        fireCallbacks();
     }
 
     protected void requestFailed(final SessionRequest request) {
-        if (this.isShutDown) {
+        if (this.isShutDown.get()) {
             return;
         }
         @SuppressWarnings("unchecked")
+        final
         T route = (T) request.getAttachment();
         this.lock.lock();
         try {
             this.pending.remove(request);
-            RouteSpecificPool<T, C, E> pool = getPool(route);
+            final RouteSpecificPool<T, C, E> pool = getPool(route);
             pool.failed(request, request.getException());
-            processPendingRequests();
+            processNextPendingRequest();
         } finally {
             this.lock.unlock();
         }
+        fireCallbacks();
     }
 
     protected void requestTimeout(final SessionRequest request) {
-        if (this.isShutDown) {
+        if (this.isShutDown.get()) {
             return;
         }
         @SuppressWarnings("unchecked")
+        final
         T route = (T) request.getAttachment();
         this.lock.lock();
         try {
             this.pending.remove(request);
-            RouteSpecificPool<T, C, E> pool = getPool(route);
+            final RouteSpecificPool<T, C, E> pool = getPool(route);
             pool.timeout(request);
-            processPendingRequests();
+            processNextPendingRequest();
         } finally {
             this.lock.unlock();
         }
+        fireCallbacks();
     }
 
     private int getMax(final T route) {
-        Integer v = this.maxPerRoute.get(route);
+        final Integer v = this.maxPerRoute.get(route);
         if (v != null) {
             return v.intValue();
         } else {
@@ -418,10 +560,8 @@ public abstract class AbstractNIOConnPool<T, C, E extends PoolEntry<T, C>>
         }
     }
 
-    public void setMaxTotal(int max) {
-        if (max <= 0) {
-            throw new IllegalArgumentException("Max value may not be negative or zero");
-        }
+    public void setMaxTotal(final int max) {
+        Args.positive(max, "Max value");
         this.lock.lock();
         try {
             this.maxTotal = max;
@@ -439,10 +579,8 @@ public abstract class AbstractNIOConnPool<T, C, E extends PoolEntry<T, C>>
         }
     }
 
-    public void setDefaultMaxPerRoute(int max) {
-        if (max <= 0) {
-            throw new IllegalArgumentException("Max value may not be negative or zero");
-        }
+    public void setDefaultMaxPerRoute(final int max) {
+        Args.positive(max, "Max value");
         this.lock.lock();
         try {
             this.defaultMaxPerRoute = max;
@@ -460,25 +598,19 @@ public abstract class AbstractNIOConnPool<T, C, E extends PoolEntry<T, C>>
         }
     }
 
-    public void setMaxPerRoute(final T route, int max) {
-        if (route == null) {
-            throw new IllegalArgumentException("Route may not be null");
-        }
-        if (max <= 0) {
-            throw new IllegalArgumentException("Max value may not be negative or zero");
-        }
+    public void setMaxPerRoute(final T route, final int max) {
+        Args.notNull(route, "Route");
+        Args.positive(max, "Max value");
         this.lock.lock();
         try {
-            this.maxPerRoute.put(route, max);
+            this.maxPerRoute.put(route, Integer.valueOf(max));
         } finally {
             this.lock.unlock();
         }
     }
 
-    public int getMaxPerRoute(T route) {
-        if (route == null) {
-            throw new IllegalArgumentException("Route may not be null");
-        }
+    public int getMaxPerRoute(final T route) {
+        Args.notNull(route, "Route");
         this.lock.lock();
         try {
             return getMax(route);
@@ -501,12 +633,10 @@ public abstract class AbstractNIOConnPool<T, C, E extends PoolEntry<T, C>>
     }
 
     public PoolStats getStats(final T route) {
-        if (route == null) {
-            throw new IllegalArgumentException("Route may not be null");
-        }
+        Args.notNull(route, "Route");
         this.lock.lock();
         try {
-            RouteSpecificPool<T, C, E> pool = getPool(route);
+            final RouteSpecificPool<T, C, E> pool = getPool(route);
             return new PoolStats(
                     pool.getLeasedCount(),
                     pool.getPendingCount(),
@@ -517,56 +647,81 @@ public abstract class AbstractNIOConnPool<T, C, E extends PoolEntry<T, C>>
         }
     }
 
-    public void closeIdle(long idletime, final TimeUnit tunit) {
-        if (tunit == null) {
-            throw new IllegalArgumentException("Time unit must not be null.");
+    /**
+     * Enumerates all available connections.
+     *
+     * @since 4.3
+     */
+    protected void enumAvailable(final PoolEntryCallback<T, C> callback) {
+        this.lock.lock();
+        try {
+            enumEntries(this.available.iterator(), callback);
+        } finally {
+            this.lock.unlock();
+        }
+    }
+
+    /**
+     * Enumerates all leased connections.
+     *
+     * @since 4.3
+     */
+    protected void enumLeased(final PoolEntryCallback<T, C> callback) {
+        this.lock.lock();
+        try {
+            enumEntries(this.leased.iterator(), callback);
+        } finally {
+            this.lock.unlock();
+        }
+    }
+
+    protected void enumEntries(final Iterator<E> it, final PoolEntryCallback<T, C> callback) {
+        while (it.hasNext()) {
+            final E entry = it.next();
+            callback.process(entry);
+            if (entry.isClosed()) {
+                final RouteSpecificPool<T, C, E> pool = getPool(entry.getRoute());
+                pool.remove(entry);
+                it.remove();
+            }
         }
+        processPendingRequests();
+    }
+
+    public void closeIdle(final long idletime, final TimeUnit tunit) {
+        Args.notNull(tunit, "Time unit");
         long time = tunit.toMillis(idletime);
         if (time < 0) {
             time = 0;
         }
-        long deadline = System.currentTimeMillis() - time;
-        this.lock.lock();
-        try {
-            Iterator<E> it = this.available.iterator();
-            while (it.hasNext()) {
-                E entry = it.next();
+        final long deadline = System.currentTimeMillis() - time;
+        enumAvailable(new PoolEntryCallback<T, C>() {
+
+            public void process(final PoolEntry<T, C> entry) {
                 if (entry.getUpdated() <= deadline) {
                     entry.close();
-                    RouteSpecificPool<T, C, E> pool = getPool(entry.getRoute());
-                    pool.remove(entry);
-                    it.remove();
                 }
             }
-            processPendingRequests();
-        } finally {
-            this.lock.unlock();
-        }
+
+        });
     }
 
     public void closeExpired() {
-        long now = System.currentTimeMillis();
-        this.lock.lock();
-        try {
-            Iterator<E> it = this.available.iterator();
-            while (it.hasNext()) {
-                E entry = it.next();
+        final long now = System.currentTimeMillis();
+        enumAvailable(new PoolEntryCallback<T, C>() {
+
+            public void process(final PoolEntry<T, C> entry) {
                 if (entry.isExpired(now)) {
                     entry.close();
-                    RouteSpecificPool<T, C, E> pool = getPool(entry.getRoute());
-                    pool.remove(entry);
-                    it.remove();
                 }
             }
-            processPendingRequests();
-        } finally {
-            this.lock.unlock();
-        }
+
+        });
     }
 
     @Override
     public String toString() {
-        StringBuilder buffer = new StringBuilder();
+        final StringBuilder buffer = new StringBuilder();
         buffer.append("[leased: ");
         buffer.append(this.leased);
         buffer.append("][available: ");
diff --git a/httpcore-nio/src/main/java/org/apache/http/nio/pool/LeaseRequest.java b/httpcore-nio/src/main/java/org/apache/http/nio/pool/LeaseRequest.java
index 629f25f..8e7d5e8 100644
--- a/httpcore-nio/src/main/java/org/apache/http/nio/pool/LeaseRequest.java
+++ b/httpcore-nio/src/main/java/org/apache/http/nio/pool/LeaseRequest.java
@@ -30,6 +30,8 @@ import org.apache.http.annotation.Immutable;
 import org.apache.http.concurrent.BasicFuture;
 import org.apache.http.pool.PoolEntry;
 
+import java.util.concurrent.atomic.AtomicBoolean;
+
 @Immutable
 class LeaseRequest<T, C, E extends PoolEntry<T, C>> {
 
@@ -38,19 +40,32 @@ class LeaseRequest<T, C, E extends PoolEntry<T, C>> {
     private final long connectTimeout;
     private final long deadline;
     private final BasicFuture<E> future;
+    private final AtomicBoolean completed;
+    private volatile E result;
+    private volatile Exception ex;
 
+    /**
+     * Contructor
+     * @param route route
+     * @param state state
+     * @param connectTimeout http connection timeout
+     * @param leaseTimeout timeout to wait in a request queue until kicked off
+     * @param future future callback
+     */
     public LeaseRequest(
             final T route,
             final Object state,
             final long connectTimeout,
+            final long leaseTimeout,
             final BasicFuture<E> future) {
         super();
         this.route = route;
         this.state = state;
         this.connectTimeout = connectTimeout;
-        this.deadline = connectTimeout > 0 ? System.currentTimeMillis() + connectTimeout :
-            Long.MAX_VALUE;
+        this.deadline = leaseTimeout > 0 ? System.currentTimeMillis() + leaseTimeout :
+                Long.MAX_VALUE;
         this.future = future;
+        this.completed = new AtomicBoolean(false);
     }
 
     public T getRoute() {
@@ -69,13 +84,37 @@ class LeaseRequest<T, C, E extends PoolEntry<T, C>> {
         return this.deadline;
     }
 
+    public boolean isDone() {
+        return this.completed.get();
+    }
+
+    public void failed(final Exception ex) {
+        if (this.completed.compareAndSet(false, true)) {
+            this.ex = ex;
+        }
+    }
+
+    public void completed(final E result) {
+        if (this.completed.compareAndSet(false, true)) {
+            this.result = result;
+        }
+    }
+
     public BasicFuture<E> getFuture() {
         return this.future;
     }
 
+    public E getResult() {
+        return this.result;
+    }
+
+    public Exception getException() {
+        return this.ex;
+    }
+
     @Override
     public String toString() {
-        StringBuilder buffer = new StringBuilder();
+        final StringBuilder buffer = new StringBuilder();
         buffer.append("[");
         buffer.append(this.route);
         buffer.append("][");
diff --git a/httpcore-nio/src/main/java/org/apache/http/nio/pool/RouteSpecificPool.java b/httpcore-nio/src/main/java/org/apache/http/nio/pool/RouteSpecificPool.java
index 054fcf7..c2bd31b 100644
--- a/httpcore-nio/src/main/java/org/apache/http/nio/pool/RouteSpecificPool.java
+++ b/httpcore-nio/src/main/java/org/apache/http/nio/pool/RouteSpecificPool.java
@@ -38,6 +38,8 @@ import org.apache.http.annotation.NotThreadSafe;
 import org.apache.http.concurrent.BasicFuture;
 import org.apache.http.nio.reactor.SessionRequest;
 import org.apache.http.pool.PoolEntry;
+import org.apache.http.util.Args;
+import org.apache.http.util.Asserts;
 
 @NotThreadSafe
 abstract class RouteSpecificPool<T, C, E extends PoolEntry<T, C>> {
@@ -76,9 +78,9 @@ abstract class RouteSpecificPool<T, C, E extends PoolEntry<T, C>> {
     public E getFree(final Object state) {
         if (!this.available.isEmpty()) {
             if (state != null) {
-                Iterator<E> it = this.available.iterator();
+                final Iterator<E> it = this.available.iterator();
                 while (it.hasNext()) {
-                    E entry = it.next();
+                    final E entry = it.next();
                     if (state.equals(entry.getState())) {
                         it.remove();
                         this.leased.add(entry);
@@ -86,9 +88,9 @@ abstract class RouteSpecificPool<T, C, E extends PoolEntry<T, C>> {
                     }
                 }
             }
-            Iterator<E> it = this.available.iterator();
+            final Iterator<E> it = this.available.iterator();
             while (it.hasNext()) {
-                E entry = it.next();
+                final E entry = it.next();
                 if (entry.getState() == null) {
                     it.remove();
                     this.leased.add(entry);
@@ -108,9 +110,7 @@ abstract class RouteSpecificPool<T, C, E extends PoolEntry<T, C>> {
     }
 
     public boolean remove(final E entry) {
-        if (entry == null) {
-            throw new IllegalArgumentException("Pool entry may not be null");
-        }
+        Args.notNull(entry, "Pool entry");
         if (!this.available.remove(entry)) {
             if (!this.leased.remove(entry)) {
                 return false;
@@ -119,15 +119,10 @@ abstract class RouteSpecificPool<T, C, E extends PoolEntry<T, C>> {
         return true;
     }
 
-    public void free(final E entry, boolean reusable) {
-        if (entry == null) {
-            throw new IllegalArgumentException("Pool entry may not be null");
-        }
-        boolean found = this.leased.remove(entry);
-        if (!found) {
-            throw new IllegalStateException("Entry " + entry +
-                    " has not been leased from this pool");
-        }
+    public void free(final E entry, final boolean reusable) {
+        Args.notNull(entry, "Pool entry");
+        final boolean found = this.leased.remove(entry);
+        Asserts.check(found, "Entry %s has not been leased from this pool", entry);
         if (reusable) {
             this.available.addFirst(entry);
         }
@@ -140,49 +135,47 @@ abstract class RouteSpecificPool<T, C, E extends PoolEntry<T, C>> {
     }
 
     private BasicFuture<E> removeRequest(final SessionRequest request) {
-        BasicFuture<E> future = this.pending.remove(request);
-        if (future == null) {
-            throw new IllegalStateException("Invalid session request");
-        }
+        final BasicFuture<E> future = this.pending.remove(request);
+        Asserts.notNull(future, "Session request future");
         return future;
     }
 
     public E createEntry(final SessionRequest request, final C conn) {
-        E entry = createEntry(this.route, conn);
+        final E entry = createEntry(this.route, conn);
         this.leased.add(entry);
         return entry;
     }
 
-    public void completed(SessionRequest request, E entry) {
-        BasicFuture<E> future = removeRequest(request);
+    public void completed(final SessionRequest request, final E entry) {
+        final BasicFuture<E> future = removeRequest(request);
         future.completed(entry);
     }
 
     public void cancelled(final SessionRequest request) {
-        BasicFuture<E> future = removeRequest(request);
+        final BasicFuture<E> future = removeRequest(request);
         future.cancel(true);
     }
 
     public void failed(final SessionRequest request, final Exception ex) {
-        BasicFuture<E> future = removeRequest(request);
+        final BasicFuture<E> future = removeRequest(request);
         future.failed(ex);
     }
 
     public void timeout(final SessionRequest request) {
-        BasicFuture<E> future = removeRequest(request);
+        final BasicFuture<E> future = removeRequest(request);
         future.failed(new SocketTimeoutException());
     }
 
     public void shutdown() {
-        for (SessionRequest sessionRequest: this.pending.keySet()) {
+        for (final SessionRequest sessionRequest: this.pending.keySet()) {
             sessionRequest.cancel();
         }
         this.pending.clear();
-        for (E entry: this.available) {
+        for (final E entry: this.available) {
             entry.close();
         }
         this.available.clear();
-        for (E entry: this.leased) {
+        for (final E entry: this.leased) {
             entry.close();
         }
         this.leased.clear();
@@ -190,7 +183,7 @@ abstract class RouteSpecificPool<T, C, E extends PoolEntry<T, C>> {
 
     @Override
     public String toString() {
-        StringBuilder buffer = new StringBuilder();
+        final StringBuilder buffer = new StringBuilder();
         buffer.append("[route: ");
         buffer.append(this.route);
         buffer.append("][leased: ");
diff --git a/httpcore/src/main/java/org/apache/http/concurrent/FutureCallback.java b/httpcore-nio/src/main/java/org/apache/http/nio/pool/SocketAddressResolver.java
similarity index 75%
copy from httpcore/src/main/java/org/apache/http/concurrent/FutureCallback.java
copy to httpcore-nio/src/main/java/org/apache/http/nio/pool/SocketAddressResolver.java
index 228c659..2cf348d 100644
--- a/httpcore/src/main/java/org/apache/http/concurrent/FutureCallback.java
+++ b/httpcore-nio/src/main/java/org/apache/http/nio/pool/SocketAddressResolver.java
@@ -24,22 +24,21 @@
  * <http://www.apache.org/>.
  *
  */
-package org.apache.http.concurrent;
 
-import java.util.concurrent.Future;
+package org.apache.http.nio.pool;
+
+import java.io.IOException;
+import java.net.SocketAddress;
 
 /**
- * A callback interface that gets invoked upon completion of a {@link Future}.
- *
- * @param <T> the future result type returned by this callback.
- * @since 4.2
+ * Strategy that resolves an abstract connection route to a local or a remote {@link SocketAddress}.
+ * .
+ * @since 4.3
  */
-public interface FutureCallback<T> {
-
-    void completed(T result);
+public interface SocketAddressResolver<T> {
 
-    void failed(Exception ex);
+    SocketAddress resolveLocalAddress(T route) throws IOException;
 
-    void cancelled();
+    SocketAddress resolveRemoteAddress(T route) throws IOException;
 
 }
diff --git a/httpcore-nio/src/main/java/org/apache/http/nio/protocol/AbstractAsyncRequestConsumer.java b/httpcore-nio/src/main/java/org/apache/http/nio/protocol/AbstractAsyncRequestConsumer.java
index 92825e1..63d532e 100644
--- a/httpcore-nio/src/main/java/org/apache/http/nio/protocol/AbstractAsyncRequestConsumer.java
+++ b/httpcore-nio/src/main/java/org/apache/http/nio/protocol/AbstractAsyncRequestConsumer.java
@@ -111,15 +111,23 @@ public abstract class AbstractAsyncRequestConsumer<T> implements HttpAsyncReques
     protected abstract void releaseResources();
 
     /**
+     * Invoked when the consumer is being closed.
+     *
+     * @since 4.3
+     */
+    protected void onClose() throws IOException {
+    }
+
+    /**
      * Use {@link #onRequestReceived(HttpRequest)} instead.
      */
     public final synchronized void requestReceived(
             final HttpRequest request) throws HttpException, IOException {
         onRequestReceived(request);
         if (request instanceof HttpEntityEnclosingRequest) {
-            HttpEntity entity = ((HttpEntityEnclosingRequest) request).getEntity();
+            final HttpEntity entity = ((HttpEntityEnclosingRequest) request).getEntity();
             if (entity != null) {
-                ContentType contentType = ContentType.getOrDefault(entity);
+                final ContentType contentType = ContentType.getOrDefault(entity);
                 onEntityEnclosed(entity, contentType);
             }
         }
@@ -143,7 +151,7 @@ public abstract class AbstractAsyncRequestConsumer<T> implements HttpAsyncReques
         this.completed = true;
         try {
             this.result = buildResult(context);
-        } catch (Exception ex) {
+        } catch (final Exception ex) {
             this.ex = ex;
         } finally {
             releaseResources();
@@ -165,6 +173,7 @@ public abstract class AbstractAsyncRequestConsumer<T> implements HttpAsyncReques
         }
         this.completed = true;
         releaseResources();
+        onClose();
     }
 
     public Exception getException() {
diff --git a/httpcore-nio/src/main/java/org/apache/http/nio/protocol/AbstractAsyncResponseConsumer.java b/httpcore-nio/src/main/java/org/apache/http/nio/protocol/AbstractAsyncResponseConsumer.java
index f452e98..67adca9 100644
--- a/httpcore-nio/src/main/java/org/apache/http/nio/protocol/AbstractAsyncResponseConsumer.java
+++ b/httpcore-nio/src/main/java/org/apache/http/nio/protocol/AbstractAsyncResponseConsumer.java
@@ -109,14 +109,22 @@ public abstract class AbstractAsyncResponseConsumer<T> implements HttpAsyncRespo
     protected abstract void releaseResources();
 
     /**
+     * Invoked when the consumer is being closed.
+     *
+     * @since 4.3
+     */
+    protected void onClose() throws IOException {
+    }
+
+    /**
      * Use {@link #onResponseReceived(HttpResponse)} instead.
      */
     public final synchronized void responseReceived(
             final HttpResponse response) throws IOException, HttpException {
         onResponseReceived(response);
-        HttpEntity entity = response.getEntity();
+        final HttpEntity entity = response.getEntity();
         if (entity != null) {
-            ContentType contentType = ContentType.getOrDefault(entity);
+            final ContentType contentType = ContentType.getOrDefault(entity);
             onEntityEnclosed(entity, contentType);
         }
     }
@@ -139,7 +147,7 @@ public abstract class AbstractAsyncResponseConsumer<T> implements HttpAsyncRespo
         this.completed = true;
         try {
             this.result = buildResult(context);
-        } catch (Exception ex) {
+        } catch (final Exception ex) {
             this.ex = ex;
         } finally {
             releaseResources();
@@ -164,12 +172,13 @@ public abstract class AbstractAsyncResponseConsumer<T> implements HttpAsyncRespo
         releaseResources();
     }
 
-    public final synchronized void close() {
+    public final synchronized void close() throws IOException {
         if (this.completed) {
             return;
         }
         this.completed = true;
         releaseResources();
+        onClose();
     }
 
     public Exception getException() {
diff --git a/httpcore-nio/src/main/java/org/apache/http/nio/protocol/BasicAsyncRequestExecutionHandler.java b/httpcore-nio/src/main/java/org/apache/http/nio/protocol/BasicAsyncClientExchangeHandler.java
similarity index 57%
rename from httpcore-nio/src/main/java/org/apache/http/nio/protocol/BasicAsyncRequestExecutionHandler.java
rename to httpcore-nio/src/main/java/org/apache/http/nio/protocol/BasicAsyncClientExchangeHandler.java
index 751fed1..34f27ca 100644
--- a/httpcore-nio/src/main/java/org/apache/http/nio/protocol/BasicAsyncRequestExecutionHandler.java
+++ b/httpcore-nio/src/main/java/org/apache/http/nio/protocol/BasicAsyncClientExchangeHandler.java
@@ -30,84 +30,89 @@ package org.apache.http.nio.protocol;
 import java.io.IOException;
 import java.util.concurrent.Future;
 
+import org.apache.http.ConnectionClosedException;
 import org.apache.http.ConnectionReuseStrategy;
 import org.apache.http.HttpException;
-import org.apache.http.HttpHost;
 import org.apache.http.HttpRequest;
 import org.apache.http.HttpResponse;
 import org.apache.http.concurrent.BasicFuture;
 import org.apache.http.concurrent.FutureCallback;
+import org.apache.http.impl.DefaultConnectionReuseStrategy;
 import org.apache.http.nio.ContentDecoder;
 import org.apache.http.nio.ContentEncoder;
 import org.apache.http.nio.IOControl;
-import org.apache.http.params.DefaultedHttpParams;
-import org.apache.http.params.HttpParams;
+import org.apache.http.nio.NHttpClientConnection;
 import org.apache.http.protocol.HttpContext;
+import org.apache.http.protocol.HttpCoreContext;
 import org.apache.http.protocol.HttpProcessor;
+import org.apache.http.util.Args;
 
 /**
- * Basic implementation of {@link HttpAsyncRequestExecutionHandler} that executes
+ * Basic implementation of {@link HttpAsyncClientExchangeHandler} that executes
  * a single HTTP request / response exchange.
  *
  * @param <T> the result type of request execution.
- * @since 4.2
+ * @since 4.3
  */
-public class BasicAsyncRequestExecutionHandler<T> implements HttpAsyncRequestExecutionHandler<T> {
+public class BasicAsyncClientExchangeHandler<T> implements HttpAsyncClientExchangeHandler {
 
     private final HttpAsyncRequestProducer requestProducer;
     private final HttpAsyncResponseConsumer<T> responseConsumer;
     private final BasicFuture<T> future;
     private final HttpContext localContext;
+    private final NHttpClientConnection conn;
     private final HttpProcessor httppocessor;
-    private final ConnectionReuseStrategy reuseStrategy;
-    private final HttpParams params;
+    private final ConnectionReuseStrategy connReuseStrategy;
 
     private volatile boolean requestSent;
-
-    public BasicAsyncRequestExecutionHandler(
+    private volatile boolean keepAlive;
+
+    /**
+     * Creates new instance of BasicAsyncRequestExecutionHandler.
+     *
+     * @param requestProducer the request producer.
+     * @param responseConsumer the response consumer.
+     * @param callback the future callback invoked when the operation is completed.
+     * @param localContext the local execution context.
+     * @param conn the actual connection.
+     * @param httppocessor the HTTP protocol processor.
+     * @param connReuseStrategy the connection re-use strategy.
+     */
+    public BasicAsyncClientExchangeHandler(
             final HttpAsyncRequestProducer requestProducer,
             final HttpAsyncResponseConsumer<T> responseConsumer,
             final FutureCallback<T> callback,
             final HttpContext localContext,
+            final NHttpClientConnection conn,
             final HttpProcessor httppocessor,
-            final ConnectionReuseStrategy reuseStrategy,
-            final HttpParams params) {
+            final ConnectionReuseStrategy connReuseStrategy) {
         super();
-        if (requestProducer == null) {
-            throw new IllegalArgumentException("Request producer may not be null");
-        }
-        if (responseConsumer == null) {
-            throw new IllegalArgumentException("Response consumer may not be null");
-        }
-        if (localContext == null) {
-            throw new IllegalArgumentException("HTTP context may not be null");
-        }
-        if (httppocessor == null) {
-            throw new IllegalArgumentException("HTTP processor may not be null");
-        }
-        if (reuseStrategy == null) {
-            throw new IllegalArgumentException("Connection reuse strategy may not be null");
-        }
-        if (params == null) {
-            throw new IllegalArgumentException("HTTP parameters may not be null");
-        }
-        this.requestProducer = requestProducer;
-        this.responseConsumer = responseConsumer;
+        this.requestProducer = Args.notNull(requestProducer, "Request producer");
+        this.responseConsumer = Args.notNull(responseConsumer, "Response consumer");
         this.future = new BasicFuture<T>(callback);
-        this.localContext = localContext;
-        this.httppocessor = httppocessor;
-        this.reuseStrategy = reuseStrategy;
-        this.params = params;
-    }
-
-    public BasicAsyncRequestExecutionHandler(
+        this.localContext = Args.notNull(localContext, "HTTP context");
+        this.conn = Args.notNull(conn, "HTTP connection");
+        this.httppocessor = Args.notNull(httppocessor, "HTTP processor");
+        this.connReuseStrategy = connReuseStrategy != null ? connReuseStrategy :
+            DefaultConnectionReuseStrategy.INSTANCE;
+    }
+
+    /**
+     * Creates new instance of BasicAsyncRequestExecutionHandler.
+     *
+     * @param requestProducer the request producer.
+     * @param responseConsumer the response consumer.
+     * @param localContext the local execution context.
+     * @param conn the actual connection.
+     * @param httppocessor the HTTP protocol processor.
+     */
+    public BasicAsyncClientExchangeHandler(
             final HttpAsyncRequestProducer requestProducer,
             final HttpAsyncResponseConsumer<T> responseConsumer,
             final HttpContext localContext,
-            final HttpProcessor httppocessor,
-            final ConnectionReuseStrategy reuseStrategy,
-            final HttpParams params) {
-        this(requestProducer, responseConsumer, null, localContext, httppocessor, reuseStrategy, params);
+            final NHttpClientConnection conn,
+            final HttpProcessor httppocessor) {
+        this(requestProducer, responseConsumer, null, localContext, conn, httppocessor, null);
     }
 
     public Future<T> getFuture() {
@@ -117,11 +122,11 @@ public class BasicAsyncRequestExecutionHandler<T> implements HttpAsyncRequestExe
     private void releaseResources() {
         try {
             this.responseConsumer.close();
-        } catch (IOException ex) {
+        } catch (final IOException ex) {
         }
         try {
             this.requestProducer.close();
-        } catch (IOException ex) {
+        } catch (final IOException ex) {
         }
     }
 
@@ -132,13 +137,11 @@ public class BasicAsyncRequestExecutionHandler<T> implements HttpAsyncRequestExe
         }
     }
 
-    public HttpHost getTarget() {
-        return this.requestProducer.getTarget();
-    }
-
     public HttpRequest generateRequest() throws IOException, HttpException {
-        HttpRequest request = this.requestProducer.generateRequest();
-        request.setParams(new DefaultedHttpParams(request.getParams(), this.params));
+        final HttpRequest request = this.requestProducer.generateRequest();
+        this.localContext.setAttribute(HttpCoreContext.HTTP_REQUEST, request);
+        this.localContext.setAttribute(HttpCoreContext.HTTP_CONNECTION, this.conn);
+        this.httppocessor.process(request, this.localContext);
         return request;
     }
 
@@ -147,21 +150,16 @@ public class BasicAsyncRequestExecutionHandler<T> implements HttpAsyncRequestExe
         this.requestProducer.produceContent(encoder, ioctrl);
     }
 
-    public void requestCompleted(final HttpContext context) {
-        this.requestProducer.requestCompleted(context);
+    public void requestCompleted() {
+        this.requestProducer.requestCompleted(this.localContext);
         this.requestSent = true;
     }
 
-    public boolean isRepeatable() {
-        return false;
-    }
-
-    public void resetRequest() {
-    }
-
     public void responseReceived(final HttpResponse response) throws IOException, HttpException {
-        response.setParams(new DefaultedHttpParams(response.getParams(), this.params));
+        this.localContext.setAttribute(HttpCoreContext.HTTP_RESPONSE, response);
+        this.httppocessor.process(response, this.localContext);
         this.responseConsumer.responseReceived(response);
+        this.keepAlive = this.connReuseStrategy.keepAlive(response, this.localContext);
     }
 
     public void consumeContent(
@@ -169,6 +167,30 @@ public class BasicAsyncRequestExecutionHandler<T> implements HttpAsyncRequestExe
         this.responseConsumer.consumeContent(decoder, ioctrl);
     }
 
+    public void responseCompleted() throws IOException {
+        try {
+            if (!this.keepAlive) {
+                this.conn.close();
+            }
+            this.responseConsumer.responseCompleted(this.localContext);
+            final T result = this.responseConsumer.getResult();
+            final Exception ex = this.responseConsumer.getException();
+            if (ex == null) {
+                this.future.completed(result);
+            } else {
+                this.future.failed(ex);
+            }
+            releaseResources();
+        } catch (final RuntimeException ex) {
+            failed(ex);
+            throw ex;
+        }
+    }
+
+    public void inputTerminated() {
+        failed(new ConnectionClosedException("Connection closed"));
+    }
+
     public void failed(final Exception ex) {
         try {
             if (!this.requestSent) {
@@ -186,53 +208,16 @@ public class BasicAsyncRequestExecutionHandler<T> implements HttpAsyncRequestExe
 
     public boolean cancel() {
         try {
-            boolean cancelled = this.responseConsumer.cancel();
+            final boolean cancelled = this.responseConsumer.cancel();
             this.future.cancel();
             releaseResources();
             return cancelled;
-        } catch (RuntimeException ex) {
-            failed(ex);
-            throw ex;
-        }
-    }
-
-    public void responseCompleted(final HttpContext context) {
-        try {
-            this.responseConsumer.responseCompleted(context);
-            T result = this.responseConsumer.getResult();
-            Exception ex = this.responseConsumer.getException();
-            if (ex == null) {
-                this.future.completed(result);
-            } else {
-                this.future.failed(ex);
-            }
-            releaseResources();
-        } catch (RuntimeException ex) {
+        } catch (final RuntimeException ex) {
             failed(ex);
             throw ex;
         }
     }
 
-    public T getResult() {
-        return this.responseConsumer.getResult();
-    }
-
-    public Exception getException() {
-        return this.responseConsumer.getException();
-    }
-
-    public HttpContext getContext() {
-        return this.localContext;
-    }
-
-    public HttpProcessor getHttpProcessor() {
-        return this.httppocessor;
-    }
-
-    public ConnectionReuseStrategy getConnectionReuseStrategy() {
-        return this.reuseStrategy;
-    }
-
     public boolean isDone() {
         return this.responseConsumer.isDone();
     }
diff --git a/httpcore-nio/src/main/java/org/apache/http/nio/protocol/BasicAsyncRequestConsumer.java b/httpcore-nio/src/main/java/org/apache/http/nio/protocol/BasicAsyncRequestConsumer.java
index 7962daf..e4b23bd 100644
--- a/httpcore-nio/src/main/java/org/apache/http/nio/protocol/BasicAsyncRequestConsumer.java
+++ b/httpcore-nio/src/main/java/org/apache/http/nio/protocol/BasicAsyncRequestConsumer.java
@@ -40,6 +40,7 @@ import org.apache.http.nio.entity.ContentBufferEntity;
 import org.apache.http.nio.util.HeapByteBufferAllocator;
 import org.apache.http.nio.util.SimpleInputBuffer;
 import org.apache.http.protocol.HttpContext;
+import org.apache.http.util.Asserts;
 
 /**
  * Basic implementation of {@link HttpAsyncRequestConsumer}. Please note that
@@ -81,9 +82,7 @@ public class BasicAsyncRequestConsumer extends AbstractAsyncRequestConsumer<Http
     @Override
     protected void onContentReceived(
             final ContentDecoder decoder, final IOControl ioctrl) throws IOException {
-        if (this.buf == null) {
-            throw new IllegalStateException("Content buffer is null");
-        }
+        Asserts.notNull(this.buf, "Content buffer");
         this.buf.consumeContent(decoder);
     }
 
diff --git a/httpcore-nio/src/main/java/org/apache/http/nio/protocol/BasicAsyncRequestHandler.java b/httpcore-nio/src/main/java/org/apache/http/nio/protocol/BasicAsyncRequestHandler.java
index b9ad29c..95d0d7b 100644
--- a/httpcore-nio/src/main/java/org/apache/http/nio/protocol/BasicAsyncRequestHandler.java
+++ b/httpcore-nio/src/main/java/org/apache/http/nio/protocol/BasicAsyncRequestHandler.java
@@ -34,6 +34,7 @@ import org.apache.http.HttpRequest;
 import org.apache.http.annotation.Immutable;
 import org.apache.http.protocol.HttpContext;
 import org.apache.http.protocol.HttpRequestHandler;
+import org.apache.http.util.Args;
 
 /**
  * Basic implementation of {@link HttpAsyncRequestHandler} that delegates
@@ -50,9 +51,7 @@ public class BasicAsyncRequestHandler implements HttpAsyncRequestHandler<HttpReq
 
     public BasicAsyncRequestHandler(final HttpRequestHandler handler) {
         super();
-        if (handler == null) {
-            throw new IllegalArgumentException("Request handler may not be null");
-        }
+        Args.notNull(handler, "Request handler");
         this.handler = handler;
     }
 
diff --git a/httpcore-nio/src/main/java/org/apache/http/nio/protocol/BasicAsyncRequestProducer.java b/httpcore-nio/src/main/java/org/apache/http/nio/protocol/BasicAsyncRequestProducer.java
index c609548..92880ce 100644
--- a/httpcore-nio/src/main/java/org/apache/http/nio/protocol/BasicAsyncRequestProducer.java
+++ b/httpcore-nio/src/main/java/org/apache/http/nio/protocol/BasicAsyncRequestProducer.java
@@ -38,6 +38,7 @@ import org.apache.http.nio.IOControl;
 import org.apache.http.nio.entity.EntityAsyncContentProducer;
 import org.apache.http.nio.entity.HttpAsyncContentProducer;
 import org.apache.http.protocol.HttpContext;
+import org.apache.http.util.Args;
 
 /**
  * Basic implementation of {@link HttpAsyncRequestProducer}. The producer
@@ -72,15 +73,9 @@ public class BasicAsyncRequestProducer implements HttpAsyncRequestProducer {
             final HttpEntityEnclosingRequest request,
             final HttpAsyncContentProducer producer) {
         super();
-        if (target == null) {
-            throw new IllegalArgumentException("HTTP host may not be null");
-        }
-        if (request == null) {
-            throw new IllegalArgumentException("HTTP request may not be null");
-        }
-        if (producer == null) {
-            throw new IllegalArgumentException("HTTP content producer may not be null");
-        }
+        Args.notNull(target, "HTTP host");
+        Args.notNull(request, "HTTP request");
+        Args.notNull(producer, "HTTP content producer");
         this.target = target;
         this.request = request;
         this.producer = producer;
@@ -95,16 +90,12 @@ public class BasicAsyncRequestProducer implements HttpAsyncRequestProducer {
      * @param request request message.
      */
     public BasicAsyncRequestProducer(final HttpHost target, final HttpRequest request) {
-        if (target == null) {
-            throw new IllegalArgumentException("HTTP host may not be null");
-        }
-        if (request == null) {
-            throw new IllegalArgumentException("HTTP request may not be null");
-        }
+        Args.notNull(target, "HTTP host");
+        Args.notNull(request, "HTTP request");
         this.target = target;
         this.request = request;
         if (request instanceof HttpEntityEnclosingRequest) {
-            HttpEntity entity = ((HttpEntityEnclosingRequest) request).getEntity();
+            final HttpEntity entity = ((HttpEntityEnclosingRequest) request).getEntity();
             if (entity != null) {
                 if (entity instanceof HttpAsyncContentProducer) {
                     this.producer = (HttpAsyncContentProducer) entity;
diff --git a/httpcore-nio/src/main/java/org/apache/http/nio/protocol/BasicAsyncResponseConsumer.java b/httpcore-nio/src/main/java/org/apache/http/nio/protocol/BasicAsyncResponseConsumer.java
index f3ed19a..29196bd 100644
--- a/httpcore-nio/src/main/java/org/apache/http/nio/protocol/BasicAsyncResponseConsumer.java
+++ b/httpcore-nio/src/main/java/org/apache/http/nio/protocol/BasicAsyncResponseConsumer.java
@@ -39,6 +39,7 @@ import org.apache.http.nio.entity.ContentBufferEntity;
 import org.apache.http.nio.util.HeapByteBufferAllocator;
 import org.apache.http.nio.util.SimpleInputBuffer;
 import org.apache.http.protocol.HttpContext;
+import org.apache.http.util.Asserts;
 
 /**
  * Basic implementation of {@link HttpAsyncResponseConsumer}. Please note that
@@ -79,9 +80,7 @@ public class BasicAsyncResponseConsumer extends AbstractAsyncResponseConsumer<Ht
     @Override
     protected void onContentReceived(
             final ContentDecoder decoder, final IOControl ioctrl) throws IOException {
-        if (this.buf == null) {
-            throw new IllegalStateException("Content buffer is null");
-        }
+        Asserts.notNull(this.buf, "Content buffer");
         this.buf.consumeContent(decoder);
     }
 
diff --git a/httpcore-nio/src/main/java/org/apache/http/nio/protocol/BasicAsyncResponseProducer.java b/httpcore-nio/src/main/java/org/apache/http/nio/protocol/BasicAsyncResponseProducer.java
index c6fe5f3..efb245f 100644
--- a/httpcore-nio/src/main/java/org/apache/http/nio/protocol/BasicAsyncResponseProducer.java
+++ b/httpcore-nio/src/main/java/org/apache/http/nio/protocol/BasicAsyncResponseProducer.java
@@ -37,6 +37,7 @@ import org.apache.http.nio.IOControl;
 import org.apache.http.nio.entity.EntityAsyncContentProducer;
 import org.apache.http.nio.entity.HttpAsyncContentProducer;
 import org.apache.http.protocol.HttpContext;
+import org.apache.http.util.Args;
 
 /**
  * Basic implementation of {@link HttpAsyncResponseProducer}. The producer
@@ -69,12 +70,8 @@ public class BasicAsyncResponseProducer implements HttpAsyncResponseProducer {
             final HttpResponse response,
             final HttpAsyncContentProducer producer) {
         super();
-        if (response == null) {
-            throw new IllegalArgumentException("HTTP response may not be null");
-        }
-        if (producer == null) {
-            throw new IllegalArgumentException("HTTP content producer may not be null");
-        }
+        Args.notNull(response, "HTTP response");
+        Args.notNull(producer, "HTTP content producer");
         this.response = response;
         this.producer = producer;
     }
@@ -88,11 +85,9 @@ public class BasicAsyncResponseProducer implements HttpAsyncResponseProducer {
      */
     public BasicAsyncResponseProducer(final HttpResponse response) {
         super();
-        if (response == null) {
-            throw new IllegalArgumentException("HTTP response may not be null");
-        }
+        Args.notNull(response, "HTTP response");
         this.response = response;
-        HttpEntity entity = response.getEntity();
+        final HttpEntity entity = response.getEntity();
         if (entity != null) {
             if (entity instanceof HttpAsyncContentProducer) {
                 this.producer = (HttpAsyncContentProducer) entity;
diff --git a/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncRequestProducer.java b/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncClientExchangeHandler.java
similarity index 51%
copy from httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncRequestProducer.java
copy to httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncClientExchangeHandler.java
index 76f0aef..08f24b2 100644
--- a/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncRequestProducer.java
+++ b/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncClientExchangeHandler.java
@@ -24,45 +24,44 @@
  * <http://www.apache.org/>.
  *
  */
+
 package org.apache.http.nio.protocol;
 
 import java.io.Closeable;
 import java.io.IOException;
 
-import org.apache.http.HttpEntityEnclosingRequest;
 import org.apache.http.HttpException;
-import org.apache.http.HttpHost;
 import org.apache.http.HttpRequest;
+import org.apache.http.HttpResponse;
+import org.apache.http.concurrent.Cancellable;
+import org.apache.http.nio.ContentDecoder;
 import org.apache.http.nio.ContentEncoder;
 import org.apache.http.nio.IOControl;
-import org.apache.http.protocol.HttpContext;
 
 /**
- * <tt>HttpAsyncRequestProducer</tt> is a callback interface whose methods
- * get invoked to generate an HTTP request message and to stream message
- * content to a non-blocking HTTP connection.
+ * <tt>HttpAsyncClientExchangeHandler</tt> represents a callback interface whose
+ * methods get invoked when executing one or multiple HTTP message exchanges
+ * on the client side.
  * <p/>
- * Repeatable request producers capable of generating the same request
- * message more than once can be reset to their initial state by calling
- * the {@link #resetRequest()} method, at which point request producers are
- * expected to release currently allocated resources that are no longer needed
- * or re-acquire resources needed to repeat the process.
+ * Individual <tt>HttpAsyncClientExchangeHandler</tt> are expected to make use of
+ * a {@link org.apache.http.protocol.HttpProcessor} to generate mandatory protocol
+ * headers for all outgoing messages and apply common, cross-cutting message
+ * transformations to all incoming and outgoing messages.
+ * <tt>HttpAsyncClientExchangeHandler</tt>s can delegate implementation
+ * of application specific content generation and processing to
+ * a {@link HttpAsyncRequestProducer} and a {@link HttpAsyncResponseConsumer}.
  *
- * @since 4.2
+ * @since 4.3
  */
-public interface HttpAsyncRequestProducer extends Closeable {
-
-    /**
-     * Invoked to obtain the request target host.
-     */
-    HttpHost getTarget();
+public interface HttpAsyncClientExchangeHandler extends Closeable, Cancellable {
 
     /**
      * Invoked to generate a HTTP request message head. The message is expected
-     * to implement the {@link HttpEntityEnclosingRequest} interface if it is
-     * to enclose a content entity. The {@link #produceContent(ContentEncoder, IOControl)}
-     * method will not be invoked if {@link HttpEntityEnclosingRequest#getEntity()}
-     * returns <code>null</code>.
+     * to implement the {@link org.apache.http.HttpEntityEnclosingRequest} interface if it is
+     * to enclose a content entity. The {@link #produceContent(ContentEncoder,
+     * IOControl)} method will not be invoked if
+     * {@link org.apache.http.HttpEntityEnclosingRequest#getEntity()} returns
+     * <code>null</code>.
      *
      * @return HTTP request message.
      * @throws HttpException in case of HTTP protocol violation
@@ -92,31 +91,62 @@ public interface HttpAsyncRequestProducer extends Closeable {
 
     /**
      * Invoked to signal that the request has been fully written out.
+     */
+    void requestCompleted();
+
+    /**
+     * Invoked when a HTTP response message is received. Please note
+     * that the {@link #consumeContent(ContentDecoder, IOControl)} method
+     * will be invoked only if the response messages has a content entity
+     * enclosed.
      *
-     * @param context HTTP context
+     * @param response HTTP response message.
+     * @throws HttpException in case of HTTP protocol violation
+     * @throws IOException in case of an I/O error
      */
-    void requestCompleted(HttpContext context);
+    void responseReceived(HttpResponse response) throws IOException, HttpException;
 
     /**
-     * Invoked to signal that the response processing terminated abnormally.
+     * Invoked to process a chunk of content from the {@link ContentDecoder}.
+     * The {@link IOControl} interface can be used to suspend input event
+     * notifications if the consumer is temporarily unable to process content.
+     * <p/>
+     * The consumer can use the {@link ContentDecoder#isCompleted()} method
+     * to find out whether or not the message content has been fully consumed.
+     * <p/>
+     * Please note that the {@link ContentDecoder} object is not thread-safe and
+     * should only be used within the context of this method call.
+     * The {@link IOControl} object can be shared and used on other thread
+     * to resume input event notifications when the consumer is capable of
+     * processing more content.
      *
-     * @param ex exception
+     * @param decoder content decoder.
+     * @param ioctrl I/O control of the underlying connection.
+     * @throws IOException in case of an I/O error
      */
-    void failed(Exception ex);
+    void consumeContent(ContentDecoder decoder, IOControl ioctrl) throws IOException;
+
+    /**
+     * Invoked to signal that the response has been fully processed.
+     */
+    void responseCompleted() throws IOException, HttpException;
 
     /**
-     * Determines whether or not this producer is capable of producing
-     * HTTP request messages more than once.
+     * Invoked to signal that the connection has been terminated prematurely
+     * by the opposite end.
      */
-    boolean isRepeatable();
+    void inputTerminated();
 
     /**
-     * Invoked to reset the producer to its initial state. Repeatable request
-     * producers are expected to release currently allocated resources that are
-     * no longer needed or re-acquire resources needed to repeat the process.
+     * Invoked to signal that the response processing terminated abnormally.
      *
-     * @throws IOException in case of an I/O error
+     * @param ex exception
+     */
+    void failed(Exception ex);
+
+    /**
+     * Determines whether or not the response processing completed.
      */
-    void resetRequest() throws IOException;
+    boolean isDone();
 
 }
diff --git a/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncExchange.java b/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncExchange.java
index ed304b3..01acfb4 100644
--- a/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncExchange.java
+++ b/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncExchange.java
@@ -27,11 +27,9 @@
 
 package org.apache.http.nio.protocol;
 
-import org.apache.http.HttpEntity;
 import org.apache.http.HttpRequest;
 import org.apache.http.HttpResponse;
 import org.apache.http.concurrent.Cancellable;
-import org.apache.http.nio.entity.HttpAsyncContentProducer;
 
 /**
  * <tt>HttpAsyncExchange</tt> represents a server-side HTTP message exchange
@@ -59,8 +57,9 @@ public interface HttpAsyncExchange {
 
     /**
      * Submits the default HTTP response and completed the message exchange.
-     * If the response encloses an {@link HttpEntity} instance the entity is
-     * also expected to implement the {@link HttpAsyncContentProducer}
+     * If the response encloses an {@link org.apache.http.HttpEntity} instance
+     * the entity is also expected to implement the
+     * {@link org.apache.http.nio.entity.HttpAsyncContentProducer }
      * interface for efficient content streaming to a non-blocking HTTP
      * connection.
      *
@@ -89,8 +88,6 @@ public interface HttpAsyncExchange {
      * connection times out or gets terminated prematurely by the client. This
      * callback can be used to cancel a long running response generating
      * process if a response is no longer needed.
-     *
-     * @param cancellable
      */
     void setCallback(Cancellable cancellable);
 
diff --git a/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncRequestConsumer.java b/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncRequestConsumer.java
index d4a1241..9d9820f 100644
--- a/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncRequestConsumer.java
+++ b/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncRequestConsumer.java
@@ -29,7 +29,6 @@ package org.apache.http.nio.protocol;
 import java.io.Closeable;
 import java.io.IOException;
 
-import org.apache.http.HttpEntityEnclosingRequest;
 import org.apache.http.HttpException;
 import org.apache.http.HttpRequest;
 import org.apache.http.nio.ContentDecoder;
@@ -50,8 +49,8 @@ public interface HttpAsyncRequestConsumer<T> extends Closeable {
      * Invoked when a HTTP request message is received. Please note
      * that the {@link #consumeContent(ContentDecoder, IOControl)} method
      * will be invoked only for if the request message implements
-     * {@link HttpEntityEnclosingRequest} interface and has a content
-     * entity enclosed.
+     * {@link org.apache.http.HttpEntityEnclosingRequest} interface and
+     * has a content entity enclosed.
      *
      * @param request HTTP request message.
      * @throws HttpException in case of HTTP protocol violation
diff --git a/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncRequestExecutor.java b/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncRequestExecutor.java
index 282fc72..0077985 100644
--- a/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncRequestExecutor.java
+++ b/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncRequestExecutor.java
@@ -27,13 +27,10 @@
 
 package org.apache.http.nio.protocol;
 
-import java.io.Closeable;
 import java.io.IOException;
 import java.net.SocketTimeoutException;
 
 import org.apache.http.ConnectionClosedException;
-import org.apache.http.ConnectionReuseStrategy;
-import org.apache.http.HttpConnection;
 import org.apache.http.HttpEntityEnclosingRequest;
 import org.apache.http.HttpException;
 import org.apache.http.HttpRequest;
@@ -46,11 +43,9 @@ import org.apache.http.nio.ContentEncoder;
 import org.apache.http.nio.NHttpClientConnection;
 import org.apache.http.nio.NHttpClientEventHandler;
 import org.apache.http.nio.NHttpConnection;
-import org.apache.http.params.CoreProtocolPNames;
-import org.apache.http.params.HttpConnectionParams;
-import org.apache.http.protocol.ExecutionContext;
 import org.apache.http.protocol.HttpContext;
-import org.apache.http.protocol.HttpProcessor;
+import org.apache.http.util.Args;
+import org.apache.http.util.Asserts;
 
 /**
  * <tt>HttpAsyncRequestExecutor</tt> is a fully asynchronous HTTP client side
@@ -58,52 +53,60 @@ import org.apache.http.protocol.HttpProcessor;
  * <tt>HttpAsyncRequestExecutor</tt> translates individual events fired through
  * the {@link NHttpClientEventHandler} interface into logically related HTTP
  * message exchanges.
- * <p/>
- * <tt>HttpAsyncRequestExecutor</tt> relies on {@link HttpProcessor}
- * to generate mandatory protocol headers for all outgoing messages and apply
- * common, cross-cutting message transformations to all incoming and outgoing
- * messages, whereas individual {@link HttpAsyncRequestExecutionHandler}s
- * are expected to implement application specific content generation and
- * processing. The caller is expected to pass an instance of
- * {@link HttpAsyncRequestExecutionHandler} to be used for the next series
+ * <p/> The caller is expected to pass an instance of
+ * {@link HttpAsyncClientExchangeHandler} to be used for the next series
  * of HTTP message exchanges through the connection context using
  * {@link #HTTP_HANDLER} attribute. HTTP exchange sequence is considered
- * complete when the {@link HttpAsyncRequestExecutionHandler#isDone()} method
+ * complete when the {@link HttpAsyncClientExchangeHandler#isDone()} method
  * returns <code>true</code>. The {@link HttpAsyncRequester} utility class can
  * be used to facilitate initiation of asynchronous HTTP request execution.
  * <p/>
- * The following parameters can be used to customize the behavior of this
- * class:
- * <ul>
- *  <li>{@link org.apache.http.params.CoreProtocolPNames#WAIT_FOR_CONTINUE}</li>
- *  <li>{@link org.apache.http.params.CoreConnectionPNames#SO_TIMEOUT}</li>
- * </ul>
+ * Individual <tt>HttpAsyncClientExchangeHandler</tt> are expected to make use of
+ * a {@link org.apache.http.protocol.HttpProcessor} to generate mandatory protocol
+ * headers for all outgoing messages and apply common, cross-cutting message
+ * transformations to all incoming and outgoing messages.
+ * <tt>HttpAsyncClientExchangeHandler</tt>s can delegate implementation of
+ * application specific content generation and processing to
+ * a {@link HttpAsyncRequestProducer} and a {@link HttpAsyncResponseConsumer}.
  *
- * @see HttpAsyncRequestExecutionHandler
+ * @see HttpAsyncClientExchangeHandler
  *
  * @since 4.2
  */
 @Immutable
 public class HttpAsyncRequestExecutor implements NHttpClientEventHandler {
 
+    public static final int DEFAULT_WAIT_FOR_CONTINUE = 3000;
     public static final String HTTP_HANDLER = "http.nio.exchange-handler";
 
-    public HttpAsyncRequestExecutor() {
+    private final int waitForContinue;
+
+    /**
+     * Creates new instance of HttpAsyncRequestExecutor.
+     *
+     * @since 4.3
+     */
+    public HttpAsyncRequestExecutor(final int waitForContinue) {
         super();
+        this.waitForContinue = Args.positive(waitForContinue, "Wait for continue time");
+    }
+
+    public HttpAsyncRequestExecutor() {
+        this(DEFAULT_WAIT_FOR_CONTINUE);
     }
 
     public void connected(
             final NHttpClientConnection conn,
             final Object attachment) throws IOException, HttpException {
-        State state = new State();
-        HttpContext context = conn.getContext();
+        final State state = new State();
+        final HttpContext context = conn.getContext();
         context.setAttribute(HTTP_EXCHANGE_STATE, state);
         requestReady(conn);
     }
 
     public void closed(final NHttpClientConnection conn) {
-        State state = getState(conn);
-        HttpAsyncRequestExecutionHandler<?> handler = getHandler(conn);
+        final State state = getState(conn);
+        final HttpAsyncClientExchangeHandler handler = getHandler(conn);
         if (state == null || (handler != null && handler.isDone())) {
             closeHandler(handler);
         }
@@ -115,7 +118,7 @@ public class HttpAsyncRequestExecutor implements NHttpClientEventHandler {
     public void exception(
             final NHttpClientConnection conn, final Exception cause) {
         shutdownConnection(conn);
-        HttpAsyncRequestExecutionHandler<?> handler = getHandler(conn);
+        final HttpAsyncClientExchangeHandler handler = getHandler(conn);
         if (handler != null) {
             handler.failed(cause);
         } else {
@@ -125,11 +128,11 @@ public class HttpAsyncRequestExecutor implements NHttpClientEventHandler {
 
     public void requestReady(
             final NHttpClientConnection conn) throws IOException, HttpException {
-        State state = ensureNotNull(getState(conn));
+        final State state = ensureNotNull(getState(conn));
         if (state.getRequestState() != MessageState.READY) {
             return;
         }
-        HttpAsyncRequestExecutionHandler<?> handler = getHandler(conn);
+        HttpAsyncClientExchangeHandler handler = getHandler(conn);
         if (handler != null && handler.isDone()) {
             closeHandler(handler);
             state.reset();
@@ -139,64 +142,51 @@ public class HttpAsyncRequestExecutor implements NHttpClientEventHandler {
             return;
         }
 
-        HttpContext context = handler.getContext();
-        context.setAttribute(ExecutionContext.HTTP_CONNECTION, conn);
-
-        HttpRequest request = handler.generateRequest();
-        context.setAttribute(ExecutionContext.HTTP_REQUEST, request);
-
-        conn.setSocketTimeout(HttpConnectionParams.getSoTimeout(request.getParams()));
-
-        HttpProcessor httppocessor = handler.getHttpProcessor();
-        httppocessor.process(request, context);
-
+        final HttpRequest request = handler.generateRequest();
         state.setRequest(request);
 
         conn.submitRequest(request);
 
         if (request instanceof HttpEntityEnclosingRequest) {
             if (((HttpEntityEnclosingRequest) request).expectContinue()) {
-                int timeout = conn.getSocketTimeout();
+                final int timeout = conn.getSocketTimeout();
                 state.setTimeout(timeout);
-                timeout = request.getParams().getIntParameter(
-                        CoreProtocolPNames.WAIT_FOR_CONTINUE, 3000);
-                conn.setSocketTimeout(timeout);
+                conn.setSocketTimeout(this.waitForContinue);
                 state.setRequestState(MessageState.ACK_EXPECTED);
             } else {
                 state.setRequestState(MessageState.BODY_STREAM);
             }
         } else {
-            handler.requestCompleted(context);
+            handler.requestCompleted();
             state.setRequestState(MessageState.COMPLETED);
         }
     }
 
     public void outputReady(
             final NHttpClientConnection conn,
-            final ContentEncoder encoder) throws IOException {
-        State state = ensureNotNull(getState(conn));
-        HttpAsyncRequestExecutionHandler<?> handler = ensureNotNull(getHandler(conn));
+            final ContentEncoder encoder) throws IOException, HttpException {
+        final State state = ensureNotNull(getState(conn));
+        final HttpAsyncClientExchangeHandler handler = ensureNotNull(getHandler(conn));
         if (state.getRequestState() == MessageState.ACK_EXPECTED) {
             conn.suspendOutput();
             return;
         }
-        HttpContext context = handler.getContext();
         handler.produceContent(encoder, conn);
         state.setRequestState(MessageState.BODY_STREAM);
         if (encoder.isCompleted()) {
-            handler.requestCompleted(context);
+            handler.requestCompleted();
             state.setRequestState(MessageState.COMPLETED);
         }
     }
 
     public void responseReceived(
             final NHttpClientConnection conn) throws HttpException, IOException {
-        State state = ensureNotNull(getState(conn));
-        HttpAsyncRequestExecutionHandler<?> handler = ensureNotNull(getHandler(conn));
-        HttpResponse response = conn.getHttpResponse();
-        HttpRequest request = state.getRequest();
+        final State state = ensureNotNull(getState(conn));
+        final HttpAsyncClientExchangeHandler handler = ensureNotNull(getHandler(conn));
+        final HttpResponse response = conn.getHttpResponse();
+        final HttpRequest request = state.getRequest();
 
-        int statusCode = response.getStatusLine().getStatusCode();
+        final int statusCode = response.getStatusLine().getStatusCode();
         if (statusCode < HttpStatus.SC_OK) {
             // 1xx intermediate response
             if (statusCode != HttpStatus.SC_CONTINUE) {
@@ -204,7 +194,7 @@ public class HttpAsyncRequestExecutor implements NHttpClientEventHandler {
                         "Unexpected response: " + response.getStatusLine());
             }
             if (state.getRequestState() == MessageState.ACK_EXPECTED) {
-                int timeout = state.getTimeout();
+                final int timeout = state.getTimeout();
                 conn.setSocketTimeout(timeout);
                 conn.requestOutput();
                 state.setRequestState(MessageState.ACK);
@@ -213,7 +203,7 @@ public class HttpAsyncRequestExecutor implements NHttpClientEventHandler {
         }
         state.setResponse(response);
         if (state.getRequestState() == MessageState.ACK_EXPECTED) {
-            int timeout = state.getTimeout();
+            final int timeout = state.getTimeout();
             conn.setSocketTimeout(timeout);
             conn.resetOutput();
             state.setRequestState(MessageState.COMPLETED);
@@ -227,12 +217,6 @@ public class HttpAsyncRequestExecutor implements NHttpClientEventHandler {
 
         handler.responseReceived(response);
 
-        HttpContext context = handler.getContext();
-        HttpProcessor httpprocessor = handler.getHttpProcessor();
-
-        context.setAttribute(ExecutionContext.HTTP_RESPONSE, response);
-        httpprocessor.process(response, context);
-
         state.setResponseState(MessageState.BODY_STREAM);
         if (!canResponseHaveBody(request, response)) {
             response.setEntity(null);
@@ -243,9 +227,9 @@ public class HttpAsyncRequestExecutor implements NHttpClientEventHandler {
 
     public void inputReady(
             final NHttpClientConnection conn,
-            final ContentDecoder decoder) throws IOException {
-        State state = ensureNotNull(getState(conn));
-        HttpAsyncRequestExecutionHandler<?> handler = ensureNotNull(getHandler(conn));
+            final ContentDecoder decoder) throws IOException, HttpException {
+        final State state = ensureNotNull(getState(conn));
+        final HttpAsyncClientExchangeHandler handler = ensureNotNull(getHandler(conn));
         handler.consumeContent(decoder, conn);
         state.setResponseState(MessageState.BODY_STREAM);
         if (decoder.isCompleted()) {
@@ -254,12 +238,18 @@ public class HttpAsyncRequestExecutor implements NHttpClientEventHandler {
     }
 
     public void endOfInput(final NHttpClientConnection conn) throws IOException {
-        State state = getState(conn);
+        final State state = getState(conn);
         if (state != null) {
             if (state.getRequestState().compareTo(MessageState.READY) != 0) {
                 state.invalidate();
-                HttpAsyncRequestExecutionHandler<?> handler = getHandler(conn);
-                handler.failed(new ConnectionClosedException("Connection closed"));
+            }
+            final HttpAsyncClientExchangeHandler handler = getHandler(conn);
+            if (handler != null) {
+                if (state.isValid()) {
+                    handler.inputTerminated();
+                } else {
+                    handler.failed(new ConnectionClosedException("Connection closed"));
+                }
             }
         }
         // Closing connection in an orderly manner and
@@ -274,17 +264,17 @@ public class HttpAsyncRequestExecutor implements NHttpClientEventHandler {
 
     public void timeout(
             final NHttpClientConnection conn) throws IOException {
-        State state = getState(conn);
+        final State state = getState(conn);
         if (state != null) {
             if (state.getRequestState() == MessageState.ACK_EXPECTED) {
-                int timeout = state.getTimeout();
+                final int timeout = state.getTimeout();
                 conn.setSocketTimeout(timeout);
                 conn.requestOutput();
                 state.setRequestState(MessageState.BODY_STREAM);
                 return;
             } else {
                 state.invalidate();
-                HttpAsyncRequestExecutionHandler<?> handler = getHandler(conn);
+                final HttpAsyncClientExchangeHandler handler = getHandler(conn);
                 if (handler != null) {
                     handler.failed(new SocketTimeoutException());
                     handler.close();
@@ -304,10 +294,11 @@ public class HttpAsyncRequestExecutor implements NHttpClientEventHandler {
     }
 
     /**
-     * This method can be used to log I/O exception thrown while closing {@link Closeable}
-     * objects (such as {@link HttpConnection}}).
+     * This method can be used to log I/O exception thrown while closing
+     * {@link java.io.Closeable} objects (such as
+     * {@link org.apache.http.HttpConnection}}).
      *
-     * @param ex I/O exception thrown by {@link Closeable#close()}
+     * @param ex I/O exception thrown by {@link java.io.Closeable#close()}
      */
     protected void log(final Exception ex) {
     }
@@ -317,36 +308,32 @@ public class HttpAsyncRequestExecutor implements NHttpClientEventHandler {
     }
 
     private State ensureNotNull(final State state) {
-        if (state == null) {
-            throw new IllegalStateException("HTTP exchange state is null");
-        }
+        Asserts.notNull(state, "HTTP exchange state");
         return state;
     }
 
-    private HttpAsyncRequestExecutionHandler<?> getHandler(final NHttpConnection conn) {
-        return (HttpAsyncRequestExecutionHandler<?>) conn.getContext().getAttribute(HTTP_HANDLER);
+    private HttpAsyncClientExchangeHandler getHandler(final NHttpConnection conn) {
+        return (HttpAsyncClientExchangeHandler) conn.getContext().getAttribute(HTTP_HANDLER);
     }
 
-    private HttpAsyncRequestExecutionHandler<?> ensureNotNull(final HttpAsyncRequestExecutionHandler<?> handler) {
-        if (handler == null) {
-            throw new IllegalStateException("HTTP exchange handler is null");
-        }
+    private HttpAsyncClientExchangeHandler ensureNotNull(final HttpAsyncClientExchangeHandler handler) {
+        Asserts.notNull(handler, "HTTP exchange handler");
         return handler;
     }
 
     private void shutdownConnection(final NHttpConnection conn) {
         try {
             conn.shutdown();
-        } catch (IOException ex) {
+        } catch (final IOException ex) {
             log(ex);
         }
     }
 
-    private void closeHandler(final HttpAsyncRequestExecutionHandler<?> handler) {
+    private void closeHandler(final HttpAsyncClientExchangeHandler handler) {
         if (handler != null) {
             try {
                 handler.close();
-            } catch (IOException ioex) {
+            } catch (final IOException ioex) {
                 log(ioex);
             }
         }
@@ -355,30 +342,21 @@ public class HttpAsyncRequestExecutor implements NHttpClientEventHandler {
     private void processResponse(
             final NHttpClientConnection conn,
             final State state,
-            final HttpAsyncRequestExecutionHandler<?> handler) throws IOException {
-        HttpContext context = handler.getContext();
-        if (state.isValid()) {
-            HttpRequest request = state.getRequest();
-            HttpResponse response = state.getResponse();
-            String method = request.getRequestLine().getMethod();
-            int status = response.getStatusLine().getStatusCode();
-            if (!(method.equalsIgnoreCase("CONNECT") && status < 300)) {
-                ConnectionReuseStrategy connReuseStrategy = handler.getConnectionReuseStrategy();
-                if (!connReuseStrategy.keepAlive(response, context)) {
-                    conn.close();
-                }
-            }
-        } else {
+            final HttpAsyncClientExchangeHandler handler) throws IOException, HttpException {
+        if (!state.isValid()) {
             conn.close();
         }
-        handler.responseCompleted(context);
+        handler.responseCompleted();
         state.reset();
+        if (!handler.isDone()) {
+            conn.requestOutput();
+        }
     }
 
     private boolean canResponseHaveBody(final HttpRequest request, final HttpResponse response) {
 
-        String method = request.getRequestLine().getMethod();
-        int status = response.getStatusLine().getStatusCode();
+        final String method = request.getRequestLine().getMethod();
+        final int status = response.getStatusLine().getStatusCode();
 
         if (method.equalsIgnoreCase("HEAD")) {
             return false;
@@ -446,7 +424,7 @@ public class HttpAsyncRequestExecutor implements NHttpClientEventHandler {
             return this.timeout;
         }
 
-        public void setTimeout(int timeout) {
+        public void setTimeout(final int timeout) {
             this.timeout = timeout;
         }
 
@@ -468,7 +446,7 @@ public class HttpAsyncRequestExecutor implements NHttpClientEventHandler {
 
         @Override
         public String toString() {
-            StringBuilder buf = new StringBuilder();
+            final StringBuilder buf = new StringBuilder();
             buf.append("request state: ");
             buf.append(this.requestState);
             buf.append("; request: ");
diff --git a/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncRequestHandlerResolver.java b/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncRequestHandlerMapper.java
similarity index 77%
copy from httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncRequestHandlerResolver.java
copy to httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncRequestHandlerMapper.java
index d5f7c7b..19d550d 100644
--- a/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncRequestHandlerResolver.java
+++ b/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncRequestHandlerMapper.java
@@ -27,23 +27,24 @@
 
 package org.apache.http.nio.protocol;
 
+import org.apache.http.HttpRequest;
+
 /**
- * <tt>HttpAsyncRequestHandlerResolver</tt> can be used to resolve an instance
- * of {@link HttpAsyncRequestHandler} matching a particular request URI.
- * Usually the resolved request handler will be used to process the request
- * with the specified request URI.
+ * <tt>HttpAsyncRequestHandlerMapper</tt> can be used to resolve an instance
+ * of {@link HttpAsyncRequestHandler} matching a particular {@link HttpRequest}.
+ * Usually the resolved request handler will be used to process the request.
  *
- * @since 4.2
+ * @since 4.3
  */
-public interface HttpAsyncRequestHandlerResolver {
+public interface HttpAsyncRequestHandlerMapper {
 
     /**
-     * Looks up a handler matching the given request URI.
+     * Looks up a handler matching the given request.
      *
-     * @param requestURI the request URI
+     * @param request the request
      * @return HTTP request handler or <code>null</code> if no match
      * is found.
      */
-    HttpAsyncRequestHandler<?> lookup(String requestURI);
+    HttpAsyncRequestHandler<?> lookup(HttpRequest request);
 
 }
diff --git a/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncRequestHandlerResolver.java b/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncRequestHandlerResolver.java
index d5f7c7b..b123558 100644
--- a/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncRequestHandlerResolver.java
+++ b/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncRequestHandlerResolver.java
@@ -28,13 +28,15 @@
 package org.apache.http.nio.protocol;
 
 /**
- * <tt>HttpAsyncRequestHandlerResolver</tt> can be used to resolve an instance
+ * <tt>HttpAsyncRequestHandlerResolver</tt> can be used to map an instance
  * of {@link HttpAsyncRequestHandler} matching a particular request URI.
- * Usually the resolved request handler will be used to process the request
+ * Usually the mapped request handler will be used to process the request
  * with the specified request URI.
  *
  * @since 4.2
+ * @deprecated see {@link HttpAsyncRequestHandlerMapper}
  */
+ at Deprecated
 public interface HttpAsyncRequestHandlerResolver {
 
     /**
diff --git a/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncRequestProducer.java b/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncRequestProducer.java
index 76f0aef..aec7335 100644
--- a/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncRequestProducer.java
+++ b/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncRequestProducer.java
@@ -29,7 +29,6 @@ package org.apache.http.nio.protocol;
 import java.io.Closeable;
 import java.io.IOException;
 
-import org.apache.http.HttpEntityEnclosingRequest;
 import org.apache.http.HttpException;
 import org.apache.http.HttpHost;
 import org.apache.http.HttpRequest;
@@ -59,9 +58,10 @@ public interface HttpAsyncRequestProducer extends Closeable {
 
     /**
      * Invoked to generate a HTTP request message head. The message is expected
-     * to implement the {@link HttpEntityEnclosingRequest} interface if it is
-     * to enclose a content entity. The {@link #produceContent(ContentEncoder, IOControl)}
-     * method will not be invoked if {@link HttpEntityEnclosingRequest#getEntity()}
+     * to implement the {@link org.apache.http.HttpEntityEnclosingRequest} interface
+     * if it is to enclose a content entity. The {@link #produceContent(
+     * ContentEncoder, IOControl)} method will not be invoked if
+     * {@link org.apache.http.HttpEntityEnclosingRequest#getEntity()}
      * returns <code>null</code>.
      *
      * @return HTTP request message.
diff --git a/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncRequester.java b/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncRequester.java
index 12f9d81..f5c01b6 100644
--- a/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncRequester.java
+++ b/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncRequester.java
@@ -26,17 +26,16 @@
  */
 package org.apache.http.nio.protocol;
 
-import java.io.Closeable;
 import java.io.IOException;
 import java.util.concurrent.Future;
 
 import org.apache.http.ConnectionClosedException;
 import org.apache.http.ConnectionReuseStrategy;
-import org.apache.http.HttpConnection;
 import org.apache.http.HttpHost;
 import org.apache.http.annotation.Immutable;
 import org.apache.http.concurrent.BasicFuture;
 import org.apache.http.concurrent.FutureCallback;
+import org.apache.http.impl.DefaultConnectionReuseStrategy;
 import org.apache.http.nio.NHttpClientConnection;
 import org.apache.http.params.HttpParams;
 import org.apache.http.pool.ConnPool;
@@ -44,6 +43,7 @@ import org.apache.http.pool.PoolEntry;
 import org.apache.http.protocol.BasicHttpContext;
 import org.apache.http.protocol.HttpContext;
 import org.apache.http.protocol.HttpProcessor;
+import org.apache.http.util.Args;
 
 /**
  * <tt>HttpAsyncRequester</tt> is a utility class that can be used
@@ -54,21 +54,46 @@ import org.apache.http.protocol.HttpProcessor;
  *
  * @since 4.2
  */
+ at SuppressWarnings("deprecation")
 @Immutable
 public class HttpAsyncRequester {
 
     private final HttpProcessor httppocessor;
-    private final ConnectionReuseStrategy reuseStrategy;
-    private final HttpParams params;
+    private final ConnectionReuseStrategy connReuseStrategy;
 
+    /**
+     * @deprecated (4.3) use {@link HttpAsyncRequester#HttpAsyncRequester(HttpProcessor,
+     *   ConnectionReuseStrategy)}
+     */
+    @Deprecated
     public HttpAsyncRequester(
             final HttpProcessor httppocessor,
             final ConnectionReuseStrategy reuseStrategy,
             final HttpParams params) {
+        this(httppocessor, reuseStrategy);
+    }
+
+    /**
+     * Creates new instance of HttpAsyncRequester.
+     *
+     * @since 4.3
+     */
+    public HttpAsyncRequester(
+            final HttpProcessor httppocessor,
+            final ConnectionReuseStrategy connReuseStrategy) {
         super();
-        this.httppocessor = httppocessor;
-        this.reuseStrategy = reuseStrategy;
-        this.params = params;
+        this.httppocessor = Args.notNull(httppocessor, "HTTP processor");
+        this.connReuseStrategy = connReuseStrategy != null ? connReuseStrategy :
+            DefaultConnectionReuseStrategy.INSTANCE;
+    }
+
+    /**
+     * Creates new instance of HttpAsyncRequester.
+     *
+     * @since 4.3
+     */
+    public HttpAsyncRequester(final HttpProcessor httppocessor) {
+        this(httppocessor, null);
     }
 
     /**
@@ -88,33 +113,25 @@ public class HttpAsyncRequester {
             final NHttpClientConnection conn,
             final HttpContext context,
             final FutureCallback<T> callback) {
-        if (requestProducer == null) {
-            throw new IllegalArgumentException("HTTP request producer may not be null");
-        }
-        if (responseConsumer == null) {
-            throw new IllegalArgumentException("HTTP response consumer may not be null");
-        }
-        if (conn == null) {
-            throw new IllegalArgumentException("HTTP connection may not be null");
-        }
-        if (context == null) {
-            throw new IllegalArgumentException("HTTP context may not be null");
-        }
-        BasicAsyncRequestExecutionHandler<T> handler = new BasicAsyncRequestExecutionHandler<T>(
-                requestProducer, responseConsumer, callback, context,
-                this.httppocessor, this.reuseStrategy, this.params);
-        doExecute(handler, conn);
+        Args.notNull(requestProducer, "HTTP request producer");
+        Args.notNull(responseConsumer, "HTTP response consumer");
+        Args.notNull(conn, "HTTP connection");
+        Args.notNull(context, "HTTP context");
+        final BasicAsyncClientExchangeHandler<T> handler = new BasicAsyncClientExchangeHandler<T>(
+                requestProducer, responseConsumer, callback, context, conn,
+                this.httppocessor, this.connReuseStrategy);
+        initExection(handler, conn);
         return handler.getFuture();
     }
 
-    private <T> void doExecute(
-            final HttpAsyncRequestExecutionHandler<T> handler, final NHttpClientConnection conn) {
+    private void initExection(
+            final HttpAsyncClientExchangeHandler handler, final NHttpClientConnection conn) {
         conn.getContext().setAttribute(HttpAsyncRequestExecutor.HTTP_HANDLER, handler);
         if (!conn.isOpen()) {
             handler.failed(new ConnectionClosedException("Connection closed"));
             try {
                 handler.close();
-            } catch (IOException ex) {
+            } catch (final IOException ex) {
                 log(ex);
             }
         } else {
@@ -174,26 +191,58 @@ public class HttpAsyncRequester {
             final ConnPool<HttpHost, E> connPool,
             final HttpContext context,
             final FutureCallback<T> callback) {
-        if (requestProducer == null) {
-            throw new IllegalArgumentException("HTTP request producer may not be null");
-        }
-        if (responseConsumer == null) {
-            throw new IllegalArgumentException("HTTP response consumer may not be null");
-        }
-        if (connPool == null) {
-            throw new IllegalArgumentException("HTTP connection pool may not be null");
-        }
-        if (context == null) {
-            throw new IllegalArgumentException("HTTP context may not be null");
-        }
-        BasicFuture<T> future = new BasicFuture<T>(callback);
-        HttpHost target = requestProducer.getTarget();
+        Args.notNull(requestProducer, "HTTP request producer");
+        Args.notNull(responseConsumer, "HTTP response consumer");
+        Args.notNull(connPool, "HTTP connection pool");
+        Args.notNull(context, "HTTP context");
+        final BasicFuture<T> future = new BasicFuture<T>(callback);
+        final HttpHost target = requestProducer.getTarget();
         connPool.lease(target, null, new ConnRequestCallback<T, E>(
                 future, requestProducer, responseConsumer, connPool, context));
         return future;
     }
 
     /**
+     * Initiates asynchronous HTTP request execution. This method automatically releases
+     * the given pool entry once request execution is completed (successfully or unsuccessfully).
+     *
+     * @param <T> the result type of request execution.
+     * @param <E> the connection pool entry type.
+     * @param requestProducer request producer callback.
+     * @param responseConsumer response consumer callaback.
+     * @param poolEntry leased pool entry. It will be automatically released
+     *   back to the pool when execution is completed.
+     * @param connPool pool of persistent reusable connections.
+     * @param context HTTP context
+     * @param callback future callback.
+     * @return future representing pending completion of the operation.
+     *
+     * @since 4.3
+     */
+    public <T, E extends PoolEntry<HttpHost, NHttpClientConnection>> Future<T> execute(
+            final HttpAsyncRequestProducer requestProducer,
+            final HttpAsyncResponseConsumer<T> responseConsumer,
+            final E poolEntry,
+            final ConnPool<HttpHost, E> connPool,
+            final HttpContext context,
+            final FutureCallback<T> callback) {
+        Args.notNull(requestProducer, "HTTP request producer");
+        Args.notNull(responseConsumer, "HTTP response consumer");
+        Args.notNull(connPool, "HTTP connection pool");
+        Args.notNull(poolEntry, "Pool entry");
+        Args.notNull(context, "HTTP context");
+        final BasicFuture<T> future = new BasicFuture<T>(callback);
+        final NHttpClientConnection conn = poolEntry.getConnection();
+        final BasicAsyncClientExchangeHandler<T> handler = new BasicAsyncClientExchangeHandler<T>(
+                requestProducer, responseConsumer,
+                new RequestExecutionCallback<T, E>(future, poolEntry, connPool),
+                context, conn,
+                this.httppocessor, this.connReuseStrategy);
+        initExection(handler, conn);
+        return future;
+    }
+
+    /**
      * Initiates asynchronous HTTP request execution.
      *
      * @param <T> the result type of request execution.
@@ -256,12 +305,12 @@ public class HttpAsyncRequester {
                 this.connPool.release(result, true);
                 return;
             }
-            NHttpClientConnection conn = result.getConnection();
-            BasicAsyncRequestExecutionHandler<T> handler = new BasicAsyncRequestExecutionHandler<T>(
+            final NHttpClientConnection conn = result.getConnection();
+            final BasicAsyncClientExchangeHandler<T> handler = new BasicAsyncClientExchangeHandler<T>(
                     this.requestProducer, this.responseConsumer,
                     new RequestExecutionCallback<T, E>(this.requestFuture, result, this.connPool),
-                    this.context, httppocessor, reuseStrategy, params);
-            doExecute(handler, conn);
+                    this.context, conn, httppocessor, connReuseStrategy);
+            initExection(handler, conn);
         }
 
         public void failed(final Exception ex) {
@@ -291,12 +340,12 @@ public class HttpAsyncRequester {
         public void releaseResources() {
             try {
                 this.requestProducer.close();
-            } catch (IOException ioex) {
+            } catch (final IOException ioex) {
                 log(ioex);
             }
             try {
                 this.responseConsumer.close();
-            } catch (IOException ioex) {
+            } catch (final IOException ioex) {
                 log(ioex);
             }
         }
@@ -347,12 +396,13 @@ public class HttpAsyncRequester {
     }
 
     /**
-     * This method can be used to log I/O exception thrown while closing {@link Closeable}
-     * objects (such as {@link HttpConnection}}).
+     * This method can be used to log I/O exception thrown while closing
+     * {@link java.io.Closeable} objects (such as
+     * {@link org.apache.http.HttpConnection}}).
      *
-     * @param ex I/O exception thrown by {@link Closeable#close()}
+     * @param ex I/O exception thrown by {@link java.io.Closeable#close()}
      */
-    protected void log(Exception ex) {
+    protected void log(final Exception ex) {
     }
 
 }
diff --git a/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncResponseProducer.java b/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncResponseProducer.java
index 0bd04b8..3d612df 100644
--- a/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncResponseProducer.java
+++ b/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncResponseProducer.java
@@ -30,7 +30,6 @@ package org.apache.http.nio.protocol;
 import java.io.Closeable;
 import java.io.IOException;
 
-import org.apache.http.HttpException;
 import org.apache.http.HttpResponse;
 import org.apache.http.nio.ContentEncoder;
 import org.apache.http.nio.IOControl;
@@ -49,8 +48,6 @@ public interface HttpAsyncResponseProducer extends Closeable {
      * Invoked to generate a HTTP response message head.
      *
      * @return HTTP response message.
-     * @throws HttpException in case of HTTP protocol violation
-     * @throws IOException in case of an I/O error
      */
     HttpResponse generateResponse();
 
diff --git a/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncService.java b/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncService.java
index f8e9fa4..758a4b8 100644
--- a/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncService.java
+++ b/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncService.java
@@ -27,12 +27,10 @@
 
 package org.apache.http.nio.protocol;
 
-import java.io.Closeable;
 import java.io.IOException;
 import java.net.SocketTimeoutException;
 
 import org.apache.http.ConnectionReuseStrategy;
-import org.apache.http.HttpConnection;
 import org.apache.http.HttpEntity;
 import org.apache.http.HttpEntityEnclosingRequest;
 import org.apache.http.HttpException;
@@ -47,6 +45,7 @@ import org.apache.http.UnsupportedHttpVersionException;
 import org.apache.http.annotation.Immutable;
 import org.apache.http.concurrent.Cancellable;
 import org.apache.http.entity.ContentType;
+import org.apache.http.impl.DefaultConnectionReuseStrategy;
 import org.apache.http.impl.DefaultHttpResponseFactory;
 import org.apache.http.nio.ContentDecoder;
 import org.apache.http.nio.ContentEncoder;
@@ -54,13 +53,13 @@ import org.apache.http.nio.NHttpConnection;
 import org.apache.http.nio.NHttpServerConnection;
 import org.apache.http.nio.NHttpServerEventHandler;
 import org.apache.http.nio.entity.NStringEntity;
-import org.apache.http.params.DefaultedHttpParams;
-import org.apache.http.params.HttpConnectionParams;
 import org.apache.http.params.HttpParams;
 import org.apache.http.protocol.BasicHttpContext;
-import org.apache.http.protocol.ExecutionContext;
 import org.apache.http.protocol.HttpContext;
+import org.apache.http.protocol.HttpCoreContext;
 import org.apache.http.protocol.HttpProcessor;
+import org.apache.http.util.Args;
+import org.apache.http.util.Asserts;
 
 /**
  * <tt>HttpAsyncService</tt> is a fully asynchronous HTTP server side protocol
@@ -72,7 +71,7 @@ import org.apache.http.protocol.HttpProcessor;
  * Upon receiving an incoming request <tt>HttpAsyncService</tt> verifies
  * the message for compliance with the server expectations using
  * {@link HttpAsyncExpectationVerifier}, if provided, and then
- * {@link HttpAsyncRequestHandlerResolver} is used to resolve the request URI
+ * {@link HttpAsyncRequestHandlerMapper} is used to map the request
  * to a particular {@link HttpAsyncRequestHandler} intended to handle
  * the request with the given URI. The protocol handler uses the selected
  * {@link HttpAsyncRequestHandler} instance to process the incoming request
@@ -90,15 +89,10 @@ import org.apache.http.protocol.HttpProcessor;
  * request handling to another service or a worker thread. HTTP response can
  * be submitted as a later a later point of time once response content becomes
  * available.
- * <p/>
- * The following parameters can be used to customize the behavior of this
- * class:
- * <ul>
- *  <li>{@link org.apache.http.params.CoreConnectionPNames#SO_TIMEOUT}</li>
- * </ul>
  *
  * @since 4.2
  */
+ at SuppressWarnings("deprecation")
 @Immutable // provided injected dependencies are immutable
 public class HttpAsyncService implements NHttpServerEventHandler {
 
@@ -107,12 +101,11 @@ public class HttpAsyncService implements NHttpServerEventHandler {
     private final HttpProcessor httpProcessor;
     private final ConnectionReuseStrategy connStrategy;
     private final HttpResponseFactory responseFactory;
-    private final HttpAsyncRequestHandlerResolver handlerResolver;
+    private final HttpAsyncRequestHandlerMapper handlerMapper;
     private final HttpAsyncExpectationVerifier expectationVerifier;
-    private final HttpParams params;
 
     /**
-     * Creates an instance of <tt>HttpAsyncServerProtocolHandler</tt>.
+     * Creates new instance of <tt>HttpAsyncServerProtocolHandler</tt>.
      *
      * @param httpProcessor HTTP protocol processor (required).
      * @param connStrategy Connection re-use strategy (required).
@@ -120,7 +113,12 @@ public class HttpAsyncService implements NHttpServerEventHandler {
      * @param handlerResolver Request handler resolver.
      * @param expectationVerifier Request expectation verifier (optional).
      * @param params HTTP parameters (required).
+     *
+     * @deprecated (4.3) use {@link HttpAsyncService#HttpAsyncService(HttpProcessor,
+     *  ConnectionReuseStrategy, HttpResponseFactory, HttpAsyncRequestHandlerMapper,
+     *    HttpAsyncExpectationVerifier)}
      */
+    @Deprecated
     public HttpAsyncService(
             final HttpProcessor httpProcessor,
             final ConnectionReuseStrategy connStrategy,
@@ -128,55 +126,92 @@ public class HttpAsyncService implements NHttpServerEventHandler {
             final HttpAsyncRequestHandlerResolver handlerResolver,
             final HttpAsyncExpectationVerifier expectationVerifier,
             final HttpParams params) {
-        super();
-        if (httpProcessor == null) {
-            throw new IllegalArgumentException("HTTP processor may not be null.");
-        }
-        if (connStrategy == null) {
-            throw new IllegalArgumentException("Connection reuse strategy may not be null");
-        }
-        if (responseFactory == null) {
-            throw new IllegalArgumentException("Response factory may not be null");
-        }
-        if (params == null) {
-            throw new IllegalArgumentException("HTTP parameters may not be null");
-        }
-        this.httpProcessor = httpProcessor;
-        this.connStrategy = connStrategy;
-        this.responseFactory = responseFactory;
-        this.handlerResolver = handlerResolver;
-        this.expectationVerifier = expectationVerifier;
-        this.params = params;
+        this(httpProcessor,
+             connStrategy,
+             responseFactory,
+             new HttpAsyncRequestHandlerResolverAdapter(handlerResolver),
+             expectationVerifier);
     }
 
     /**
-     * Creates an instance of <tt>HttpAsyncServerProtocolHandler</tt>.
+     * Creates new instance of <tt>HttpAsyncServerProtocolHandler</tt>.
      *
      * @param httpProcessor HTTP protocol processor (required).
      * @param connStrategy Connection re-use strategy (required).
      * @param handlerResolver Request handler resolver.
      * @param params HTTP parameters (required).
+     *
+     * @deprecated (4.3) use {@link HttpAsyncService#HttpAsyncService(HttpProcessor,
+     *   ConnectionReuseStrategy, HttpResponseFactory, HttpAsyncRequestHandlerMapper,
+     *   HttpAsyncExpectationVerifier)}
      */
+    @Deprecated
     public HttpAsyncService(
             final HttpProcessor httpProcessor,
             final ConnectionReuseStrategy connStrategy,
             final HttpAsyncRequestHandlerResolver handlerResolver,
             final HttpParams params) {
-        this(httpProcessor, connStrategy, new DefaultHttpResponseFactory(),
-                handlerResolver, null, params);
+        this(httpProcessor,
+             connStrategy,
+             DefaultHttpResponseFactory.INSTANCE,
+             new HttpAsyncRequestHandlerResolverAdapter(handlerResolver),
+             null);
+    }
+
+    /**
+     * Creates new instance of <tt>HttpAsyncServerProtocolHandler</tt>.
+     *
+     * @param httpProcessor HTTP protocol processor.
+     * @param connStrategy Connection re-use strategy. If <code>null</code>
+     *   {@link DefaultConnectionReuseStrategy#INSTANCE} will be used.
+     * @param responseFactory HTTP response factory. If <code>null</code>
+     *   {@link DefaultHttpResponseFactory#INSTANCE} will be used.
+     * @param handlerMapper Request handler mapper.
+     * @param expectationVerifier Request expectation verifier. May be <code>null</code>.
+     *
+     * @since 4.3
+     */
+    public HttpAsyncService(
+            final HttpProcessor httpProcessor,
+            final ConnectionReuseStrategy connStrategy,
+            final HttpResponseFactory responseFactory,
+            final HttpAsyncRequestHandlerMapper handlerMapper,
+            final HttpAsyncExpectationVerifier expectationVerifier) {
+        super();
+        this.httpProcessor = Args.notNull(httpProcessor, "HTTP processor");
+        this.connStrategy = connStrategy != null ? connStrategy :
+            DefaultConnectionReuseStrategy.INSTANCE;
+        this.responseFactory = responseFactory != null ? responseFactory :
+            DefaultHttpResponseFactory.INSTANCE;
+        this.handlerMapper = handlerMapper;
+        this.expectationVerifier = expectationVerifier;
+    }
+
+    /**
+     * Creates new instance of <tt>HttpAsyncServerProtocolHandler</tt>.
+     *
+     * @param httpProcessor HTTP protocol processor.
+     * @param handlerMapper Request handler mapper.
+     *
+     * @since 4.3
+     */
+    public HttpAsyncService(
+            final HttpProcessor httpProcessor,
+            final HttpAsyncRequestHandlerMapper handlerMapper) {
+        this(httpProcessor, null, null, handlerMapper, null);
     }
 
     public void connected(final NHttpServerConnection conn) {
-        State state = new State();
+        final State state = new State();
         conn.getContext().setAttribute(HTTP_EXCHANGE_STATE, state);
     }
 
     public void closed(final NHttpServerConnection conn) {
-        State state = getState(conn);
+        final State state = getState(conn);
         if (state != null) {
             state.setTerminated();
             closeHandlers(state);
-            Cancellable cancellable = state.getCancellable();
+            final Cancellable cancellable = state.getCancellable();
             if (cancellable != null) {
                 cancellable.cancel();
             }
@@ -186,11 +221,11 @@ public class HttpAsyncService implements NHttpServerEventHandler {
 
     public void exception(
             final NHttpServerConnection conn, final Exception cause) {
-        State state = ensureNotNull(getState(conn));
+        final State state = ensureNotNull(getState(conn));
         if (state != null) {
             state.setTerminated();
             closeHandlers(state, cause);
-            Cancellable cancellable = state.getCancellable();
+            final Cancellable cancellable = state.getCancellable();
             if (cancellable != null) {
                 cancellable.cancel();
             }
@@ -202,15 +237,15 @@ public class HttpAsyncService implements NHttpServerEventHandler {
                     closeConnection(conn);
                     log(cause);
                 } else {
-                    HttpContext context = state.getContext();
-                    HttpAsyncResponseProducer responseProducer = handleException(
+                    final HttpContext context = state.getContext();
+                    final HttpAsyncResponseProducer responseProducer = handleException(
                             cause, context);
                     state.setResponseProducer(responseProducer);
                     try {
-                        HttpResponse response = responseProducer.generateResponse();
+                        final HttpResponse response = responseProducer.generateResponse();
                         state.setResponse(response);
                         commitFinalResponse(conn, state);
-                    } catch (Exception ex) {
+                    } catch (final Exception ex) {
                         shutdownConnection(conn);
                         closeHandlers(state);
                         if (ex instanceof RuntimeException) {
@@ -231,22 +266,21 @@ public class HttpAsyncService implements NHttpServerEventHandler {
 
     public void requestReceived(
             final NHttpServerConnection conn) throws IOException, HttpException {
-        State state = ensureNotNull(getState(conn));
+        final State state = ensureNotNull(getState(conn));
         if (state.getResponseState() != MessageState.READY) {
             throw new ProtocolException("Out of sequence request message detected (pipelining is not supported)");
         }
-        HttpRequest request = conn.getHttpRequest();
-        HttpContext context = state.getContext();
-        request.setParams(new DefaultedHttpParams(request.getParams(), this.params));
+        final HttpRequest request = conn.getHttpRequest();
+        final HttpContext context = state.getContext();
 
-        context.setAttribute(ExecutionContext.HTTP_REQUEST, request);
-        context.setAttribute(ExecutionContext.HTTP_CONNECTION, conn);
+        context.setAttribute(HttpCoreContext.HTTP_REQUEST, request);
+        context.setAttribute(HttpCoreContext.HTTP_CONNECTION, conn);
         this.httpProcessor.process(request, context);
 
         state.setRequest(request);
-        HttpAsyncRequestHandler<Object> requestHandler = getRequestHandler(request);
+        final HttpAsyncRequestHandler<Object> requestHandler = getRequestHandler(request);
         state.setRequestHandler(requestHandler);
-        HttpAsyncRequestConsumer<Object> consumer = requestHandler.processRequest(request, context);
+        final HttpAsyncRequestConsumer<Object> consumer = requestHandler.processRequest(request, context);
         state.setRequestConsumer(consumer);
 
         consumer.requestReceived(request);
@@ -254,11 +288,11 @@ public class HttpAsyncService implements NHttpServerEventHandler {
         if (request instanceof HttpEntityEnclosingRequest) {
             if (((HttpEntityEnclosingRequest) request).expectContinue()) {
                 state.setRequestState(MessageState.ACK_EXPECTED);
-                HttpResponse ack = this.responseFactory.newHttpResponse(HttpVersion.HTTP_1_1,
+                final HttpResponse ack = this.responseFactory.newHttpResponse(HttpVersion.HTTP_1_1,
                         HttpStatus.SC_CONTINUE, context);
                 if (this.expectationVerifier != null) {
                     conn.suspendInput();
-                    HttpAsyncExchange httpex = new Exchange(
+                    final HttpAsyncExchange httpex = new Exchange(
                             request, ack, state, conn);
                     this.expectationVerifier.verify(httpex, context);
                 } else {
@@ -278,8 +312,8 @@ public class HttpAsyncService implements NHttpServerEventHandler {
     public void inputReady(
             final NHttpServerConnection conn,
             final ContentDecoder decoder) throws IOException, HttpException {
-        State state = ensureNotNull(getState(conn));
-        HttpAsyncRequestConsumer<?> consumer = ensureNotNull(state.getRequestConsumer());
+        final State state = ensureNotNull(getState(conn));
+        final HttpAsyncRequestConsumer<?> consumer = ensureNotNull(state.getRequestConsumer());
         consumer.consumeContent(decoder, conn);
         state.setRequestState(MessageState.BODY_STREAM);
         if (decoder.isCompleted()) {
@@ -289,17 +323,17 @@ public class HttpAsyncService implements NHttpServerEventHandler {
 
     public void responseReady(
             final NHttpServerConnection conn) throws IOException, HttpException {
-        State state = ensureNotNull(getState(conn));
+        final State state = ensureNotNull(getState(conn));
         if (state.getResponse() != null) {
             return;
         }
-        HttpAsyncResponseProducer responseProducer = state.getResponseProducer();
+        final HttpAsyncResponseProducer responseProducer = state.getResponseProducer();
         if (responseProducer == null) {
             return;
         }
-        HttpContext context = state.getContext();
-        HttpResponse response = responseProducer.generateResponse();
-        int status = response.getStatusLine().getStatusCode();
+        final HttpContext context = state.getContext();
+        final HttpResponse response = responseProducer.generateResponse();
+        final int status = response.getStatusLine().getStatusCode();
         if (state.getRequestState() == MessageState.ACK_EXPECTED) {
             if (status == 100) {
                 try {
@@ -334,10 +368,10 @@ public class HttpAsyncService implements NHttpServerEventHandler {
     public void outputReady(
             final NHttpServerConnection conn,
             final ContentEncoder encoder) throws IOException {
-        State state = ensureNotNull(getState(conn));
-        HttpAsyncResponseProducer responseProducer = state.getResponseProducer();
-        HttpContext context = state.getContext();
-        HttpResponse response = state.getResponse();
+        final State state = ensureNotNull(getState(conn));
+        final HttpAsyncResponseProducer responseProducer = state.getResponseProducer();
+        final HttpContext context = state.getContext();
+        final HttpResponse response = state.getResponse();
 
         responseProducer.produceContent(encoder, conn);
         state.setResponseState(MessageState.BODY_STREAM);
@@ -350,7 +384,6 @@ public class HttpAsyncService implements NHttpServerEventHandler {
             }
             closeHandlers(state);
             state.reset();
-            conn.setSocketTimeout(HttpConnectionParams.getSoTimeout(this.params));
         }
     }
 
@@ -366,7 +399,7 @@ public class HttpAsyncService implements NHttpServerEventHandler {
     }
 
     public void timeout(final NHttpServerConnection conn) throws IOException {
-        State state = getState(conn);
+        final State state = getState(conn);
         if (state != null) {
             closeHandlers(state, new SocketTimeoutException());
         }
@@ -387,24 +420,21 @@ public class HttpAsyncService implements NHttpServerEventHandler {
     }
 
     private State ensureNotNull(final State state) {
-        if (state == null) {
-            throw new IllegalStateException("HTTP exchange state is null");
-        }
+        Asserts.notNull(state, "HTTP exchange state");
         return state;
     }
 
     private HttpAsyncRequestConsumer<Object> ensureNotNull(final HttpAsyncRequestConsumer<Object> requestConsumer) {
-        if (requestConsumer == null) {
-            throw new IllegalStateException("Request consumer is null");
-        }
+        Asserts.notNull(requestConsumer, "Request consumer");
         return requestConsumer;
     }
 
     /**
-     * This method can be used to log I/O exception thrown while closing {@link Closeable}
-     * objects (such as {@link HttpConnection}).
+     * This method can be used to log I/O exception thrown while closing
+     * {@link java.io.Closeable} objects (such as
+     * {@link org.apache.http.HttpConnection}).
      *
-     * @param ex I/O exception thrown by {@link Closeable#close()}
+     * @param ex I/O exception thrown by {@link java.io.Closeable#close()}
      */
     protected void log(final Exception ex) {
     }
@@ -412,7 +442,7 @@ public class HttpAsyncService implements NHttpServerEventHandler {
     private void closeConnection(final NHttpConnection conn) {
         try {
             conn.close();
-        } catch (IOException ex) {
+        } catch (final IOException ex) {
             log(ex);
         }
     }
@@ -420,32 +450,32 @@ public class HttpAsyncService implements NHttpServerEventHandler {
     private void shutdownConnection(final NHttpConnection conn) {
         try {
             conn.shutdown();
-        } catch (IOException ex) {
+        } catch (final IOException ex) {
             log(ex);
         }
     }
 
     private void closeHandlers(final State state, final Exception ex) {
-        HttpAsyncRequestConsumer<Object> consumer = state.getRequestConsumer();
+        final HttpAsyncRequestConsumer<Object> consumer = state.getRequestConsumer();
         if (consumer != null) {
             try {
                 consumer.failed(ex);
             } finally {
                 try {
                     consumer.close();
-                } catch (IOException ioex) {
+                } catch (final IOException ioex) {
                     log(ioex);
                 }
             }
         }
-        HttpAsyncResponseProducer producer = state.getResponseProducer();
+        final HttpAsyncResponseProducer producer = state.getResponseProducer();
         if (producer != null) {
             try {
                 producer.failed(ex);
             } finally {
                 try {
                     producer.close();
-                } catch (IOException ioex) {
+                } catch (final IOException ioex) {
                     log(ioex);
                 }
             }
@@ -453,19 +483,19 @@ public class HttpAsyncService implements NHttpServerEventHandler {
     }
 
     private void closeHandlers(final State state) {
-        HttpAsyncRequestConsumer<Object> consumer = state.getRequestConsumer();
+        final HttpAsyncRequestConsumer<Object> consumer = state.getRequestConsumer();
         if (consumer != null) {
             try {
                 consumer.close();
-            } catch (IOException ioex) {
+            } catch (final IOException ioex) {
                 log(ioex);
             }
         }
-        HttpAsyncResponseProducer producer = state.getResponseProducer();
+        final HttpAsyncResponseProducer producer = state.getResponseProducer();
         if (producer != null) {
             try {
                 producer.close();
-            } catch (IOException ioex) {
+            } catch (final IOException ioex) {
                 log(ioex);
             }
         }
@@ -485,9 +515,9 @@ public class HttpAsyncService implements NHttpServerEventHandler {
         if (message == null) {
             message = ex.toString();
         }
-        HttpResponse response = this.responseFactory.newHttpResponse(HttpVersion.HTTP_1_1,
+        final HttpResponse response = this.responseFactory.newHttpResponse(HttpVersion.HTTP_1_1,
                 code, context);
-        return new ErrorResponseProducer(response, 
+        return new ErrorResponseProducer(response,
                 new NStringEntity(message, ContentType.DEFAULT_TEXT), false);
     }
 
@@ -495,7 +525,7 @@ public class HttpAsyncService implements NHttpServerEventHandler {
         if (request != null && "HEAD".equalsIgnoreCase(request.getRequestLine().getMethod())) {
             return false;
         }
-        int status = response.getStatusLine().getStatusCode();
+        final int status = response.getStatusLine().getStatusCode();
         return status >= HttpStatus.SC_OK
             && status != HttpStatus.SC_NO_CONTENT
             && status != HttpStatus.SC_NOT_MODIFIED
@@ -504,28 +534,28 @@ public class HttpAsyncService implements NHttpServerEventHandler {
 
     private void processRequest(
             final NHttpServerConnection conn,
-            final State state) throws HttpException, IOException {
-        HttpAsyncRequestHandler<Object> handler = state.getRequestHandler();
-        HttpContext context = state.getContext();
-        HttpAsyncRequestConsumer<?> consumer = state.getRequestConsumer();
+            final State state) throws IOException {
+        final HttpAsyncRequestHandler<Object> handler = state.getRequestHandler();
+        final HttpContext context = state.getContext();
+        final HttpAsyncRequestConsumer<?> consumer = state.getRequestConsumer();
         consumer.requestCompleted(context);
         state.setRequestState(MessageState.COMPLETED);
         state.setResponseState(MessageState.INIT);
-        Exception exception = consumer.getException();
+        final Exception exception = consumer.getException();
         if (exception != null) {
-            HttpAsyncResponseProducer responseProducer = handleException(exception, context);
+            final HttpAsyncResponseProducer responseProducer = handleException(exception, context);
             state.setResponseProducer(responseProducer);
             conn.requestOutput();
         } else {
-            HttpRequest request = state.getRequest();
-            Object result = consumer.getResult();
-            HttpResponse response = this.responseFactory.newHttpResponse(HttpVersion.HTTP_1_1,
+            final HttpRequest request = state.getRequest();
+            final Object result = consumer.getResult();
+            final HttpResponse response = this.responseFactory.newHttpResponse(HttpVersion.HTTP_1_1,
                     HttpStatus.SC_OK, context);
-            Exchange httpexchange = new Exchange(request, response, state, conn);
+            final Exchange httpexchange = new Exchange(request, response, state, conn);
             try {
                 handler.handle(result, httpexchange, context);
-            } catch (HttpException ex) {
-                HttpAsyncResponseProducer responseProducer = handleException(ex, context);
+            } catch (final HttpException ex) {
+                final HttpAsyncResponseProducer responseProducer = handleException(ex, context);
                 state.setResponseProducer(responseProducer);
                 conn.requestOutput();
             }
@@ -535,12 +565,11 @@ public class HttpAsyncService implements NHttpServerEventHandler {
     private void commitFinalResponse(
             final NHttpServerConnection conn,
             final State state) throws IOException, HttpException {
-        HttpContext context = state.getContext();
-        HttpRequest request = state.getRequest();
-        HttpResponse response = state.getResponse();
+        final HttpContext context = state.getContext();
+        final HttpRequest request = state.getRequest();
+        final HttpResponse response = state.getResponse();
 
-        response.setParams(new DefaultedHttpParams(response.getParams(), this.params));
-        context.setAttribute(ExecutionContext.HTTP_RESPONSE, response);
+        context.setAttribute(HttpCoreContext.HTTP_RESPONSE, response);
         this.httpProcessor.process(response, context);
 
         HttpEntity entity = response.getEntity();
@@ -552,7 +581,7 @@ public class HttpAsyncService implements NHttpServerEventHandler {
         conn.submitResponse(response);
 
         if (entity == null) {
-            HttpAsyncResponseProducer responseProducer = state.getResponseProducer();
+            final HttpAsyncResponseProducer responseProducer = state.getResponseProducer();
             responseProducer.responseCompleted(context);
             if (!this.connStrategy.keepAlive(response, context)) {
                 conn.close();
@@ -562,7 +591,6 @@ public class HttpAsyncService implements NHttpServerEventHandler {
             }
             closeHandlers(state);
             state.reset();
-            conn.setSocketTimeout(HttpConnectionParams.getSoTimeout(this.params));
         } else {
             state.setResponseState(MessageState.BODY_STREAM);
         }
@@ -571,9 +599,8 @@ public class HttpAsyncService implements NHttpServerEventHandler {
     @SuppressWarnings("unchecked")
     private HttpAsyncRequestHandler<Object> getRequestHandler(final HttpRequest request) {
         HttpAsyncRequestHandler<Object> handler = null;
-        if (this.handlerResolver != null) {
-            String requestURI = request.getRequestLine().getUri();
-            handler = (HttpAsyncRequestHandler<Object>) this.handlerResolver.lookup(requestURI);
+        if (this.handlerMapper != null) {
+            handler = (HttpAsyncRequestHandler<Object>) this.handlerMapper.lookup(request);
         }
         if (handler == null) {
             handler = new NullRequestHandler();
@@ -691,7 +718,7 @@ public class HttpAsyncService implements NHttpServerEventHandler {
 
         @Override
         public String toString() {
-            StringBuilder buf = new StringBuilder();
+            final StringBuilder buf = new StringBuilder();
             buf.append("request state: ");
             buf.append(this.requestState);
             buf.append("; request: ");
@@ -741,9 +768,7 @@ public class HttpAsyncService implements NHttpServerEventHandler {
 
         public void setCallback(final Cancellable cancellable) {
             synchronized (this) {
-                if (this.completed) {
-                    throw new IllegalStateException("Response already submitted");
-                }
+                Asserts.check(!this.completed, "Response already submitted");
                 if (this.state.isTerminated() && cancellable != null) {
                     cancellable.cancel();
                 } else {
@@ -754,13 +779,9 @@ public class HttpAsyncService implements NHttpServerEventHandler {
         }
 
         public void submitResponse(final HttpAsyncResponseProducer responseProducer) {
-            if (responseProducer == null) {
-                throw new IllegalArgumentException("Response producer may not be null");
-            }
+            Args.notNull(responseProducer, "Response producer");
             synchronized (this) {
-                if (this.completed) {
-                    throw new IllegalStateException("Response already submitted");
-                }
+                Asserts.check(!this.completed, "Response already submitted");
                 this.completed = true;
                 if (!this.state.isTerminated()) {
                     this.state.setResponseProducer(responseProducer);
@@ -769,7 +790,7 @@ public class HttpAsyncService implements NHttpServerEventHandler {
                 } else {
                     try {
                         responseProducer.close();
-                    } catch (IOException ex) {
+                    } catch (final IOException ex) {
                     }
                 }
             }
@@ -783,7 +804,7 @@ public class HttpAsyncService implements NHttpServerEventHandler {
             return this.completed;
         }
 
-        public void setTimeout(int timeout) {
+        public void setTimeout(final int timeout) {
             this.conn.setSocketTimeout(timeout);
         }
 
@@ -793,4 +814,22 @@ public class HttpAsyncService implements NHttpServerEventHandler {
 
     }
 
+    /**
+     * Adaptor class to transition from HttpAsyncRequestHandlerResolver to HttpAsyncRequestHandlerMapper.
+     */
+    @Deprecated
+    private static class HttpAsyncRequestHandlerResolverAdapter implements HttpAsyncRequestHandlerMapper {
+
+        private final HttpAsyncRequestHandlerResolver resolver;
+
+        public HttpAsyncRequestHandlerResolverAdapter(final HttpAsyncRequestHandlerResolver resolver) {
+            this.resolver = resolver;
+        }
+
+        public HttpAsyncRequestHandler<?> lookup(final HttpRequest request) {
+            return resolver.lookup(request.getRequestLine().getUri());
+        }
+
+    }
+
 }
diff --git a/httpcore-nio/src/main/java/org/apache/http/nio/protocol/NullRequestConsumer.java b/httpcore-nio/src/main/java/org/apache/http/nio/protocol/NullRequestConsumer.java
index 196cf2d..2ffeaaf 100644
--- a/httpcore-nio/src/main/java/org/apache/http/nio/protocol/NullRequestConsumer.java
+++ b/httpcore-nio/src/main/java/org/apache/http/nio/protocol/NullRequestConsumer.java
@@ -66,7 +66,7 @@ class NullRequestConsumer implements HttpAsyncRequestConsumer<Object> {
     }
 
     public Object getResult() {
-        return this.completed;
+        return Boolean.valueOf(this.completed);
     }
 
     public Exception getException() {
diff --git a/httpcore-nio/src/main/java/org/apache/http/nio/protocol/NullRequestHandler.java b/httpcore-nio/src/main/java/org/apache/http/nio/protocol/NullRequestHandler.java
index 210428f..f2867bc 100644
--- a/httpcore-nio/src/main/java/org/apache/http/nio/protocol/NullRequestHandler.java
+++ b/httpcore-nio/src/main/java/org/apache/http/nio/protocol/NullRequestHandler.java
@@ -49,7 +49,7 @@ class NullRequestHandler implements HttpAsyncRequestHandler<Object> {
             final Object obj,
             final HttpAsyncExchange httpexchange,
             final HttpContext context) {
-        HttpResponse response = httpexchange.getResponse();
+        final HttpResponse response = httpexchange.getResponse();
         response.setStatusCode(HttpStatus.SC_NOT_IMPLEMENTED);
         httpexchange.submitResponse(new ErrorResponseProducer(
                 response, new NStringEntity("Service not implemented", ContentType.TEXT_PLAIN), true));
diff --git a/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncRequestHandlerRegistry.java b/httpcore-nio/src/main/java/org/apache/http/nio/protocol/UriHttpAsyncRequestHandlerMapper.java
similarity index 60%
rename from httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncRequestHandlerRegistry.java
rename to httpcore-nio/src/main/java/org/apache/http/nio/protocol/UriHttpAsyncRequestHandlerMapper.java
index b4f804a..e01f386 100644
--- a/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncRequestHandlerRegistry.java
+++ b/httpcore-nio/src/main/java/org/apache/http/nio/protocol/UriHttpAsyncRequestHandlerMapper.java
@@ -27,10 +27,10 @@
 
 package org.apache.http.nio.protocol;
 
-import java.util.Map;
-
+import org.apache.http.HttpRequest;
 import org.apache.http.annotation.ThreadSafe;
 import org.apache.http.protocol.UriPatternMatcher;
+import org.apache.http.util.Args;
 
 /**
  * Maintains a map of HTTP request handlers keyed by a request URI pattern.
@@ -42,23 +42,28 @@ import org.apache.http.protocol.UriPatternMatcher;
  *   <li><code><uri>*</code></li>
  * </ul>
  * <br>
- * This class can be used to resolve an instance of {@link HttpAsyncRequestHandler}
- * matching a particular request URI. Usually the resolved request handler
+ * This class can be used to map an instance of {@link HttpAsyncRequestHandler}
+ * matching a particular request URI. Usually the mapped request handler
  * will be used to process the request with the specified request URI.
  *
- * @since 4.2
+ * @since 4.3
  */
 @ThreadSafe
-public class HttpAsyncRequestHandlerRegistry implements HttpAsyncRequestHandlerResolver {
+public class UriHttpAsyncRequestHandlerMapper implements HttpAsyncRequestHandlerMapper {
 
     private final UriPatternMatcher<HttpAsyncRequestHandler<?>> matcher;
 
-    public HttpAsyncRequestHandlerRegistry() {
-        matcher = new UriPatternMatcher<HttpAsyncRequestHandler<?>>();
+    protected UriHttpAsyncRequestHandlerMapper(final UriPatternMatcher<HttpAsyncRequestHandler<?>> matcher) {
+        super();
+        this.matcher = Args.notNull(matcher, "Pattern matcher");
+    }
+
+    public UriHttpAsyncRequestHandlerMapper() {
+        this(new UriPatternMatcher<HttpAsyncRequestHandler<?>>());
     }
 
     /**
-     * Registers the given {@link NHttpRequestHandler} as a handler for URIs
+     * Registers the given {@link HttpAsyncRequestHandler} as a handler for URIs
      * matching the given pattern.
      *
      * @param pattern the pattern to register the handler for.
@@ -78,23 +83,30 @@ public class HttpAsyncRequestHandlerRegistry implements HttpAsyncRequestHandlerR
     }
 
     /**
-     * Sets handlers from the given map.
-     * @param map the map containing handlers keyed by their URI patterns.
+     * Extracts request path from the given {@link HttpRequest}
      */
-    public void setHandlers(final Map<String, HttpAsyncRequestHandler<?>> map) {
-        matcher.setObjects(map);
+    protected String getRequestPath(final HttpRequest request) {
+        String uriPath = request.getRequestLine().getUri();
+        int index = uriPath.indexOf("?");
+        if (index != -1) {
+            uriPath = uriPath.substring(0, index);
+        } else {
+            index = uriPath.indexOf("#");
+            if (index != -1) {
+                uriPath = uriPath.substring(0, index);
+            }
+        }
+        return uriPath;
     }
 
     /**
-     * Get the handler map.
-     * @return The map of handlers and their associated URI patterns.
+     * Looks up a handler matching the given request URI.
+     *
+     * @param request the request
+     * @return handler or <code>null</code> if no match is found.
      */
-    public Map<String, HttpAsyncRequestHandler<?>> getHandlers() {
-        return matcher.getObjects();
-    }
-
-    public HttpAsyncRequestHandler<?> lookup(String requestURI) {
-        return matcher.lookup(requestURI);
+    public HttpAsyncRequestHandler<?> lookup(final HttpRequest request) {
+        return matcher.lookup(getRequestPath(request));
     }
 
 }
diff --git a/httpcore-nio/src/main/java/org/apache/http/nio/reactor/IOReactorStatus.java b/httpcore-nio/src/main/java/org/apache/http/nio/reactor/IOReactorStatus.java
index 4a26228..b671b13 100644
--- a/httpcore-nio/src/main/java/org/apache/http/nio/reactor/IOReactorStatus.java
+++ b/httpcore-nio/src/main/java/org/apache/http/nio/reactor/IOReactorStatus.java
@@ -57,6 +57,6 @@ public enum IOReactorStatus {
     /**
      * The reactor has shut down.
      */
-    SHUT_DOWN;
+    SHUT_DOWN
 
 }
diff --git a/httpcore-nio/src/main/java/org/apache/http/nio/reactor/IOSession.java b/httpcore-nio/src/main/java/org/apache/http/nio/reactor/IOSession.java
index 39ec796..55840dd 100644
--- a/httpcore-nio/src/main/java/org/apache/http/nio/reactor/IOSession.java
+++ b/httpcore-nio/src/main/java/org/apache/http/nio/reactor/IOSession.java
@@ -174,8 +174,6 @@ public interface IOSession {
      * <p>
      * I/O sessions can be made aware of the status of external session buffers
      * using the {@link SessionBufferStatus} interface.
-     *
-     * @param status
      */
     void setBufferStatus(SessionBufferStatus status);
 
diff --git a/httpcore-nio/src/main/java/org/apache/http/nio/reactor/ListeningIOReactor.java b/httpcore-nio/src/main/java/org/apache/http/nio/reactor/ListeningIOReactor.java
index 7bbdd58..9a1832c 100644
--- a/httpcore-nio/src/main/java/org/apache/http/nio/reactor/ListeningIOReactor.java
+++ b/httpcore-nio/src/main/java/org/apache/http/nio/reactor/ListeningIOReactor.java
@@ -27,9 +27,9 @@
 
 package org.apache.http.nio.reactor;
 
+import java.io.IOException;
 import java.net.SocketAddress;
 import java.util.Set;
-import java.io.IOException;
 
 /**
  * ListeningIOReactor represents an I/O reactor capable of listening for
diff --git a/httpcore-nio/src/main/java/org/apache/http/nio/reactor/SessionBufferStatus.java b/httpcore-nio/src/main/java/org/apache/http/nio/reactor/SessionBufferStatus.java
index bab50e5..bb214ea 100644
--- a/httpcore-nio/src/main/java/org/apache/http/nio/reactor/SessionBufferStatus.java
+++ b/httpcore-nio/src/main/java/org/apache/http/nio/reactor/SessionBufferStatus.java
@@ -1,6 +1,4 @@
 /*
- * $Date:
- *
  * ====================================================================
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements.  See the NOTICE file
@@ -26,7 +24,6 @@
  * <http://www.apache.org/>.
  *
  */
-
 package org.apache.http.nio.reactor;
 
 /**
diff --git a/httpcore-nio/src/main/java/org/apache/http/nio/reactor/SessionInputBuffer.java b/httpcore-nio/src/main/java/org/apache/http/nio/reactor/SessionInputBuffer.java
index 2c19fca..cdc949a 100644
--- a/httpcore-nio/src/main/java/org/apache/http/nio/reactor/SessionInputBuffer.java
+++ b/httpcore-nio/src/main/java/org/apache/http/nio/reactor/SessionInputBuffer.java
@@ -143,7 +143,7 @@ public interface SessionInputBuffer {
      * specific implementations of this interface.
      *
      * @param dst the destination buffer.
-     * @param endOfStream
+     * @param endOfStream end of stream flag
      * @return <code>true</code> if a sequence of chars representing a complete
      *  line has been transferred to the destination buffer, <code>false</code>
      *  otherwise.
@@ -168,7 +168,7 @@ public interface SessionInputBuffer {
      * The choice of a char encoding and line delimiter sequence is up to the
      * specific implementations of this interface.
      *
-     * @param endOfStream
+     * @param endOfStream end of stream flag
      * @return a string representing a complete line, if available.
      * <code>null</code> otherwise.
      *
diff --git a/httpcore-nio/src/main/java/org/apache/http/nio/reactor/SocketAccessor.java b/httpcore-nio/src/main/java/org/apache/http/nio/reactor/SocketAccessor.java
index 3a50aac..f1062e4 100644
--- a/httpcore-nio/src/main/java/org/apache/http/nio/reactor/SocketAccessor.java
+++ b/httpcore-nio/src/main/java/org/apache/http/nio/reactor/SocketAccessor.java
@@ -38,7 +38,7 @@ public interface SocketAccessor {
 
     /**
      * Return the underlying socket
-     * 
+     *
      * @return - the underlying Socket, may be <code>null</code>.
      */
     Socket getSocket();
diff --git a/httpcore-nio/src/main/java/org/apache/http/nio/reactor/ssl/SSLIOSession.java b/httpcore-nio/src/main/java/org/apache/http/nio/reactor/ssl/SSLIOSession.java
index c579e14..6cf8f8e 100644
--- a/httpcore-nio/src/main/java/org/apache/http/nio/reactor/ssl/SSLIOSession.java
+++ b/httpcore-nio/src/main/java/org/apache/http/nio/reactor/ssl/SSLIOSession.java
@@ -27,19 +27,6 @@
 
 package org.apache.http.nio.reactor.ssl;
 
-import org.apache.http.annotation.ThreadSafe;
-import org.apache.http.nio.reactor.EventMask;
-import org.apache.http.nio.reactor.IOSession;
-import org.apache.http.nio.reactor.SocketAccessor;
-import org.apache.http.nio.reactor.SessionBufferStatus;
-
-import javax.net.ssl.SSLContext;
-import javax.net.ssl.SSLEngine;
-import javax.net.ssl.SSLEngineResult;
-import javax.net.ssl.SSLSession;
-import javax.net.ssl.SSLEngineResult.HandshakeStatus;
-import javax.net.ssl.SSLEngineResult.Status;
-import javax.net.ssl.SSLException;
 import java.io.IOException;
 import java.net.InetSocketAddress;
 import java.net.Socket;
@@ -48,6 +35,22 @@ import java.nio.ByteBuffer;
 import java.nio.channels.ByteChannel;
 import java.nio.channels.SelectionKey;
 
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLEngine;
+import javax.net.ssl.SSLEngineResult;
+import javax.net.ssl.SSLEngineResult.HandshakeStatus;
+import javax.net.ssl.SSLEngineResult.Status;
+import javax.net.ssl.SSLException;
+import javax.net.ssl.SSLSession;
+
+import org.apache.http.annotation.ThreadSafe;
+import org.apache.http.nio.reactor.EventMask;
+import org.apache.http.nio.reactor.IOSession;
+import org.apache.http.nio.reactor.SessionBufferStatus;
+import org.apache.http.nio.reactor.SocketAccessor;
+import org.apache.http.util.Args;
+import org.apache.http.util.Asserts;
+
 /**
  * <tt>SSLIOSession</tt> is a decorator class intended to transparently extend
  * an {@link IOSession} with transport layer security capabilities based on
@@ -105,12 +108,8 @@ public class SSLIOSession implements IOSession, SessionBufferStatus, SocketAcces
             final SSLContext sslContext,
             final SSLSetupHandler handler) {
         super();
-        if (session == null) {
-            throw new IllegalArgumentException("IO session may not be null");
-        }
-        if (sslContext == null) {
-            throw new IllegalArgumentException("SSL context may not be null");
-        }
+        Args.notNull(session, "IO session");
+        Args.notNull(sslContext, "SSL context");
         this.session = session;
         this.defaultMode = defaultMode;
         this.appEventMask = session.getEventMask();
@@ -120,22 +119,22 @@ public class SSLIOSession implements IOSession, SessionBufferStatus, SocketAcces
         // Override the status buffer interface
         this.session.setBufferStatus(this);
 
-        SocketAddress address = session.getRemoteAddress();
+        final SocketAddress address = session.getRemoteAddress();
         if (address instanceof InetSocketAddress) {
-            String hostname = ((InetSocketAddress) address).getHostName();
-            int port = ((InetSocketAddress) address).getPort();
+            final String hostname = ((InetSocketAddress) address).getHostName();
+            final int port = ((InetSocketAddress) address).getPort();
             this.sslEngine = sslContext.createSSLEngine(hostname, port);
         } else {
             this.sslEngine = sslContext.createSSLEngine();
         }
 
         // Allocate buffers for network (encrypted) data
-        int netBuffersize = this.sslEngine.getSession().getPacketBufferSize();
+        final int netBuffersize = this.sslEngine.getSession().getPacketBufferSize();
         this.inEncrypted = ByteBuffer.allocate(netBuffersize);
         this.outEncrypted = ByteBuffer.allocate(netBuffersize);
 
         // Allocate buffers for application (unencrypted) data
-        int appBuffersize = this.sslEngine.getSession().getApplicationBufferSize();
+        final int appBuffersize = this.sslEngine.getSession().getApplicationBufferSize();
         this.inPlain = ByteBuffer.allocate(appBuffersize);
         this.outPlain = ByteBuffer.allocate(appBuffersize);
     }
@@ -163,9 +162,7 @@ public class SSLIOSession implements IOSession, SessionBufferStatus, SocketAcces
      * @throws IllegalStateException if the session has already been initialized.
      */
     public synchronized void initialize(final SSLMode mode) throws SSLException {
-        if (this.initialized) {
-            throw new IllegalStateException("SSL I/O session already initialized");
-        }
+        Asserts.check(!this.initialized, "SSL I/O session already initialized");
         if (this.status >= IOSession.CLOSING) {
             return;
         }
@@ -207,7 +204,7 @@ public class SSLIOSession implements IOSession, SessionBufferStatus, SocketAcces
     //
     // sun.security.pkcs11.wrapper.PKCS11Exception is re-thrown as
     // plain RuntimeException in sun.security.ssl.Handshaker#checkThrown
-    private SSLException convert(final RuntimeException ex) throws SSLException {
+    private SSLException convert(final RuntimeException ex) {
         Throwable cause = ex.getCause();
         if (cause == null) {
             cause = ex;
@@ -218,7 +215,7 @@ public class SSLIOSession implements IOSession, SessionBufferStatus, SocketAcces
     private SSLEngineResult doWrap(final ByteBuffer src, final ByteBuffer dst) throws SSLException {
         try {
             return this.sslEngine.wrap(src, dst);
-        } catch (RuntimeException ex) {
+        } catch (final RuntimeException ex) {
             throw convert(ex);
         }
     }
@@ -226,18 +223,18 @@ public class SSLIOSession implements IOSession, SessionBufferStatus, SocketAcces
     private SSLEngineResult doUnwrap(final ByteBuffer src, final ByteBuffer dst) throws SSLException {
         try {
             return this.sslEngine.unwrap(src, dst);
-        } catch (RuntimeException ex) {
+        } catch (final RuntimeException ex) {
             throw convert(ex);
         }
     }
 
     private void doRunTask() throws SSLException {
         try {
-            Runnable r = this.sslEngine.getDelegatedTask();
+            final Runnable r = this.sslEngine.getDelegatedTask();
             if (r != null) {
                 r.run();
             }
-        } catch (RuntimeException ex) {
+        } catch (final RuntimeException ex) {
             throw convert(ex);
         }
     }
@@ -303,7 +300,7 @@ public class SSLIOSession implements IOSession, SessionBufferStatus, SocketAcces
             return;
         }
         // Need to toggle the event mask for this channel?
-        int oldMask = this.session.getEventMask();
+        final int oldMask = this.session.getEventMask();
         int newMask = oldMask;
         switch (this.sslEngine.getHandshakeStatus()) {
         case NEED_WRAP:
@@ -334,7 +331,7 @@ public class SSLIOSession implements IOSession, SessionBufferStatus, SocketAcces
 
     private int sendEncryptedData() throws IOException {
         this.outEncrypted.flip();
-        int bytesWritten = this.session.channel().write(this.outEncrypted);
+        final int bytesWritten = this.session.channel().write(this.outEncrypted);
         this.outEncrypted.compact();
         return bytesWritten;
     }
@@ -350,7 +347,7 @@ public class SSLIOSession implements IOSession, SessionBufferStatus, SocketAcces
         boolean decrypted = false;
         while (this.inEncrypted.position() > 0) {
             this.inEncrypted.flip();
-            SSLEngineResult result = doUnwrap(this.inEncrypted, this.inPlain);
+            final SSLEngineResult result = doUnwrap(this.inEncrypted, this.inPlain);
             this.inEncrypted.compact();
             if (result.getStatus() == Status.OK) {
                 decrypted = true;
@@ -374,12 +371,12 @@ public class SSLIOSession implements IOSession, SessionBufferStatus, SocketAcces
      * @throws IOException in case of an I/O error.
      */
     public synchronized boolean isAppInputReady() throws IOException {
-        int bytesRead = receiveEncryptedData();
+        final int bytesRead = receiveEncryptedData();
         if (bytesRead == -1) {
             this.endOfStream = true;
         }
         doHandshake();
-        HandshakeStatus status = this.sslEngine.getHandshakeStatus();
+        final HandshakeStatus status = this.sslEngine.getHandshakeStatus();
         if (status == HandshakeStatus.NOT_HANDSHAKING || status == HandshakeStatus.FINISHED) {
             decryptData();
         }
@@ -437,9 +434,7 @@ public class SSLIOSession implements IOSession, SessionBufferStatus, SocketAcces
     }
 
     private synchronized int writePlain(final ByteBuffer src) throws SSLException {
-        if (src == null) {
-            throw new IllegalArgumentException("Byte buffer may not be null");
-        }
+        Args.notNull(src, "Byte buffer");
         if (this.status != ACTIVE) {
             return -1;
         }
@@ -449,7 +444,7 @@ public class SSLIOSession implements IOSession, SessionBufferStatus, SocketAcces
             this.outPlain.compact();
         }
         if (this.outPlain.position() == 0) {
-            SSLEngineResult result = doWrap(src, this.outEncrypted);
+            final SSLEngineResult result = doWrap(src, this.outEncrypted);
             if (result.getStatus() == Status.CLOSED) {
                 this.status = CLOSED;
             }
@@ -460,12 +455,10 @@ public class SSLIOSession implements IOSession, SessionBufferStatus, SocketAcces
     }
 
     private synchronized int readPlain(final ByteBuffer dst) {
-        if (dst == null) {
-            throw new IllegalArgumentException("Byte buffer may not be null");
-        }
+        Args.notNull(dst, "Byte buffer");
         if (this.inPlain.position() > 0) {
             this.inPlain.flip();
-            int n = Math.min(this.inPlain.remaining(), dst.remaining());
+            final int n = Math.min(this.inPlain.remaining(), dst.remaining());
             for (int i = 0; i < n; i++) {
                 dst.put(this.inPlain.get());
             }
@@ -521,17 +514,17 @@ public class SSLIOSession implements IOSession, SessionBufferStatus, SocketAcces
         return this.appEventMask;
     }
 
-    public synchronized void setEventMask(int ops) {
+    public synchronized void setEventMask(final int ops) {
         this.appEventMask = ops;
         updateEventMask();
     }
 
-    public synchronized void setEvent(int op) {
+    public synchronized void setEvent(final int op) {
         this.appEventMask = this.appEventMask | op;
         updateEventMask();
     }
 
-    public synchronized void clearEvent(int op) {
+    public synchronized void clearEvent(final int op) {
         this.appEventMask = this.appEventMask & ~op;
         updateEventMask();
     }
@@ -540,7 +533,7 @@ public class SSLIOSession implements IOSession, SessionBufferStatus, SocketAcces
         return this.session.getSocketTimeout();
     }
 
-    public void setSocketTimeout(int timeout) {
+    public void setSocketTimeout(final int timeout) {
         this.session.setSocketTimeout(timeout);
     }
 
@@ -572,7 +565,7 @@ public class SSLIOSession implements IOSession, SessionBufferStatus, SocketAcces
         this.session.setAttribute(name, obj);
     }
 
-    private static void formatOps(final StringBuilder buffer, int ops) {
+    private static void formatOps(final StringBuilder buffer, final int ops) {
         if ((ops & SelectionKey.OP_READ) > 0) {
             buffer.append('r');
         }
@@ -582,8 +575,8 @@ public class SSLIOSession implements IOSession, SessionBufferStatus, SocketAcces
     }
 
     @Override
-    public synchronized String toString() {
-        StringBuilder buffer = new StringBuilder();
+    public String toString() {
+        final StringBuilder buffer = new StringBuilder();
         buffer.append(this.session);
         buffer.append("[");
         switch (this.status) {
@@ -621,13 +614,13 @@ public class SSLIOSession implements IOSession, SessionBufferStatus, SocketAcces
         buffer.append("]");
         return buffer.toString();
     }
-    
+
     public Socket getSocket(){
-    	if (this.session instanceof SocketAccessor){
-    		return ((SocketAccessor) this.session).getSocket();
-    	} else {
-    		return null;
-    	}
+        if (this.session instanceof SocketAccessor){
+            return ((SocketAccessor) this.session).getSocket();
+        } else {
+            return null;
+        }
     }
 
     private class InternalByteChannel implements ByteChannel {
diff --git a/httpcore-nio/src/main/java/org/apache/http/nio/util/ContentInputBuffer.java b/httpcore-nio/src/main/java/org/apache/http/nio/util/ContentInputBuffer.java
index 635c36b..0431a40 100644
--- a/httpcore-nio/src/main/java/org/apache/http/nio/util/ContentInputBuffer.java
+++ b/httpcore-nio/src/main/java/org/apache/http/nio/util/ContentInputBuffer.java
@@ -32,7 +32,7 @@ import java.io.IOException;
 import org.apache.http.nio.ContentDecoder;
 
 /**
- * Buffer for storing content streamed out from a {@link ContentDecoder}.
+ * Generic content input buffer.
  *
  * @since 4.0
  */
@@ -45,7 +45,10 @@ public interface ContentInputBuffer {
      * @param decoder the content decoder.
      * @return number of bytes read.
      * @throws IOException in case of an I/O error.
+     *
+     * @deprecated (4.3) use implementation specific methods.
      */
+    @Deprecated
     int consumeContent(ContentDecoder decoder) throws IOException;
 
     /**
diff --git a/httpcore-nio/src/main/java/org/apache/http/nio/util/ContentOutputBuffer.java b/httpcore-nio/src/main/java/org/apache/http/nio/util/ContentOutputBuffer.java
index 7946bc8..49e01bf 100644
--- a/httpcore-nio/src/main/java/org/apache/http/nio/util/ContentOutputBuffer.java
+++ b/httpcore-nio/src/main/java/org/apache/http/nio/util/ContentOutputBuffer.java
@@ -32,7 +32,7 @@ import java.io.IOException;
 import org.apache.http.nio.ContentEncoder;
 
 /**
- * Buffer for storing content to be streamed out to a {@link ContentEncoder}.
+ * Generic content output buffer.
  *
  * @since 4.0
  */
@@ -44,7 +44,10 @@ public interface ContentOutputBuffer {
      * @param encoder content encoder.
      * @return number of bytes written.
      * @throws IOException in case of an I/O error.
+     *
+     * @deprecated (4.3) use implementation specific methods.
      */
+    @Deprecated
     int produceContent(ContentEncoder encoder) throws IOException;
 
     /**
diff --git a/httpcore-nio/src/main/java/org/apache/http/nio/util/DirectByteBufferAllocator.java b/httpcore-nio/src/main/java/org/apache/http/nio/util/DirectByteBufferAllocator.java
index b3637e8..6f716f2 100644
--- a/httpcore-nio/src/main/java/org/apache/http/nio/util/DirectByteBufferAllocator.java
+++ b/httpcore-nio/src/main/java/org/apache/http/nio/util/DirectByteBufferAllocator.java
@@ -40,7 +40,13 @@ import org.apache.http.annotation.Immutable;
 @Immutable
 public class DirectByteBufferAllocator implements ByteBufferAllocator {
 
-    public ByteBuffer allocate(int size) {
+    public static final DirectByteBufferAllocator INSTANCE = new DirectByteBufferAllocator();
+
+    public DirectByteBufferAllocator() {
+        super();
+    }
+
+    public ByteBuffer allocate(final int size) {
         return ByteBuffer.allocateDirect(size);
     }
 
diff --git a/httpcore-nio/src/main/java/org/apache/http/nio/util/ExpandableBuffer.java b/httpcore-nio/src/main/java/org/apache/http/nio/util/ExpandableBuffer.java
index ef89317..e096ff6 100644
--- a/httpcore-nio/src/main/java/org/apache/http/nio/util/ExpandableBuffer.java
+++ b/httpcore-nio/src/main/java/org/apache/http/nio/util/ExpandableBuffer.java
@@ -31,6 +31,7 @@ import java.nio.ByteBuffer;
 
 import org.apache.http.annotation.NotThreadSafe;
 import org.apache.http.io.BufferInfo;
+import org.apache.http.util.Args;
 
 /**
  * A buffer that expand its capacity on demand using {@link ByteBufferAllocator}
@@ -59,11 +60,9 @@ public class ExpandableBuffer implements BufferInfo, org.apache.http.nio.util.Bu
      * @param buffersize the buffer size.
      * @param allocator allocator to be used to allocate {@link ByteBuffer}s.
      */
-    public ExpandableBuffer(int buffersize, final ByteBufferAllocator allocator) {
+    public ExpandableBuffer(final int buffersize, final ByteBufferAllocator allocator) {
         super();
-        if (allocator == null) {
-            throw new IllegalArgumentException("ByteBuffer allocator may not be null");
-        }
+        Args.notNull(allocator, "ByteBuffer allocator");
         this.allocator = allocator;
         this.buffer = allocator.allocate(buffersize);
         this.mode = INPUT_MODE;
@@ -106,8 +105,8 @@ public class ExpandableBuffer implements BufferInfo, org.apache.http.nio.util.Bu
         }
     }
 
-    private void expandCapacity(int capacity) {
-        ByteBuffer oldbuffer = this.buffer;
+    private void expandCapacity(final int capacity) {
+        final ByteBuffer oldbuffer = this.buffer;
         this.buffer = allocator.allocate(capacity);
         oldbuffer.flip();
         this.buffer.put(oldbuffer);
@@ -126,10 +125,8 @@ public class ExpandableBuffer implements BufferInfo, org.apache.http.nio.util.Bu
 
     /**
      * Ensures the buffer can accommodate the required capacity.
-     *
-     * @param requiredCapacity
      */
-    protected void ensureCapacity(int requiredCapacity) {
+    protected void ensureCapacity(final int requiredCapacity) {
         if (requiredCapacity > this.buffer.capacity()) {
             expandCapacity(requiredCapacity);
         }
@@ -185,9 +182,9 @@ public class ExpandableBuffer implements BufferInfo, org.apache.http.nio.util.Bu
 
     @Override
     public String toString() {
-        StringBuilder sb = new StringBuilder();
+        final StringBuilder sb = new StringBuilder();
         sb.append("[mode=");
-        int mode = getMode();
+        final int mode = getMode();
         if (mode == INPUT_MODE) {
             sb.append("in");
         } else {
diff --git a/httpcore-nio/src/main/java/org/apache/http/nio/util/HeapByteBufferAllocator.java b/httpcore-nio/src/main/java/org/apache/http/nio/util/HeapByteBufferAllocator.java
index f3638ce..e194c59 100644
--- a/httpcore-nio/src/main/java/org/apache/http/nio/util/HeapByteBufferAllocator.java
+++ b/httpcore-nio/src/main/java/org/apache/http/nio/util/HeapByteBufferAllocator.java
@@ -40,7 +40,13 @@ import org.apache.http.annotation.Immutable;
 @Immutable
 public class HeapByteBufferAllocator implements ByteBufferAllocator {
 
-    public ByteBuffer allocate(int size) {
+    public static final HeapByteBufferAllocator INSTANCE = new HeapByteBufferAllocator();
+
+    public HeapByteBufferAllocator() {
+        super();
+    }
+
+    public ByteBuffer allocate(final int size) {
         return ByteBuffer.allocate(size);
     }
 
diff --git a/httpcore-nio/src/main/java/org/apache/http/nio/util/SharedInputBuffer.java b/httpcore-nio/src/main/java/org/apache/http/nio/util/SharedInputBuffer.java
index 4610cc4..0a58bae 100644
--- a/httpcore-nio/src/main/java/org/apache/http/nio/util/SharedInputBuffer.java
+++ b/httpcore-nio/src/main/java/org/apache/http/nio/util/SharedInputBuffer.java
@@ -54,23 +54,40 @@ import org.apache.http.nio.IOControl;
 @ThreadSafe
 public class SharedInputBuffer extends ExpandableBuffer implements ContentInputBuffer {
 
-    private final IOControl ioctrl;
     private final ReentrantLock lock;
     private final Condition condition;
 
+    private volatile IOControl ioctrl;
     private volatile boolean shutdown = false;
     private volatile boolean endOfStream = false;
 
-    public SharedInputBuffer(int buffersize, final IOControl ioctrl, final ByteBufferAllocator allocator) {
+    /**
+     * @deprecated (4.3) use {@link SharedInputBuffer#SharedInputBuffer(int, ByteBufferAllocator)}
+     */
+    @Deprecated
+    public SharedInputBuffer(final int buffersize, final IOControl ioctrl, final ByteBufferAllocator allocator) {
         super(buffersize, allocator);
-        if (ioctrl == null) {
-            throw new IllegalArgumentException("I/O content control may not be null");
-        }
         this.ioctrl = ioctrl;
         this.lock = new ReentrantLock();
         this.condition = this.lock.newCondition();
     }
 
+    /**
+     * @since 4.3
+     */
+    public SharedInputBuffer(final int buffersize, final ByteBufferAllocator allocator) {
+        super(buffersize, allocator);
+        this.lock = new ReentrantLock();
+        this.condition = this.lock.newCondition();
+    }
+
+    /**
+     * @since 4.3
+     */
+    public SharedInputBuffer(final int buffersize) {
+        this(buffersize, HeapByteBufferAllocator.INSTANCE);
+    }
+
     public void reset() {
         if (this.shutdown) {
             return;
@@ -84,12 +101,26 @@ public class SharedInputBuffer extends ExpandableBuffer implements ContentInputB
         }
     }
 
+    /**
+     * @deprecated (4.3) use {@link #consumeContent(ContentDecoder, IOControl)}
+     */
+    @Deprecated
     public int consumeContent(final ContentDecoder decoder) throws IOException {
+        return consumeContent(decoder, null);
+    }
+
+    /**
+     * @since 4.3
+     */
+    public int consumeContent(final ContentDecoder decoder, final IOControl ioctrl) throws IOException {
         if (this.shutdown) {
             return -1;
         }
         this.lock.lock();
         try {
+            if (ioctrl != null) {
+                this.ioctrl = ioctrl;
+            }
             setInputMode();
             int totalRead = 0;
             int bytesRead;
@@ -100,7 +131,9 @@ public class SharedInputBuffer extends ExpandableBuffer implements ContentInputB
                 this.endOfStream = true;
             }
             if (!this.buffer.hasRemaining()) {
-                this.ioctrl.suspendInput();
+                if (this.ioctrl != null) {
+                    this.ioctrl.suspendInput();
+                }
             }
             this.condition.signalAll();
 
@@ -166,10 +199,12 @@ public class SharedInputBuffer extends ExpandableBuffer implements ContentInputB
                     if (this.shutdown) {
                         throw new InterruptedIOException("Input operation aborted");
                     }
-                    this.ioctrl.requestInput();
+                    if (this.ioctrl != null) {
+                        this.ioctrl.requestInput();
+                    }
                     this.condition.await();
                 }
-            } catch (InterruptedException ex) {
+            } catch (final InterruptedException ex) {
                 throw new IOException("Interrupted while waiting for more data");
             }
         } finally {
@@ -229,7 +264,7 @@ public class SharedInputBuffer extends ExpandableBuffer implements ContentInputB
         }
     }
 
-    public int read(final byte[] b, int off, int len) throws IOException {
+    public int read(final byte[] b, final int off, final int len) throws IOException {
         if (this.shutdown) {
             return -1;
         }
diff --git a/httpcore-nio/src/main/java/org/apache/http/nio/util/SharedOutputBuffer.java b/httpcore-nio/src/main/java/org/apache/http/nio/util/SharedOutputBuffer.java
index 07db377..3a399fc 100644
--- a/httpcore-nio/src/main/java/org/apache/http/nio/util/SharedOutputBuffer.java
+++ b/httpcore-nio/src/main/java/org/apache/http/nio/util/SharedOutputBuffer.java
@@ -34,6 +34,8 @@ import java.util.concurrent.locks.ReentrantLock;
 import org.apache.http.annotation.ThreadSafe;
 import org.apache.http.nio.ContentEncoder;
 import org.apache.http.nio.IOControl;
+import org.apache.http.util.Args;
+import org.apache.http.util.Asserts;
 
 /**
  * Implementation of the {@link ContentOutputBuffer} interface that can be
@@ -54,23 +56,41 @@ import org.apache.http.nio.IOControl;
 @ThreadSafe
 public class SharedOutputBuffer extends ExpandableBuffer implements ContentOutputBuffer {
 
-    private final IOControl ioctrl;
     private final ReentrantLock lock;
     private final Condition condition;
 
+    private volatile IOControl ioctrl;
     private volatile boolean shutdown = false;
     private volatile boolean endOfStream = false;
 
-    public SharedOutputBuffer(int buffersize, final IOControl ioctrl, final ByteBufferAllocator allocator) {
+    /**
+     * @deprecated (4.3) use {@link SharedOutputBuffer#SharedOutputBuffer(int, ByteBufferAllocator)}
+     */
+    @Deprecated
+    public SharedOutputBuffer(final int buffersize, final IOControl ioctrl, final ByteBufferAllocator allocator) {
         super(buffersize, allocator);
-        if (ioctrl == null) {
-            throw new IllegalArgumentException("I/O content control may not be null");
-        }
+        Args.notNull(ioctrl, "I/O content control");
         this.ioctrl = ioctrl;
         this.lock = new ReentrantLock();
         this.condition = this.lock.newCondition();
     }
 
+    /**
+     * @since 4.3
+     */
+    public SharedOutputBuffer(final int buffersize, final ByteBufferAllocator allocator) {
+        super(buffersize, allocator);
+        this.lock = new ReentrantLock();
+        this.condition = this.lock.newCondition();
+    }
+
+    /**
+     * @since 4.3
+     */
+    public SharedOutputBuffer(final int buffersize) {
+        this(buffersize, HeapByteBufferAllocator.INSTANCE);
+    }
+
     public void reset() {
         if (this.shutdown) {
             return;
@@ -124,12 +144,26 @@ public class SharedOutputBuffer extends ExpandableBuffer implements ContentOutpu
         }
     }
 
+    /**
+     * @deprecated (4.3) use {@link #produceContent(ContentEncoder, IOControl)}
+     */
+    @Deprecated
     public int produceContent(final ContentEncoder encoder) throws IOException {
+        return produceContent(encoder, null);
+    }
+
+    /**
+     * @since 4.3
+     */
+    public int produceContent(final ContentEncoder encoder, final IOControl ioctrl) throws IOException {
         if (this.shutdown) {
             return -1;
         }
         this.lock.lock();
         try {
+            if (ioctrl != null) {
+                this.ioctrl = ioctrl;
+            }
             setOutputMode();
             int bytesWritten = 0;
             if (super.hasData()) {
@@ -146,7 +180,9 @@ public class SharedOutputBuffer extends ExpandableBuffer implements ContentOutpu
                 }
                 if (!this.endOfStream) {
                     // suspend output events
-                    this.ioctrl.suspendOutput();
+                    if (this.ioctrl != null) {
+                        this.ioctrl.suspendOutput();
+                    }
                 }
             }
             this.condition.signalAll();
@@ -173,15 +209,14 @@ public class SharedOutputBuffer extends ExpandableBuffer implements ContentOutpu
         }
     }
 
-    public void write(final byte[] b, int off, int len) throws IOException {
+    public void write(final byte[] b, final int off, final int len) throws IOException {
         if (b == null) {
             return;
         }
+        int pos = off;
         this.lock.lock();
         try {
-            if (this.shutdown || this.endOfStream) {
-                throw new IllegalStateException("Buffer already closed for writing");
-            }
+            Asserts.check(!this.shutdown && !this.endOfStream, "Buffer already closed for writing");
             setInputMode();
             int remaining = len;
             while (remaining > 0) {
@@ -189,10 +224,10 @@ public class SharedOutputBuffer extends ExpandableBuffer implements ContentOutpu
                     flushContent();
                     setInputMode();
                 }
-                int chunk = Math.min(remaining, this.buffer.remaining());
-                this.buffer.put(b, off, chunk);
+                final int chunk = Math.min(remaining, this.buffer.remaining());
+                this.buffer.put(b, pos, chunk);
                 remaining -= chunk;
-                off += chunk;
+                pos += chunk;
             }
         } finally {
             this.lock.unlock();
@@ -206,12 +241,10 @@ public class SharedOutputBuffer extends ExpandableBuffer implements ContentOutpu
         write(b, 0, b.length);
     }
 
-    public void write(int b) throws IOException {
+    public void write(final int b) throws IOException {
         this.lock.lock();
         try {
-            if (this.shutdown || this.endOfStream) {
-                throw new IllegalStateException("Buffer already closed for writing");
-            }
+            Asserts.check(!this.shutdown && !this.endOfStream, "Buffer already closed for writing");
             setInputMode();
             if (!this.buffer.hasRemaining()) {
                 flushContent();
@@ -234,10 +267,12 @@ public class SharedOutputBuffer extends ExpandableBuffer implements ContentOutpu
                     if (this.shutdown) {
                         throw new InterruptedIOException("Output operation aborted");
                     }
-                    this.ioctrl.requestOutput();
+                    if (this.ioctrl != null) {
+                        this.ioctrl.requestOutput();
+                    }
                     this.condition.await();
                 }
-            } catch (InterruptedException ex) {
+            } catch (final InterruptedException ex) {
                 throw new IOException("Interrupted while flushing the content buffer");
             }
         } finally {
@@ -252,7 +287,9 @@ public class SharedOutputBuffer extends ExpandableBuffer implements ContentOutpu
                 return;
             }
             this.endOfStream = true;
-            this.ioctrl.requestOutput();
+            if (this.ioctrl != null) {
+                this.ioctrl.requestOutput();
+            }
         } finally {
             this.lock.unlock();
         }
diff --git a/httpcore-nio/src/main/java/org/apache/http/nio/util/SimpleInputBuffer.java b/httpcore-nio/src/main/java/org/apache/http/nio/util/SimpleInputBuffer.java
index 4f0187d..0aa3d6b 100644
--- a/httpcore-nio/src/main/java/org/apache/http/nio/util/SimpleInputBuffer.java
+++ b/httpcore-nio/src/main/java/org/apache/http/nio/util/SimpleInputBuffer.java
@@ -43,10 +43,17 @@ public class SimpleInputBuffer extends ExpandableBuffer implements ContentInputB
 
     private boolean endOfStream = false;
 
-    public SimpleInputBuffer(int buffersize, final ByteBufferAllocator allocator) {
+    public SimpleInputBuffer(final int buffersize, final ByteBufferAllocator allocator) {
         super(buffersize, allocator);
     }
 
+    /**
+     * @since 4.3
+     */
+    public SimpleInputBuffer(final int buffersize) {
+        this(buffersize, HeapByteBufferAllocator.INSTANCE);
+    }
+
     public void reset() {
         this.endOfStream = false;
         super.clear();
@@ -85,7 +92,7 @@ public class SimpleInputBuffer extends ExpandableBuffer implements ContentInputB
         return this.buffer.get() & 0xff;
     }
 
-    public int read(final byte[] b, int off, int len) throws IOException {
+    public int read(final byte[] b, final int off, final int len) throws IOException {
         if (isEndOfStream()) {
             return -1;
         }
diff --git a/httpcore-nio/src/main/java/org/apache/http/nio/util/SimpleOutputBuffer.java b/httpcore-nio/src/main/java/org/apache/http/nio/util/SimpleOutputBuffer.java
index 27e5eab..479c845 100644
--- a/httpcore-nio/src/main/java/org/apache/http/nio/util/SimpleOutputBuffer.java
+++ b/httpcore-nio/src/main/java/org/apache/http/nio/util/SimpleOutputBuffer.java
@@ -43,21 +43,28 @@ public class SimpleOutputBuffer extends ExpandableBuffer implements ContentOutpu
 
     private boolean endOfStream;
 
-    public SimpleOutputBuffer(int buffersize, final ByteBufferAllocator allocator) {
+    public SimpleOutputBuffer(final int buffersize, final ByteBufferAllocator allocator) {
         super(buffersize, allocator);
         this.endOfStream = false;
     }
 
+    /**
+     * @since 4.3
+     */
+    public SimpleOutputBuffer(final int buffersize) {
+        this(buffersize, HeapByteBufferAllocator.INSTANCE);
+    }
+
     public int produceContent(final ContentEncoder encoder) throws IOException {
         setOutputMode();
-        int bytesWritten = encoder.write(this.buffer);
+        final int bytesWritten = encoder.write(this.buffer);
         if (!hasData() && this.endOfStream) {
             encoder.complete();
         }
         return bytesWritten;
     }
 
-    public void write(final byte[] b, int off, int len) throws IOException {
+    public void write(final byte[] b, final int off, final int len) throws IOException {
         if (b == null) {
             return;
         }
@@ -79,7 +86,7 @@ public class SimpleOutputBuffer extends ExpandableBuffer implements ContentOutpu
         write(b, 0, b.length);
     }
 
-    public void write(int b) throws IOException {
+    public void write(final int b) throws IOException {
         if (this.endOfStream) {
             return;
         }
diff --git a/httpcore-nio/src/main/resources/org/apache/http/nio/version.properties b/httpcore-nio/src/main/resources/org/apache/http/nio/version.properties
index e92771f..5193b7d 100644
--- a/httpcore-nio/src/main/resources/org/apache/http/nio/version.properties
+++ b/httpcore-nio/src/main/resources/org/apache/http/nio/version.properties
@@ -14,7 +14,7 @@
 # "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.    
+# under the License.
 #
 info.module    = Httpcore-nio
 info.release   = ${pom.version}
diff --git a/httpcore-nio/src/site/apt/index.apt b/httpcore-nio/src/site/apt/index.apt
deleted file mode 100644
index 99a6144..0000000
--- a/httpcore-nio/src/site/apt/index.apt
+++ /dev/null
@@ -1,44 +0,0 @@
-~~ ====================================================================
-~~ Licensed to the Apache Software Foundation (ASF) under one
-~~ or more contributor license agreements.  See the NOTICE file
-~~ distributed with this work for additional information
-~~ regarding copyright ownership.  The ASF licenses this file
-~~ to you 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.
-~~ ====================================================================
-~~ 
-~~ This software consists of voluntary contributions made by many
-~~ individuals on behalf of the Apache Software Foundation.  For more
-~~ information on the Apache Software Foundation, please see
-~~ <http://www.apache.org/>.
-
-    ----------
-    HttpComponents HttpCore NIO Extensions Module
-    ----------
-    ----------
-    ----------
-
-HttpCore (NIO Extensions Module)
-
-    This module contains optional extensions to the HttpCore API that
-    leverage the event driven, non-blocking I/O (NIO) model.
-    HttpCore NIO extensions require a Java 5.0 compatible runtime and
-    the HttpCore {{{../httpcore/index.html}base}} module.
-
-    {{{./apidocs/index.html}Javadocs}}
-    
-    {{{./xref/index.html}Project sources}}
-    
-    {{{./dependencies.html}Dependencies}}    
-    
-    {{{./issue-tracking.html}Issue Tracking}}    
diff --git a/httpcore-nio/src/site/resources/css/site.css b/httpcore-nio/src/site/resources/css/site.css
deleted file mode 100644
index 017b79d..0000000
--- a/httpcore-nio/src/site/resources/css/site.css
+++ /dev/null
@@ -1 +0,0 @@
- at import url("../../../css/hc-maven.css");
\ No newline at end of file
diff --git a/httpcore-nio/src/site/site.xml b/httpcore-nio/src/site/site.xml
deleted file mode 100644
index a1b8da0..0000000
--- a/httpcore-nio/src/site/site.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="ISO-8859-1"?>
-<!--
-   ====================================================================
-   Licensed to the Apache Software Foundation (ASF) under one
-   or more contributor license agreements.  See the NOTICE file
-   distributed with this work for additional information
-   regarding copyright ownership.  The ASF licenses this file
-   to you 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.
-   ====================================================================
-
-   This software consists of voluntary contributions made by many
-   individuals on behalf of the Apache Software Foundation.  For more
-   information on the Apache Software Foundation, please see
-   <http://www.apache.org/>.
- -->
-
-<project name="HttpCore">
-
-  <body>
-    <menu name="HttpCore Overview">
-      <item name="Description" href="../index.html"/>
-      <item name="Examples" href="../examples.html"/>
-    </menu>
-    <menu name="Modules">
-      <item name="HttpCore" href="../httpcore/index.html"/>
-      <item name="HttpCore NIO" href="index.html"/>
-    </menu>
-  </body>
-</project>
diff --git a/httpcore-nio/src/test/java/org/apache/http/nio/util/ContentDecoderMock.java b/httpcore-nio/src/test/java/org/apache/http/ByteChannelMock.java
similarity index 59%
copy from httpcore-nio/src/test/java/org/apache/http/nio/util/ContentDecoderMock.java
copy to httpcore-nio/src/test/java/org/apache/http/ByteChannelMock.java
index e0400f2..50ef788 100644
--- a/httpcore-nio/src/test/java/org/apache/http/nio/util/ContentDecoderMock.java
+++ b/httpcore-nio/src/test/java/org/apache/http/ByteChannelMock.java
@@ -25,40 +25,45 @@
  *
  */
 
-package org.apache.http.nio.util;
+package org.apache.http;
 
 import java.io.IOException;
 import java.nio.ByteBuffer;
-import java.nio.channels.ReadableByteChannel;
+import java.nio.channels.ByteChannel;
 
-import org.apache.http.nio.ContentDecoder;
+public class ByteChannelMock implements ByteChannel {
 
-public class ContentDecoderMock implements ContentDecoder {
+    private final ReadableByteChannelMock readableChannel;
+    private final WritableByteChannelMock writableChannel;
+    private boolean closed;
 
-    private final ReadableByteChannel channel;
-    private boolean completed;
-
-    public ContentDecoderMock(final ReadableByteChannel channel) {
+    public ByteChannelMock(
+        final ReadableByteChannelMock readableChannel,
+        final WritableByteChannelMock writableChannel) {
         super();
-        this.channel = channel;
+        this.readableChannel = readableChannel;
+        this.writableChannel = writableChannel;
     }
 
     public int read(final ByteBuffer dst) throws IOException {
-        if (dst == null) {
-            throw new IllegalArgumentException("Byte buffer may not be null");
-        }
-        if (this.completed) {
-            return -1;
-        }
-        int bytesRead = this.channel.read(dst);
-        if (bytesRead == -1) {
-            this.completed = true;
-        }
-        return bytesRead;
+        return this.readableChannel.read(dst);
     }
 
-    public boolean isCompleted() {
-        return this.completed;
+    public int write(final ByteBuffer src) throws IOException {
+        return this.writableChannel.write(src);
+    }
+
+    public boolean isOpen() {
+        return !this.closed;
+    }
+
+    public void close() throws IOException {
+        if (this.closed) {
+            return;
+        }
+        this.closed = true;
+        this.readableChannel.close();
+        this.writableChannel.close();
     }
 
 }
diff --git a/httpcore-nio/src/test/java/org/apache/http/HttpCoreNIOTestBase.java b/httpcore-nio/src/test/java/org/apache/http/HttpCoreNIOTestBase.java
deleted file mode 100644
index 3605c94..0000000
--- a/httpcore-nio/src/test/java/org/apache/http/HttpCoreNIOTestBase.java
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- * ====================================================================
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- *
- */
-
-package org.apache.http;
-
-import org.apache.http.impl.DefaultConnectionReuseStrategy;
-import org.apache.http.impl.nio.DefaultNHttpClientConnection;
-import org.apache.http.impl.nio.DefaultNHttpServerConnection;
-import org.apache.http.impl.nio.pool.BasicNIOConnFactory;
-import org.apache.http.impl.nio.pool.BasicNIOConnPool;
-import org.apache.http.nio.NHttpConnectionFactory;
-import org.apache.http.nio.protocol.HttpAsyncRequester;
-import org.apache.http.params.CoreConnectionPNames;
-import org.apache.http.params.CoreProtocolPNames;
-import org.apache.http.params.HttpParams;
-import org.apache.http.params.SyncBasicHttpParams;
-import org.apache.http.protocol.HttpProcessor;
-import org.apache.http.protocol.ImmutableHttpProcessor;
-import org.apache.http.protocol.RequestConnControl;
-import org.apache.http.protocol.RequestContent;
-import org.apache.http.protocol.RequestExpectContinue;
-import org.apache.http.protocol.RequestTargetHost;
-import org.apache.http.protocol.RequestUserAgent;
-import org.apache.http.protocol.ResponseConnControl;
-import org.apache.http.protocol.ResponseContent;
-import org.apache.http.protocol.ResponseDate;
-import org.apache.http.protocol.ResponseServer;
-import org.apache.http.testserver.HttpClientNio;
-import org.apache.http.testserver.HttpServerNio;
-import org.junit.After;
-
-/**
- * Base class for all HttpCore NIO tests
- */
-public abstract class HttpCoreNIOTestBase {
-
-    protected HttpParams serverParams;
-    protected HttpParams clientParams;
-    protected HttpServerNio server;
-    protected HttpClientNio client;
-    protected HttpProcessor serverHttpProc;
-    protected HttpProcessor clientHttpProc;
-    protected BasicNIOConnPool connpool;
-    protected HttpAsyncRequester executor;
-
-    protected abstract NHttpConnectionFactory<DefaultNHttpServerConnection> createServerConnectionFactory(
-            HttpParams params) throws Exception;
-
-    protected abstract NHttpConnectionFactory<DefaultNHttpClientConnection> createClientConnectionFactory(
-            HttpParams params) throws Exception;
-
-    protected NHttpConnectionFactory<DefaultNHttpClientConnection> createClientSSLConnectionFactory(
-            HttpParams params) throws Exception {
-        return null;
-    }
-
-    public void initServer() throws Exception {
-        this.serverParams = new SyncBasicHttpParams();
-        this.serverParams
-            .setIntParameter(CoreConnectionPNames.SO_TIMEOUT, 60000)
-            .setIntParameter(CoreConnectionPNames.SOCKET_BUFFER_SIZE, 8 * 1024)
-            .setBooleanParameter(CoreConnectionPNames.STALE_CONNECTION_CHECK, false)
-            .setBooleanParameter(CoreConnectionPNames.TCP_NODELAY, true)
-            .setParameter(CoreProtocolPNames.ORIGIN_SERVER, "TEST-SERVER/1.1");
-        this.server = new HttpServerNio(createServerConnectionFactory(this.serverParams));
-        this.server.setExceptionHandler(new SimpleIOReactorExceptionHandler());
-        this.serverHttpProc = new ImmutableHttpProcessor(new HttpResponseInterceptor[] {
-                new ResponseDate(),
-                new ResponseServer(),
-                new ResponseContent(),
-                new ResponseConnControl()
-        });
-    }
-
-    public void initClient() throws Exception {
-        this.clientParams = new SyncBasicHttpParams();
-        this.clientParams
-            .setIntParameter(CoreConnectionPNames.SO_TIMEOUT, 60000)
-            .setIntParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 60000)
-            .setIntParameter(CoreConnectionPNames.SOCKET_BUFFER_SIZE, 8 * 1024)
-            .setBooleanParameter(CoreConnectionPNames.STALE_CONNECTION_CHECK, false)
-            .setBooleanParameter(CoreConnectionPNames.TCP_NODELAY, true)
-            .setParameter(CoreProtocolPNames.USER_AGENT, "TEST-CLIENT/1.1");
-
-        this.client = new HttpClientNio(createClientConnectionFactory(this.clientParams));
-        this.client.setExceptionHandler(new SimpleIOReactorExceptionHandler());
-        this.clientHttpProc = new ImmutableHttpProcessor(new HttpRequestInterceptor[] {
-                new RequestContent(),
-                new RequestTargetHost(),
-                new RequestConnControl(),
-                new RequestUserAgent(),
-                new RequestExpectContinue()});
-    }
-
-    public void initConnPool() throws Exception {
-        this.connpool = new BasicNIOConnPool(
-                this.client.getIoReactor(),
-                new BasicNIOConnFactory(createClientConnectionFactory(this.clientParams),
-                        createClientSSLConnectionFactory(this.clientParams)),
-                this.clientParams);
-        this.executor = new HttpAsyncRequester(
-                this.clientHttpProc,
-                new DefaultConnectionReuseStrategy(),
-                this.clientParams);
-    }
-
-    @After
-    public void shutDownConnPool() throws Exception {
-        if (this.connpool != null) {
-            this.connpool.shutdown(2000);
-            this.connpool = null;
-        }
-    }
-
-    @After
-    public void shutDownClient() throws Exception {
-        if (this.client != null) {
-            this.client.shutdown();
-            this.client = null;
-        }
-    }
-
-    @After
-    public void shutDownServer() throws Exception {
-        if (this.server != null) {
-            this.server.shutdown();
-            this.server = null;
-        }
-    }
-
-}
diff --git a/httpcore-nio/src/test/java/org/apache/http/LoggingClientConnectionFactory.java b/httpcore-nio/src/test/java/org/apache/http/LoggingClientConnectionFactory.java
deleted file mode 100644
index 26ab6af..0000000
--- a/httpcore-nio/src/test/java/org/apache/http/LoggingClientConnectionFactory.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * ====================================================================
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- *
- */
-package org.apache.http;
-
-import org.apache.http.impl.DefaultHttpResponseFactory;
-import org.apache.http.impl.nio.DefaultNHttpClientConnection;
-import org.apache.http.impl.nio.DefaultNHttpClientConnectionFactory;
-import org.apache.http.nio.reactor.IOSession;
-import org.apache.http.nio.util.ByteBufferAllocator;
-import org.apache.http.nio.util.HeapByteBufferAllocator;
-import org.apache.http.params.HttpParams;
-
-public class LoggingClientConnectionFactory extends DefaultNHttpClientConnectionFactory {
-
-    public LoggingClientConnectionFactory(final HttpParams params) {
-        super(new DefaultHttpResponseFactory(), new HeapByteBufferAllocator(), params);
-    }
-
-    @Override
-    protected DefaultNHttpClientConnection createConnection(
-            final IOSession session,
-            final HttpResponseFactory responseFactory,
-            final ByteBufferAllocator allocator,
-            final HttpParams params) {
-        return new LoggingNHttpClientConnection(session, responseFactory, allocator, params);
-    }
-
-}
diff --git a/httpcore-nio/src/test/java/org/apache/http/LoggingServerConnectionFactory.java b/httpcore-nio/src/test/java/org/apache/http/LoggingServerConnectionFactory.java
deleted file mode 100644
index 8f4b10b..0000000
--- a/httpcore-nio/src/test/java/org/apache/http/LoggingServerConnectionFactory.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * ====================================================================
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- *
- */
-package org.apache.http;
-
-import org.apache.http.impl.DefaultHttpRequestFactory;
-import org.apache.http.impl.nio.DefaultNHttpServerConnection;
-import org.apache.http.impl.nio.DefaultNHttpServerConnectionFactory;
-import org.apache.http.nio.reactor.IOSession;
-import org.apache.http.nio.util.ByteBufferAllocator;
-import org.apache.http.nio.util.HeapByteBufferAllocator;
-import org.apache.http.params.HttpParams;
-
-public class LoggingServerConnectionFactory extends DefaultNHttpServerConnectionFactory {
-
-    public LoggingServerConnectionFactory(final HttpParams params) {
-        super(new DefaultHttpRequestFactory(), new HeapByteBufferAllocator(), params);
-    }
-
-    @Override
-    protected DefaultNHttpServerConnection createConnection(
-            final IOSession session,
-            final HttpRequestFactory requestFactory,
-            final ByteBufferAllocator allocator,
-            final HttpParams params) {
-        return new LoggingNHttpServerConnection(session, requestFactory, allocator, params);
-    }
-
-}
diff --git a/httpcore-nio/src/test/java/org/apache/http/ReadableByteChannelMock.java b/httpcore-nio/src/test/java/org/apache/http/ReadableByteChannelMock.java
index 19315d9..75a689a 100644
--- a/httpcore-nio/src/test/java/org/apache/http/ReadableByteChannelMock.java
+++ b/httpcore-nio/src/test/java/org/apache/http/ReadableByteChannelMock.java
@@ -29,21 +29,24 @@ package org.apache.http;
 
 import java.io.IOException;
 import java.nio.ByteBuffer;
+import java.nio.channels.ClosedChannelException;
 import java.nio.channels.ReadableByteChannel;
+import java.nio.charset.Charset;
 
 import org.apache.http.util.EncodingUtils;
 
 public class ReadableByteChannelMock implements ReadableByteChannel {
 
     private final String[] chunks;
-    private final String charset;
+    private final Charset charset;
 
     private int chunkCount = 0;
 
     private ByteBuffer currentChunk;
+    private boolean eof = false;
     private boolean closed = false;
 
-    public ReadableByteChannelMock(final String[] chunks, final String charset) {
+    public ReadableByteChannelMock(final String[] chunks, final Charset charset) {
         super();
         this.chunks = chunks;
         this.charset = charset;
@@ -52,18 +55,21 @@ public class ReadableByteChannelMock implements ReadableByteChannel {
     private void prepareChunk() {
         if (this.currentChunk == null || !this.currentChunk.hasRemaining()) {
             if (this.chunkCount < this.chunks.length) {
-                String s = this.chunks[this.chunkCount];
+                final String s = this.chunks[this.chunkCount];
                 this.chunkCount++;
-                this.currentChunk = ByteBuffer.wrap(EncodingUtils.getBytes(s, this.charset));
+                this.currentChunk = ByteBuffer.wrap(EncodingUtils.getBytes(s, this.charset.name()));
             } else {
-                this.closed = true;
+                this.eof = true;
             }
         }
     }
 
     public int read(final ByteBuffer dst) throws IOException {
-        prepareChunk();
         if (this.closed) {
+            throw new ClosedChannelException();
+        }
+        prepareChunk();
+        if (this.eof) {
             return -1;
         }
         int i = 0;
@@ -79,8 +85,7 @@ public class ReadableByteChannelMock implements ReadableByteChannel {
     }
 
     public boolean isOpen() {
-        return !this.closed;
+        return !this.closed && !this.eof;
     }
 
-
 }
diff --git a/httpcore-nio/src/test/java/org/apache/http/WritableByteChannelMock.java b/httpcore-nio/src/test/java/org/apache/http/WritableByteChannelMock.java
new file mode 100644
index 0000000..9daebd7
--- /dev/null
+++ b/httpcore-nio/src/test/java/org/apache/http/WritableByteChannelMock.java
@@ -0,0 +1,158 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+
+package org.apache.http;
+
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.nio.ByteBuffer;
+import java.nio.channels.ClosedChannelException;
+import java.nio.channels.WritableByteChannel;
+import java.nio.charset.Charset;
+
+import org.apache.http.nio.util.ExpandableBuffer;
+import org.apache.http.nio.util.HeapByteBufferAllocator;
+
+public class WritableByteChannelMock implements WritableByteChannel {
+
+    static class InternalBuffer extends ExpandableBuffer {
+
+        private final int capacityLimit;
+        private int curCapacity;
+
+        public InternalBuffer(final int buffersize, final int capacityLimit) {
+            super(buffersize, HeapByteBufferAllocator.INSTANCE);
+            this.capacityLimit = capacityLimit;
+            this.curCapacity = capacityLimit;
+        }
+
+        public int write(final ByteBuffer src) {
+            if (src == null) {
+                return 0;
+            }
+            setInputMode();
+            if (this.capacityLimit > 0) {
+                if (this.curCapacity > 0) {
+                    final int requiredCapacity = this.buffer.position() + this.curCapacity;
+                    ensureCapacity(requiredCapacity);
+                    int count = 0;
+                    while (src.hasRemaining() && this.curCapacity > 0) {
+                        this.buffer.put(src.get());
+                        count++;
+                        this.curCapacity--;
+                    }
+                    return count;
+                } else {
+                    return 0;
+                }
+            } else {
+                final int chunk = src.remaining();
+                final int requiredCapacity = this.buffer.position() + src.remaining();
+                ensureCapacity(requiredCapacity);
+                this.buffer.put(src);
+                return chunk;
+            }
+        }
+
+        @Override
+        protected void clear() {
+            super.clear();
+        }
+
+        public void resetCapacity() {
+            this.curCapacity = this.capacityLimit;
+        }
+
+        private static String toString(
+            final byte[] b, final int off, final int len, final Charset charset) {
+            try {
+                return new String(b, off, len, charset.name());
+            } catch (final UnsupportedEncodingException e) {
+                return new String(b, off, len);
+            }
+        }
+
+        public String dump(final Charset charset) {
+            setOutputMode();
+            if (this.buffer.hasArray()) {
+                return toString(this.buffer.array(), this.buffer.position(), this.buffer.limit(),
+                    charset);
+            } else {
+                final ByteBuffer dup = this.buffer.duplicate();
+                final byte[] b = new byte[dup.remaining()];
+                int i = 0;
+                while (dup.hasRemaining()) {
+                    b[i] = dup.get();
+                    i++;
+                }
+                return toString(b, 0, b.length, charset);
+            }
+        }
+
+    }
+
+    private final InternalBuffer buf;
+    private boolean closed;
+
+    public WritableByteChannelMock(final int size, final int capacityLimit) {
+        super();
+        this.buf = new InternalBuffer(size, capacityLimit);
+    }
+
+    public WritableByteChannelMock(final int size) {
+        this(size, 0);
+    }
+
+    public int write(final ByteBuffer src) throws IOException {
+        if (this.closed) {
+            throw new ClosedChannelException();
+        }
+        return this.buf.write(src);
+    }
+
+    public boolean isOpen() {
+        return !this.closed;
+    }
+
+    public void close() throws IOException {
+        this.closed = true;
+    }
+
+    public void flush() {
+        this.buf.resetCapacity();
+    }
+
+    public void reset() {
+        this.buf.resetCapacity();
+        this.buf.clear();
+    }
+
+    public String dump(final Charset charset){
+        return this.buf.dump(charset);
+    }
+
+}
diff --git a/httpcore-nio/src/test/java/org/apache/http/impl/nio/TestContentChannel.java b/httpcore-nio/src/test/java/org/apache/http/impl/nio/TestContentChannel.java
index 7f71004..3ffdb8c 100644
--- a/httpcore-nio/src/test/java/org/apache/http/impl/nio/TestContentChannel.java
+++ b/httpcore-nio/src/test/java/org/apache/http/impl/nio/TestContentChannel.java
@@ -26,9 +26,9 @@
  */
 package org.apache.http.impl.nio;
 
+import static org.junit.Assert.assertTrue;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
-import static org.junit.Assert.*;
 
 import java.nio.ByteBuffer;
 
@@ -59,7 +59,7 @@ public class TestContentChannel {
 
     @Test
     public void testContentDecoder() throws Exception {
-        ContentDecoderChannel cdc = new ContentDecoderChannel(decoder);
+        final ContentDecoderChannel cdc = new ContentDecoderChannel(decoder);
 
         cdc.read(bb);
         verify(decoder, times(1)).read(bb);
@@ -71,7 +71,7 @@ public class TestContentChannel {
 
     @Test
     public void testContentEncoder() throws Exception {
-        ContentEncoderChannel cec = new ContentEncoderChannel(encoder);
+        final ContentEncoderChannel cec = new ContentEncoderChannel(encoder);
 
         cec.write(bb);
         verify(encoder, times(1)).write(bb);
diff --git a/httpcore-nio/src/test/java/org/apache/http/impl/nio/TestDefaultNHttpClientConnection.java b/httpcore-nio/src/test/java/org/apache/http/impl/nio/TestDefaultNHttpClientConnection.java
new file mode 100644
index 0000000..7857b6d
--- /dev/null
+++ b/httpcore-nio/src/test/java/org/apache/http/impl/nio/TestDefaultNHttpClientConnection.java
@@ -0,0 +1,670 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+package org.apache.http.impl.nio;
+
+import java.nio.ByteBuffer;
+import java.nio.channels.ByteChannel;
+import java.nio.channels.SelectionKey;
+import java.util.LinkedList;
+
+import org.apache.http.ByteChannelMock;
+import org.apache.http.Consts;
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpRequest;
+import org.apache.http.HttpResponse;
+import org.apache.http.HttpVersion;
+import org.apache.http.ReadableByteChannelMock;
+import org.apache.http.WritableByteChannelMock;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.nio.codecs.LengthDelimitedDecoder;
+import org.apache.http.message.BasicHttpEntityEnclosingRequest;
+import org.apache.http.message.BasicHttpRequest;
+import org.apache.http.nio.ContentDecoder;
+import org.apache.http.nio.ContentEncoder;
+import org.apache.http.nio.IOControl;
+import org.apache.http.nio.NHttpClientConnection;
+import org.apache.http.nio.NHttpClientEventHandler;
+import org.apache.http.nio.NHttpConnection;
+import org.apache.http.nio.entity.HttpAsyncContentProducer;
+import org.apache.http.nio.entity.NStringEntity;
+import org.apache.http.nio.reactor.IOSession;
+import org.apache.http.nio.util.SimpleInputBuffer;
+import org.apache.http.protocol.HTTP;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Matchers;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+
+public class TestDefaultNHttpClientConnection {
+
+    @Mock
+    private IOSession session;
+    @Mock
+    private ByteChannel channel;
+    @Mock
+    private NHttpClientEventHandler handler;
+
+    private DefaultNHttpClientConnection conn;
+
+    @Before
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+        conn = new DefaultNHttpClientConnection(session, 32);
+    }
+
+    @Test
+    public void testSubmitRequest() throws Exception {
+        final BasicHttpRequest request = new BasicHttpRequest("GET", "/");
+        conn.submitRequest(request);
+
+        Assert.assertNull(conn.getHttpRequest());
+        Assert.assertTrue(conn.hasBufferedOutput());
+
+        Mockito.verify(session).setEvent(SelectionKey.OP_WRITE);
+    }
+
+    @Test
+    public void testSubmitEntityEnclosingRequest() throws Exception {
+        final BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/");
+        request.setEntity(new StringEntity("stuff"));
+
+        Mockito.when(session.channel()).thenReturn(channel);
+
+        Assert.assertEquals(0, conn.getMetrics().getRequestCount());
+        conn.submitRequest(request);
+
+        Assert.assertSame(request, conn.getHttpRequest());
+        Assert.assertTrue(conn.hasBufferedOutput());
+        Assert.assertTrue(conn.isRequestSubmitted());
+        Assert.assertNotNull(conn.contentEncoder);
+        Assert.assertEquals(1, conn.getMetrics().getRequestCount());
+
+        Mockito.verify(session).setEvent(SelectionKey.OP_WRITE);
+    }
+
+    @Test
+    public void testOutputReset() throws Exception {
+        final BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/");
+        request.setEntity(new StringEntity("stuff"));
+
+        Mockito.when(session.channel()).thenReturn(channel);
+
+        conn.submitRequest(request);
+
+        Assert.assertNotNull(conn.getHttpRequest());
+        Assert.assertNotNull(conn.contentEncoder);
+
+        conn.resetOutput();
+
+        Assert.assertNull(conn.getHttpRequest());
+        Assert.assertNull(conn.contentEncoder);
+    }
+
+    static class RequestReadyAnswer implements Answer<Void> {
+
+        private final HttpRequest request;
+
+        RequestReadyAnswer(final HttpRequest request) {
+            super();
+            this.request = request;
+        }
+
+        public Void answer(final InvocationOnMock invocation) throws Throwable {
+            final Object[] args = invocation.getArguments();
+            final NHttpClientConnection conn = (NHttpClientConnection) args[0];
+            conn.submitRequest(request);
+            return null;
+        }
+    }
+
+    static class ProduceContentAnswer implements Answer<Void> {
+
+        private final HttpAsyncContentProducer contentProducer;
+
+        ProduceContentAnswer(final HttpAsyncContentProducer contentProducer) {
+            super();
+            this.contentProducer = contentProducer;
+        }
+
+        public Void answer(final InvocationOnMock invocation) throws Throwable {
+            final Object[] args = invocation.getArguments();
+            final IOControl ioctrl = (IOControl) args[0];
+            final ContentEncoder encoder = (ContentEncoder) args[1];
+            contentProducer.produceContent(encoder, ioctrl);
+            return null;
+        }
+    }
+
+    @Test
+    public void testProduceOutputShortMessageAfterSubmit() throws Exception {
+        final BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/");
+        final NStringEntity entity = new NStringEntity("stuff");
+        request.setEntity(entity);
+
+        final WritableByteChannelMock wchannel = Mockito.spy(new WritableByteChannelMock(64));
+        final ByteChannelMock channel = new ByteChannelMock(null, wchannel);
+        Mockito.when(session.channel()).thenReturn(channel);
+
+        conn.submitRequest(request);
+        Assert.assertEquals(19, conn.outbuf.length());
+
+        Mockito.doAnswer(new ProduceContentAnswer(entity)).when(
+            handler).outputReady(Mockito.<NHttpClientConnection>any(), Mockito.<ContentEncoder>any());
+
+        conn.produceOutput(handler);
+
+        Assert.assertNull(conn.getHttpRequest());
+        Assert.assertNull(conn.contentEncoder);
+        Assert.assertEquals("POST / HTTP/1.1\r\n\r\nstuff", wchannel.dump(Consts.ASCII));
+
+        Mockito.verify(session, Mockito.times(1)).clearEvent(SelectionKey.OP_WRITE);
+        Mockito.verify(wchannel, Mockito.times(1)).write(Matchers.<ByteBuffer>any());
+    }
+
+    @Test
+    public void testProduceOutputLongMessageAfterSubmit() throws Exception {
+        final BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/");
+        final NStringEntity entity = new NStringEntity("a lot of various stuff");
+        request.setEntity(entity);
+
+        final WritableByteChannelMock wchannel = Mockito.spy(new WritableByteChannelMock(64));
+        final ByteChannelMock channel = new ByteChannelMock(null, wchannel);
+        Mockito.when(session.channel()).thenReturn(channel);
+
+        conn.submitRequest(request);
+        Assert.assertEquals(19, conn.outbuf.length());
+
+        Mockito.doAnswer(new ProduceContentAnswer(entity)).when(
+            handler).outputReady(Mockito.<NHttpClientConnection>any(), Mockito.<ContentEncoder>any());
+
+        conn.produceOutput(handler);
+
+        Assert.assertNull(conn.getHttpRequest());
+        Assert.assertNull(conn.contentEncoder);
+        Assert.assertEquals("POST / HTTP/1.1\r\n\r\na lot of various stuff", wchannel.dump(Consts.ASCII));
+
+        Mockito.verify(session, Mockito.times(1)).clearEvent(SelectionKey.OP_WRITE);
+        Mockito.verify(wchannel, Mockito.times(2)).write(Matchers.<ByteBuffer>any());
+    }
+
+    @Test
+    public void testProduceOutputShortMessage() throws Exception {
+        final BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/");
+        final NStringEntity entity = new NStringEntity("stuff");
+        request.setEntity(entity);
+
+        final WritableByteChannelMock wchannel = Mockito.spy(new WritableByteChannelMock(64));
+        final ByteChannelMock channel = new ByteChannelMock(null, wchannel);
+        Mockito.when(session.channel()).thenReturn(channel);
+
+        Mockito.doAnswer(new RequestReadyAnswer(request)).when(
+            handler).requestReady(Mockito.<NHttpClientConnection>any());
+
+        Mockito.doAnswer(new ProduceContentAnswer(entity)).when(
+            handler).outputReady(Mockito.<NHttpClientConnection>any(), Mockito.<ContentEncoder>any());
+
+        conn.produceOutput(handler);
+
+        Assert.assertNull(conn.getHttpRequest());
+        Assert.assertNull(conn.contentEncoder);
+        Assert.assertEquals("POST / HTTP/1.1\r\n\r\nstuff", wchannel.dump(Consts.ASCII));
+
+        Mockito.verify(session, Mockito.times(1)).clearEvent(SelectionKey.OP_WRITE);
+        Mockito.verify(wchannel, Mockito.times(1)).write(Matchers.<ByteBuffer>any());
+    }
+
+    @Test
+    public void testProduceOutputLongMessage() throws Exception {
+        final BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/");
+        final NStringEntity entity = new NStringEntity("a lot of various stuff");
+        request.setEntity(entity);
+
+        final WritableByteChannelMock wchannel = Mockito.spy(new WritableByteChannelMock(64));
+        final ByteChannelMock channel = new ByteChannelMock(null, wchannel);
+        Mockito.when(session.channel()).thenReturn(channel);
+
+        Mockito.doAnswer(new RequestReadyAnswer(request)).when(
+            handler).requestReady(Mockito.<NHttpClientConnection>any());
+
+        Mockito.doAnswer(new ProduceContentAnswer(entity)).when(
+            handler).outputReady(Mockito.<NHttpClientConnection>any(), Mockito.<ContentEncoder>any());
+
+        conn.produceOutput(handler);
+
+        Assert.assertNull(conn.getHttpRequest());
+        Assert.assertNull(conn.contentEncoder);
+        Assert.assertEquals("POST / HTTP/1.1\r\n\r\na lot of various stuff", wchannel.dump(Consts.ASCII));
+
+        Mockito.verify(session, Mockito.times(1)).clearEvent(SelectionKey.OP_WRITE);
+        Mockito.verify(wchannel, Mockito.times(2)).write(Matchers.<ByteBuffer>any());
+    }
+
+    @Test
+    public void testProduceOutputLongMessageSaturatedChannel() throws Exception {
+        final BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/");
+        final NStringEntity entity = new NStringEntity("a lot of various stuff");
+        request.setEntity(entity);
+
+        final WritableByteChannelMock wchannel = Mockito.spy(new WritableByteChannelMock(64, 24));
+        final ByteChannelMock channel = new ByteChannelMock(null, wchannel);
+        Mockito.when(session.channel()).thenReturn(channel);
+
+        Mockito.doAnswer(new RequestReadyAnswer(request)).when(
+            handler).requestReady(Mockito.<NHttpClientConnection>any());
+
+        Mockito.doAnswer(new ProduceContentAnswer(entity)).when(
+            handler).outputReady(Mockito.<NHttpClientConnection>any(), Mockito.<ContentEncoder>any());
+
+        conn.produceOutput(handler);
+
+        Assert.assertNull(conn.getHttpRequest());
+        Assert.assertNull(conn.contentEncoder);
+        Assert.assertEquals("POST / HTTP/1.1\r\n\r\na lot", wchannel.dump(Consts.ASCII));
+        Assert.assertEquals(17, conn.outbuf.length());
+
+        Mockito.verify(session, Mockito.never()).clearEvent(SelectionKey.OP_WRITE);
+        Mockito.verify(wchannel, Mockito.times(2)).write(Matchers.<ByteBuffer>any());
+    }
+
+    @Test
+    public void testProduceOutputLongMessageSaturatedChannel2() throws Exception {
+        conn = new DefaultNHttpClientConnection(session, 24);
+        final BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/");
+        final NStringEntity entity = new NStringEntity("a loooooooooooooooooooooooot of various stuff");
+        request.setEntity(entity);
+
+        final WritableByteChannelMock wchannel = Mockito.spy(new WritableByteChannelMock(64, 24));
+        final ByteChannelMock channel = new ByteChannelMock(null, wchannel);
+        Mockito.when(session.channel()).thenReturn(channel);
+
+        Mockito.doAnswer(new RequestReadyAnswer(request)).when(
+            handler).requestReady(Mockito.<NHttpClientConnection>any());
+
+        Mockito.doAnswer(new ProduceContentAnswer(entity)).when(
+            handler).outputReady(Mockito.<NHttpClientConnection>any(), Mockito.<ContentEncoder>any());
+
+        conn.produceOutput(handler);
+
+        Assert.assertNotNull(conn.getHttpRequest());
+        Assert.assertNotNull(conn.contentEncoder);
+        Assert.assertEquals("POST / HTTP/1.1\r\n\r\na loo", wchannel.dump(Consts.ASCII));
+
+        Mockito.verify(session, Mockito.never()).clearEvent(SelectionKey.OP_WRITE);
+        Mockito.verify(wchannel, Mockito.times(3)).write(Matchers.<ByteBuffer>any());
+    }
+
+    @Test
+    public void testProduceOutputLongChunkedMessage() throws Exception {
+        conn = new DefaultNHttpClientConnection(session, 64);
+
+        final BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/");
+        request.addHeader(HTTP.TRANSFER_ENCODING, HTTP.CHUNK_CODING);
+        final NStringEntity entity = new NStringEntity("a lot of various stuff");
+        entity.setChunked(true);
+        request.setEntity(entity);
+
+        final WritableByteChannelMock wchannel = Mockito.spy(new WritableByteChannelMock(64));
+        final ByteChannelMock channel = new ByteChannelMock(null, wchannel);
+        Mockito.when(session.channel()).thenReturn(channel);
+
+        Mockito.doAnswer(new RequestReadyAnswer(request)).when(
+            handler).requestReady(Mockito.<NHttpClientConnection>any());
+
+        Mockito.doAnswer(new ProduceContentAnswer(entity)).when(
+            handler).outputReady(Mockito.<NHttpClientConnection>any(), Mockito.<ContentEncoder>any());
+
+        conn.produceOutput(handler);
+
+        Assert.assertNull(conn.getHttpRequest());
+        Assert.assertNull(conn.contentEncoder);
+        Assert.assertEquals("POST / HTTP/1.1\r\nTransfer-Encoding: chunked\r\n\r\n" +
+                "5\r\na lot\r\n11\r\n of various stuff\r\n0\r\n\r\n", wchannel.dump(Consts.ASCII));
+
+        Mockito.verify(session, Mockito.times(1)).clearEvent(SelectionKey.OP_WRITE);
+        Mockito.verify(wchannel, Mockito.times(2)).write(Matchers.<ByteBuffer>any());
+    }
+
+    @Test
+    public void testProduceOutputLongChunkedMessageSaturatedChannel() throws Exception {
+        conn = new DefaultNHttpClientConnection(session, 64);
+
+        final BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/");
+        request.addHeader(HTTP.TRANSFER_ENCODING, HTTP.CHUNK_CODING);
+        final NStringEntity entity = new NStringEntity("a lot of various stuff");
+        entity.setChunked(true);
+        request.setEntity(entity);
+
+        final WritableByteChannelMock wchannel = Mockito.spy(new WritableByteChannelMock(64, 64));
+        final ByteChannelMock channel = new ByteChannelMock(null, wchannel);
+        Mockito.when(session.channel()).thenReturn(channel);
+
+        Mockito.doAnswer(new RequestReadyAnswer(request)).when(
+            handler).requestReady(Mockito.<NHttpClientConnection>any());
+
+        Mockito.doAnswer(new ProduceContentAnswer(entity)).when(
+            handler).outputReady(Mockito.<NHttpClientConnection>any(), Mockito.<ContentEncoder>any());
+
+        conn.produceOutput(handler);
+
+        Assert.assertNull(conn.getHttpRequest());
+        Assert.assertNull(conn.contentEncoder);
+        Assert.assertEquals("POST / HTTP/1.1\r\nTransfer-Encoding: chunked\r\n\r\n" +
+                "5\r\na lot\r\n11\r\n of", wchannel.dump(Consts.ASCII));
+        Assert.assertEquals(21, conn.outbuf.length());
+
+        Mockito.verify(session, Mockito.never()).clearEvent(SelectionKey.OP_WRITE);
+        Mockito.verify(wchannel, Mockito.times(2)).write(Matchers.<ByteBuffer>any());
+    }
+
+    @Test
+    public void testProduceOutputClosingConnection() throws Exception {
+        final BasicHttpRequest request = new BasicHttpRequest("GET", "/");
+
+        final WritableByteChannelMock wchannel = Mockito.spy(new WritableByteChannelMock(64));
+        final ByteChannelMock channel = new ByteChannelMock(null, wchannel);
+        Mockito.when(session.channel()).thenReturn(channel);
+
+        conn.submitRequest(request);
+        conn.close();
+
+        Assert.assertEquals(NHttpConnection.CLOSING, conn.getStatus());
+
+        conn.produceOutput(handler);
+
+        Assert.assertEquals(NHttpConnection.CLOSED, conn.getStatus());
+
+        Mockito.verify(wchannel, Mockito.times(1)).write(Matchers.<ByteBuffer>any());
+        Mockito.verify(session, Mockito.times(1)).close();
+        Mockito.verify(session, Mockito.never()).clearEvent(SelectionKey.OP_WRITE);
+        Mockito.verify(handler, Mockito.never()).requestReady(
+            Mockito.<NHttpClientConnection>any());
+        Mockito.verify(handler, Mockito.never()).outputReady(
+            Mockito.<NHttpClientConnection>any(), Mockito.<ContentEncoder>any());
+    }
+
+    static class ResponseCapturingAnswer implements Answer<Void> {
+
+        private final LinkedList<HttpResponse> responses;
+
+        ResponseCapturingAnswer(final LinkedList<HttpResponse> responses) {
+            super();
+            this.responses = responses;
+        }
+
+        public Void answer(final InvocationOnMock invocation) throws Throwable {
+            final Object[] args = invocation.getArguments();
+            final NHttpClientConnection conn = (NHttpClientConnection) args[0];
+            if (conn != null) {
+                final HttpResponse response = conn.getHttpResponse();
+                if (response != null) {
+                    responses.add(response);
+                }
+            }
+            return null;
+        }
+
+    }
+
+    static class ConsumeContentAnswer implements Answer<Void> {
+
+        private final SimpleInputBuffer buf;
+
+        ConsumeContentAnswer(final SimpleInputBuffer buf) {
+            super();
+            this.buf = buf;
+        }
+
+        public Void answer(final InvocationOnMock invocation) throws Throwable {
+            final Object[] args = invocation.getArguments();
+            final ContentDecoder decoder = (ContentDecoder) args[1];
+            buf.consumeContent(decoder);
+            return null;
+        }
+
+    }
+
+    @Test
+    public void testConsumeInputShortMessage() throws Exception {
+        final ReadableByteChannelMock rchannel = Mockito.spy(new ReadableByteChannelMock(
+            new String[] {"HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\nstuff"}, Consts.ASCII));
+        final ByteChannelMock channel = new ByteChannelMock(rchannel, null);
+        Mockito.when(session.channel()).thenReturn(channel);
+        Mockito.when(session.getEventMask()).thenReturn(SelectionKey.OP_READ);
+
+        final LinkedList<HttpResponse> responses = new LinkedList<HttpResponse>();
+
+        Mockito.doAnswer(new ResponseCapturingAnswer(responses)).when(
+            handler).responseReceived(Mockito.<NHttpClientConnection>any());
+        Mockito.doAnswer(new ConsumeContentAnswer(new SimpleInputBuffer(64))).when(
+            handler).inputReady(Mockito.<NHttpClientConnection>any(), Mockito.<ContentDecoder>any());
+
+        Assert.assertEquals(0, conn.getMetrics().getResponseCount());
+
+        conn.consumeInput(handler);
+
+        Assert.assertNull(conn.getHttpResponse());
+        Assert.assertNull(conn.contentDecoder);
+        Assert.assertEquals(1, conn.getMetrics().getResponseCount());
+        Assert.assertEquals(43, conn.getMetrics().getReceivedBytesCount());
+
+        Mockito.verify(handler, Mockito.times(1)).responseReceived(
+            Mockito.<NHttpClientConnection>any());
+        Mockito.verify(handler, Mockito.times(1)).inputReady(
+            Mockito.<NHttpClientConnection>any(), Mockito.<LengthDelimitedDecoder>any());
+        Mockito.verify(rchannel, Mockito.times(2)).read(Mockito.<ByteBuffer>any());
+        Mockito.verify(handler, Mockito.never()).exception(
+            Mockito.<NHttpClientConnection>any(), Mockito.<Exception>any());
+
+        Assert.assertFalse(responses.isEmpty());
+        final HttpResponse response = responses.getFirst();
+        Assert.assertNotNull(response);
+        Assert.assertEquals(HttpVersion.HTTP_1_1, response.getStatusLine().getProtocolVersion());
+        Assert.assertEquals(200, response.getStatusLine().getStatusCode());
+        Assert.assertEquals("OK", response.getStatusLine().getReasonPhrase());
+        final HttpEntity entity = response.getEntity();
+        Assert.assertNotNull(entity);
+        Assert.assertEquals(5, entity.getContentLength());
+    }
+
+    @Test
+    public void testConsumeInputLongMessage() throws Exception {
+        conn = new DefaultNHttpClientConnection(session, 1024);
+        final ReadableByteChannelMock rchannel = Mockito.spy(new ReadableByteChannelMock(
+            new String[] {"HTTP/1.1 200 OK\r\nContent-Length: 100\r\n\r\na lot of stuff",
+                "", ""}, Consts.ASCII));
+        final ByteChannelMock channel = new ByteChannelMock(rchannel, null);
+        Mockito.when(session.channel()).thenReturn(channel);
+        Mockito.when(session.getEventMask()).thenReturn(SelectionKey.OP_READ);
+
+        final LinkedList<HttpResponse> responses = new LinkedList<HttpResponse>();
+
+        Mockito.doAnswer(new ResponseCapturingAnswer(responses)).when(
+            handler).responseReceived(Mockito.<NHttpClientConnection>any());
+        Mockito.doAnswer(new ConsumeContentAnswer(new SimpleInputBuffer(64))).when(
+            handler).inputReady(Mockito.<NHttpClientConnection>any(), Mockito.<ContentDecoder>any());
+
+        Assert.assertEquals(0, conn.getMetrics().getResponseCount());
+
+        conn.consumeInput(handler);
+
+        Assert.assertNotNull(conn.getHttpResponse());
+        Assert.assertNotNull(conn.contentDecoder);
+        Assert.assertEquals(1, conn.getMetrics().getResponseCount());
+        Assert.assertEquals(54, conn.getMetrics().getReceivedBytesCount());
+
+        Mockito.verify(handler, Mockito.times(1)).responseReceived(
+            Mockito.<NHttpClientConnection>any());
+        Mockito.verify(handler, Mockito.times(1)).inputReady(
+            Mockito.<NHttpClientConnection>any(), Mockito.<LengthDelimitedDecoder>any());
+        Mockito.verify(rchannel, Mockito.times(2)).read(Mockito.<ByteBuffer>any());
+        Mockito.verify(handler, Mockito.never()).exception(
+            Mockito.<NHttpClientConnection>any(), Mockito.<Exception>any());
+
+        Assert.assertFalse(responses.isEmpty());
+        final HttpResponse response = responses.getFirst();
+        Assert.assertNotNull(response);
+        Assert.assertEquals(HttpVersion.HTTP_1_1, response.getStatusLine().getProtocolVersion());
+        Assert.assertEquals(200, response.getStatusLine().getStatusCode());
+        Assert.assertEquals("OK", response.getStatusLine().getReasonPhrase());
+        final HttpEntity entity = response.getEntity();
+        Assert.assertNotNull(entity);
+        Assert.assertEquals(100, entity.getContentLength());
+
+        conn.consumeInput(handler);
+
+        Assert.assertEquals(1, conn.getMetrics().getResponseCount());
+        Assert.assertEquals(54, conn.getMetrics().getReceivedBytesCount());
+
+        Mockito.verify(rchannel, Mockito.times(3)).read(Mockito.<ByteBuffer>any());
+        Mockito.verify(handler, Mockito.never()).exception(
+            Mockito.<NHttpClientConnection>any(), Mockito.<Exception>any());
+    }
+
+    @Test
+    public void testConsumeInputBasicMessageNoEntity() throws Exception {
+        final ReadableByteChannelMock rchannel = Mockito.spy(new ReadableByteChannelMock(
+            new String[] {"HTTP/1.1 100 Continue\r\n\r\n"}, Consts.ASCII));
+        final ByteChannelMock channel = new ByteChannelMock(rchannel, null);
+        Mockito.when(session.channel()).thenReturn(channel);
+        Mockito.when(session.getEventMask()).thenReturn(SelectionKey.OP_READ);
+
+        final LinkedList<HttpResponse> responses = new LinkedList<HttpResponse>();
+
+        Mockito.doAnswer(new ResponseCapturingAnswer(responses)).when(
+            handler).responseReceived(Mockito.<NHttpClientConnection>any());
+        Mockito.doAnswer(new ConsumeContentAnswer(new SimpleInputBuffer(64))).when(
+            handler).inputReady(Mockito.<NHttpClientConnection>any(), Mockito.<ContentDecoder>any());
+
+        conn.consumeInput(handler);
+
+        Assert.assertNull(conn.getHttpResponse());
+        Assert.assertNull(conn.contentDecoder);
+
+        Mockito.verify(handler, Mockito.times(1)).responseReceived(
+            Mockito.<NHttpClientConnection>any());
+        Mockito.verify(handler, Mockito.never()).inputReady(
+            Mockito.<NHttpClientConnection>any(), Mockito.<LengthDelimitedDecoder>any());
+        Mockito.verify(rchannel, Mockito.times(1)).read(Mockito.<ByteBuffer>any());
+        Mockito.verify(handler, Mockito.never()).exception(
+            Mockito.<NHttpClientConnection>any(), Mockito.<Exception>any());
+
+        Assert.assertFalse(responses.isEmpty());
+        final HttpResponse response = responses.getFirst();
+        Assert.assertNotNull(response);
+        Assert.assertEquals(HttpVersion.HTTP_1_1, response.getStatusLine().getProtocolVersion());
+        Assert.assertEquals(100, response.getStatusLine().getStatusCode());
+        final HttpEntity entity = response.getEntity();
+        Assert.assertNull(entity);
+    }
+
+    @Test
+    public void testConsumeInputNoData() throws Exception {
+        conn = new DefaultNHttpClientConnection(session, 1024);
+        final ReadableByteChannelMock rchannel = Mockito.spy(new ReadableByteChannelMock(
+            new String[] {"", ""}, Consts.ASCII));
+        final ByteChannelMock channel = new ByteChannelMock(rchannel, null);
+        Mockito.when(session.channel()).thenReturn(channel);
+        Mockito.when(session.getEventMask()).thenReturn(SelectionKey.OP_READ);
+
+        final LinkedList<HttpResponse> responses = new LinkedList<HttpResponse>();
+
+        Mockito.doAnswer(new ResponseCapturingAnswer(responses)).when(
+            handler).responseReceived(Mockito.<NHttpClientConnection>any());
+        Mockito.doAnswer(new ConsumeContentAnswer(new SimpleInputBuffer(64))).when(
+            handler).inputReady(Mockito.<NHttpClientConnection>any(), Mockito.<ContentDecoder>any());
+
+        Assert.assertEquals(0, conn.getMetrics().getResponseCount());
+
+        conn.consumeInput(handler);
+
+        Assert.assertNull(conn.getHttpResponse());
+        Assert.assertNull(conn.contentDecoder);
+        Assert.assertEquals(0, conn.getMetrics().getResponseCount());
+        Assert.assertEquals(0, conn.getMetrics().getReceivedBytesCount());
+
+        Mockito.verify(handler, Mockito.never()).responseReceived(
+            Mockito.<NHttpClientConnection>any());
+        Mockito.verify(handler, Mockito.never()).inputReady(
+            Mockito.<NHttpClientConnection>any(), Mockito.<LengthDelimitedDecoder>any());
+        Mockito.verify(rchannel, Mockito.times(1)).read(Mockito.<ByteBuffer>any());
+        Mockito.verify(handler, Mockito.never()).exception(
+            Mockito.<NHttpClientConnection>any(), Mockito.<Exception>any());
+
+        conn.consumeInput(handler);
+
+        Assert.assertNull(conn.getHttpResponse());
+        Assert.assertNull(conn.contentDecoder);
+        Assert.assertEquals(0, conn.getMetrics().getResponseCount());
+        Assert.assertEquals(0, conn.getMetrics().getReceivedBytesCount());
+
+        Mockito.verify(handler, Mockito.never()).responseReceived(
+            Mockito.<NHttpClientConnection>any());
+        Mockito.verify(handler, Mockito.never()).inputReady(
+            Mockito.<NHttpClientConnection>any(), Mockito.<LengthDelimitedDecoder>any());
+        Mockito.verify(rchannel, Mockito.times(2)).read(Mockito.<ByteBuffer>any());
+        Mockito.verify(handler, Mockito.never()).exception(
+            Mockito.<NHttpClientConnection>any(), Mockito.<Exception>any());
+
+        conn.consumeInput(handler);
+        Assert.assertNull(conn.getHttpResponse());
+        Assert.assertNull(conn.contentDecoder);
+        Assert.assertEquals(0, conn.getMetrics().getResponseCount());
+        Assert.assertEquals(0, conn.getMetrics().getReceivedBytesCount());
+
+        Mockito.verify(handler, Mockito.never()).responseReceived(
+            Mockito.<NHttpClientConnection>any());
+        Mockito.verify(handler, Mockito.never()).inputReady(
+            Mockito.<NHttpClientConnection>any(), Mockito.<LengthDelimitedDecoder>any());
+        Mockito.verify(rchannel, Mockito.times(3)).read(Mockito.<ByteBuffer>any());
+        Mockito.verify(handler, Mockito.times(1)).endOfInput(
+            Mockito.<NHttpClientConnection>any());
+        Mockito.verify(handler, Mockito.never()).exception(
+            Mockito.<NHttpClientConnection>any(), Mockito.<Exception>any());
+
+    }
+
+    @Test
+    public void testConsumeInputConnectionClosed() throws Exception {
+        conn = new DefaultNHttpClientConnection(session, 1024);
+        final ReadableByteChannelMock rchannel = Mockito.spy(new ReadableByteChannelMock(
+            new String[] {"", ""}, Consts.ASCII));
+        final ByteChannelMock channel = new ByteChannelMock(rchannel, null);
+        Mockito.when(session.channel()).thenReturn(channel);
+        Mockito.when(session.getEventMask()).thenReturn(SelectionKey.OP_READ);
+
+        conn.close();
+        conn.consumeInput(handler);
+        Mockito.verify(rchannel, Mockito.never()).read(Mockito.<ByteBuffer>any());
+        Mockito.verify(session, Mockito.times(1)).clearEvent(SelectionKey.OP_READ);
+    }
+
+}
diff --git a/httpcore-nio/src/test/java/org/apache/http/impl/nio/TestDefaultNHttpServerConnection.java b/httpcore-nio/src/test/java/org/apache/http/impl/nio/TestDefaultNHttpServerConnection.java
new file mode 100644
index 0000000..87c934d
--- /dev/null
+++ b/httpcore-nio/src/test/java/org/apache/http/impl/nio/TestDefaultNHttpServerConnection.java
@@ -0,0 +1,672 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+package org.apache.http.impl.nio;
+
+import java.nio.ByteBuffer;
+import java.nio.channels.ByteChannel;
+import java.nio.channels.SelectionKey;
+import java.util.LinkedList;
+
+import org.apache.http.ByteChannelMock;
+import org.apache.http.Consts;
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpEntityEnclosingRequest;
+import org.apache.http.HttpRequest;
+import org.apache.http.HttpResponse;
+import org.apache.http.HttpVersion;
+import org.apache.http.ReadableByteChannelMock;
+import org.apache.http.WritableByteChannelMock;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.nio.codecs.LengthDelimitedDecoder;
+import org.apache.http.message.BasicHttpResponse;
+import org.apache.http.nio.ContentDecoder;
+import org.apache.http.nio.ContentEncoder;
+import org.apache.http.nio.IOControl;
+import org.apache.http.nio.NHttpServerConnection;
+import org.apache.http.nio.NHttpConnection;
+import org.apache.http.nio.NHttpServerEventHandler;
+import org.apache.http.nio.entity.HttpAsyncContentProducer;
+import org.apache.http.nio.entity.NStringEntity;
+import org.apache.http.nio.reactor.IOSession;
+import org.apache.http.nio.util.SimpleInputBuffer;
+import org.apache.http.protocol.HTTP;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Matchers;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+
+public class TestDefaultNHttpServerConnection {
+
+    @Mock
+    private IOSession session;
+    @Mock
+    private ByteChannel channel;
+    @Mock
+    private NHttpServerEventHandler handler;
+
+    private DefaultNHttpServerConnection conn;
+
+    @Before
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+        conn = new DefaultNHttpServerConnection(session, 32);
+    }
+
+    @Test
+    public void testSubmitRequest() throws Exception {
+        final BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
+        conn.submitResponse(response);
+
+        Assert.assertNull(conn.getHttpResponse());
+        Assert.assertTrue(conn.hasBufferedOutput());
+
+        Mockito.verify(session).setEvent(SelectionKey.OP_WRITE);
+    }
+
+    @Test
+    public void testSubmitEntityEnclosingRequest() throws Exception {
+        final BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
+        response.setEntity(new StringEntity("stuff"));
+
+        Mockito.when(session.channel()).thenReturn(channel);
+
+        Assert.assertEquals(0, conn.getMetrics().getResponseCount());
+        conn.submitResponse(response);
+
+        Assert.assertSame(response, conn.getHttpResponse());
+        Assert.assertTrue(conn.hasBufferedOutput());
+        Assert.assertTrue(conn.isResponseSubmitted());
+        Assert.assertNotNull(conn.contentEncoder);
+        Assert.assertEquals(1, conn.getMetrics().getResponseCount());
+
+        Mockito.verify(session).setEvent(SelectionKey.OP_WRITE);
+    }
+
+    @Test
+    public void testOutputReset() throws Exception {
+        final BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
+        response.setEntity(new StringEntity("stuff"));
+
+        Mockito.when(session.channel()).thenReturn(channel);
+
+        conn.submitResponse(response);
+
+        Assert.assertNotNull(conn.getHttpResponse());
+        Assert.assertNotNull(conn.contentEncoder);
+
+        conn.resetOutput();
+
+        Assert.assertNull(conn.getHttpResponse());
+        Assert.assertNull(conn.contentEncoder);
+    }
+
+    static class ResponseReadyAnswer implements Answer<Void> {
+
+        private final HttpResponse response;
+
+        ResponseReadyAnswer(final HttpResponse response) {
+            super();
+            this.response = response;
+        }
+
+        public Void answer(final InvocationOnMock invocation) throws Throwable {
+            final Object[] args = invocation.getArguments();
+            final NHttpServerConnection conn = (NHttpServerConnection) args[0];
+            conn.submitResponse(response);
+            return null;
+        }
+    }
+
+    static class ProduceContentAnswer implements Answer<Void> {
+
+        private final HttpAsyncContentProducer contentProducer;
+
+        ProduceContentAnswer(final HttpAsyncContentProducer contentProducer) {
+            super();
+            this.contentProducer = contentProducer;
+        }
+
+        public Void answer(final InvocationOnMock invocation) throws Throwable {
+            final Object[] args = invocation.getArguments();
+            final IOControl ioctrl = (IOControl) args[0];
+            final ContentEncoder encoder = (ContentEncoder) args[1];
+            contentProducer.produceContent(encoder, ioctrl);
+            return null;
+        }
+    }
+
+    @Test
+    public void testProduceOutputShortMessageAfterSubmit() throws Exception {
+        final BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
+        final NStringEntity entity = new NStringEntity("stuff");
+        response.setEntity(entity);
+
+        final WritableByteChannelMock wchannel = Mockito.spy(new WritableByteChannelMock(64));
+        final ByteChannelMock channel = new ByteChannelMock(null, wchannel);
+        Mockito.when(session.channel()).thenReturn(channel);
+
+        conn.submitResponse(response);
+        Assert.assertEquals(19, conn.outbuf.length());
+
+        Mockito.doAnswer(new ProduceContentAnswer(entity)).when(
+            handler).outputReady(Mockito.<NHttpServerConnection>any(), Mockito.<ContentEncoder>any());
+
+        conn.produceOutput(handler);
+
+        Assert.assertNull(conn.getHttpResponse());
+        Assert.assertNull(conn.contentEncoder);
+        Assert.assertEquals("HTTP/1.1 200 OK\r\n\r\nstuff", wchannel.dump(Consts.ASCII));
+
+        Mockito.verify(session, Mockito.times(1)).clearEvent(SelectionKey.OP_WRITE);
+        Mockito.verify(wchannel, Mockito.times(1)).write(Matchers.<ByteBuffer>any());
+    }
+
+    @Test
+    public void testProduceOutputLongMessageAfterSubmit() throws Exception {
+        final BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
+        final NStringEntity entity = new NStringEntity("a lot of various stuff");
+        response.setEntity(entity);
+
+        final WritableByteChannelMock wchannel = Mockito.spy(new WritableByteChannelMock(64));
+        final ByteChannelMock channel = new ByteChannelMock(null, wchannel);
+        Mockito.when(session.channel()).thenReturn(channel);
+
+        conn.submitResponse(response);
+        Assert.assertEquals(19, conn.outbuf.length());
+
+        Mockito.doAnswer(new ProduceContentAnswer(entity)).when(
+            handler).outputReady(Mockito.<NHttpServerConnection>any(), Mockito.<ContentEncoder>any());
+
+        conn.produceOutput(handler);
+
+        Assert.assertNull(conn.getHttpResponse());
+        Assert.assertNull(conn.contentEncoder);
+        Assert.assertEquals("HTTP/1.1 200 OK\r\n\r\na lot of various stuff", wchannel.dump(Consts.ASCII));
+
+        Mockito.verify(session, Mockito.times(1)).clearEvent(SelectionKey.OP_WRITE);
+        Mockito.verify(wchannel, Mockito.times(2)).write(Matchers.<ByteBuffer>any());
+    }
+
+    @Test
+    public void testProduceOutputShortMessage() throws Exception {
+        final BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
+        final NStringEntity entity = new NStringEntity("stuff");
+        response.setEntity(entity);
+
+        final WritableByteChannelMock wchannel = Mockito.spy(new WritableByteChannelMock(64));
+        final ByteChannelMock channel = new ByteChannelMock(null, wchannel);
+        Mockito.when(session.channel()).thenReturn(channel);
+
+        Mockito.doAnswer(new ResponseReadyAnswer(response)).when(
+            handler).responseReady(Mockito.<NHttpServerConnection>any());
+
+        Mockito.doAnswer(new ProduceContentAnswer(entity)).when(
+            handler).outputReady(Mockito.<NHttpServerConnection>any(), Mockito.<ContentEncoder>any());
+
+        conn.produceOutput(handler);
+
+        Assert.assertNull(conn.getHttpResponse());
+        Assert.assertNull(conn.contentEncoder);
+        Assert.assertEquals("HTTP/1.1 200 OK\r\n\r\nstuff", wchannel.dump(Consts.ASCII));
+
+        Mockito.verify(session, Mockito.times(1)).clearEvent(SelectionKey.OP_WRITE);
+        Mockito.verify(wchannel, Mockito.times(1)).write(Matchers.<ByteBuffer>any());
+    }
+
+    @Test
+    public void testProduceOutputLongMessage() throws Exception {
+        final BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
+        final NStringEntity entity = new NStringEntity("a lot of various stuff");
+        response.setEntity(entity);
+
+        final WritableByteChannelMock wchannel = Mockito.spy(new WritableByteChannelMock(64));
+        final ByteChannelMock channel = new ByteChannelMock(null, wchannel);
+        Mockito.when(session.channel()).thenReturn(channel);
+
+        Mockito.doAnswer(new ResponseReadyAnswer(response)).when(
+            handler).responseReady(Mockito.<NHttpServerConnection>any());
+
+        Mockito.doAnswer(new ProduceContentAnswer(entity)).when(
+            handler).outputReady(Mockito.<NHttpServerConnection>any(), Mockito.<ContentEncoder>any());
+
+        conn.produceOutput(handler);
+
+        Assert.assertNull(conn.getHttpResponse());
+        Assert.assertNull(conn.contentEncoder);
+        Assert.assertEquals("HTTP/1.1 200 OK\r\n\r\na lot of various stuff", wchannel.dump(Consts.ASCII));
+
+        Mockito.verify(session, Mockito.times(1)).clearEvent(SelectionKey.OP_WRITE);
+        Mockito.verify(wchannel, Mockito.times(2)).write(Matchers.<ByteBuffer>any());
+    }
+
+    @Test
+    public void testProduceOutputLongMessageSaturatedChannel() throws Exception {
+        final BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
+        final NStringEntity entity = new NStringEntity("a lot of various stuff");
+        response.setEntity(entity);
+
+        final WritableByteChannelMock wchannel = Mockito.spy(new WritableByteChannelMock(64, 24));
+        final ByteChannelMock channel = new ByteChannelMock(null, wchannel);
+        Mockito.when(session.channel()).thenReturn(channel);
+
+        Mockito.doAnswer(new ResponseReadyAnswer(response)).when(
+            handler).responseReady(Mockito.<NHttpServerConnection>any());
+
+        Mockito.doAnswer(new ProduceContentAnswer(entity)).when(
+            handler).outputReady(Mockito.<NHttpServerConnection>any(), Mockito.<ContentEncoder>any());
+
+        conn.produceOutput(handler);
+
+        Assert.assertNull(conn.getHttpResponse());
+        Assert.assertNull(conn.contentEncoder);
+        Assert.assertEquals("HTTP/1.1 200 OK\r\n\r\na lot", wchannel.dump(Consts.ASCII));
+        Assert.assertEquals(17, conn.outbuf.length());
+
+        Mockito.verify(session, Mockito.never()).clearEvent(SelectionKey.OP_WRITE);
+        Mockito.verify(wchannel, Mockito.times(2)).write(Matchers.<ByteBuffer>any());
+    }
+
+    @Test
+    public void testProduceOutputLongMessageSaturatedChannel2() throws Exception {
+        conn = new DefaultNHttpServerConnection(session, 24);
+        final BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
+        final NStringEntity entity = new NStringEntity("a loooooooooooooooooooooooot of various stuff");
+        response.setEntity(entity);
+
+        final WritableByteChannelMock wchannel = Mockito.spy(new WritableByteChannelMock(64, 24));
+        final ByteChannelMock channel = new ByteChannelMock(null, wchannel);
+        Mockito.when(session.channel()).thenReturn(channel);
+
+        Mockito.doAnswer(new ResponseReadyAnswer(response)).when(
+            handler).responseReady(Mockito.<NHttpServerConnection>any());
+
+        Mockito.doAnswer(new ProduceContentAnswer(entity)).when(
+            handler).outputReady(Mockito.<NHttpServerConnection>any(), Mockito.<ContentEncoder>any());
+
+        conn.produceOutput(handler);
+
+        Assert.assertNotNull(conn.getHttpResponse());
+        Assert.assertNotNull(conn.contentEncoder);
+        Assert.assertEquals("HTTP/1.1 200 OK\r\n\r\na loo", wchannel.dump(Consts.ASCII));
+
+        Mockito.verify(session, Mockito.never()).clearEvent(SelectionKey.OP_WRITE);
+        Mockito.verify(wchannel, Mockito.times(3)).write(Matchers.<ByteBuffer>any());
+    }
+
+    @Test
+    public void testProduceOutputLongChunkedMessage() throws Exception {
+        conn = new DefaultNHttpServerConnection(session, 64);
+
+        final BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
+        response.addHeader(HTTP.TRANSFER_ENCODING, HTTP.CHUNK_CODING);
+        final NStringEntity entity = new NStringEntity("a lot of various stuff");
+        entity.setChunked(true);
+        response.setEntity(entity);
+
+        final WritableByteChannelMock wchannel = Mockito.spy(new WritableByteChannelMock(64));
+        final ByteChannelMock channel = new ByteChannelMock(null, wchannel);
+        Mockito.when(session.channel()).thenReturn(channel);
+
+        Mockito.doAnswer(new ResponseReadyAnswer(response)).when(
+            handler).responseReady(Mockito.<NHttpServerConnection>any());
+
+        Mockito.doAnswer(new ProduceContentAnswer(entity)).when(
+            handler).outputReady(Mockito.<NHttpServerConnection>any(), Mockito.<ContentEncoder>any());
+
+        conn.produceOutput(handler);
+
+        Assert.assertNull(conn.getHttpResponse());
+        Assert.assertNull(conn.contentEncoder);
+        Assert.assertEquals("HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n" +
+                "5\r\na lot\r\n11\r\n of various stuff\r\n0\r\n\r\n", wchannel.dump(Consts.ASCII));
+
+        Mockito.verify(session, Mockito.times(1)).clearEvent(SelectionKey.OP_WRITE);
+        Mockito.verify(wchannel, Mockito.times(2)).write(Matchers.<ByteBuffer>any());
+    }
+
+    @Test
+    public void testProduceOutputLongChunkedMessageSaturatedChannel() throws Exception {
+        conn = new DefaultNHttpServerConnection(session, 64);
+
+        final BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
+        response.addHeader(HTTP.TRANSFER_ENCODING, HTTP.CHUNK_CODING);
+        final NStringEntity entity = new NStringEntity("a lot of various stuff");
+        entity.setChunked(true);
+        response.setEntity(entity);
+
+        final WritableByteChannelMock wchannel = Mockito.spy(new WritableByteChannelMock(64, 64));
+        final ByteChannelMock channel = new ByteChannelMock(null, wchannel);
+        Mockito.when(session.channel()).thenReturn(channel);
+
+        Mockito.doAnswer(new ResponseReadyAnswer(response)).when(
+            handler).responseReady(Mockito.<NHttpServerConnection>any());
+
+        Mockito.doAnswer(new ProduceContentAnswer(entity)).when(
+            handler).outputReady(Mockito.<NHttpServerConnection>any(), Mockito.<ContentEncoder>any());
+
+        conn.produceOutput(handler);
+
+        Assert.assertNull(conn.getHttpResponse());
+        Assert.assertNull(conn.contentEncoder);
+        Assert.assertEquals("HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n" +
+                "5\r\na lot\r\n11\r\n of", wchannel.dump(Consts.ASCII));
+        Assert.assertEquals(21, conn.outbuf.length());
+
+        Mockito.verify(session, Mockito.never()).clearEvent(SelectionKey.OP_WRITE);
+        Mockito.verify(wchannel, Mockito.times(2)).write(Matchers.<ByteBuffer>any());
+    }
+
+    @Test
+    public void testProduceOutputClosingConnection() throws Exception {
+        final BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
+
+        final WritableByteChannelMock wchannel = Mockito.spy(new WritableByteChannelMock(64));
+        final ByteChannelMock channel = new ByteChannelMock(null, wchannel);
+        Mockito.when(session.channel()).thenReturn(channel);
+
+        conn.submitResponse(response);
+        conn.close();
+
+        Assert.assertEquals(NHttpConnection.CLOSING, conn.getStatus());
+
+        conn.produceOutput(handler);
+
+        Assert.assertEquals(NHttpConnection.CLOSED, conn.getStatus());
+
+        Mockito.verify(wchannel, Mockito.times(1)).write(Matchers.<ByteBuffer>any());
+        Mockito.verify(session, Mockito.times(1)).close();
+        Mockito.verify(session, Mockito.never()).clearEvent(SelectionKey.OP_WRITE);
+        Mockito.verify(handler, Mockito.never()).responseReady(
+            Mockito.<NHttpServerConnection>any());
+        Mockito.verify(handler, Mockito.never()).outputReady(
+            Mockito.<NHttpServerConnection>any(), Mockito.<ContentEncoder>any());
+    }
+
+    static class RequestCapturingAnswer implements Answer<Void> {
+
+        private final LinkedList<HttpRequest> requests;
+
+        RequestCapturingAnswer(final LinkedList<HttpRequest> requests) {
+            super();
+            this.requests = requests;
+        }
+
+        public Void answer(final InvocationOnMock invocation) throws Throwable {
+            final Object[] args = invocation.getArguments();
+            final NHttpServerConnection conn = (NHttpServerConnection) args[0];
+            if (conn != null) {
+                final HttpRequest request = conn.getHttpRequest();
+                if (request != null) {
+                    requests.add(request);
+                }
+            }
+            return null;
+        }
+
+    }
+
+    static class ConsumeContentAnswer implements Answer<Void> {
+
+        private final SimpleInputBuffer buf;
+
+        ConsumeContentAnswer(final SimpleInputBuffer buf) {
+            super();
+            this.buf = buf;
+        }
+
+        public Void answer(final InvocationOnMock invocation) throws Throwable {
+            final Object[] args = invocation.getArguments();
+            final ContentDecoder decoder = (ContentDecoder) args[1];
+            buf.consumeContent(decoder);
+            return null;
+        }
+
+    }
+
+    @Test
+    public void testConsumeInputShortMessage() throws Exception {
+        final ReadableByteChannelMock rchannel = Mockito.spy(new ReadableByteChannelMock(
+            new String[] {"POST / HTTP/1.1\r\nContent-Length: 5\r\n\r\nstuff"}, Consts.ASCII));
+        final ByteChannelMock channel = new ByteChannelMock(rchannel, null);
+        Mockito.when(session.channel()).thenReturn(channel);
+        Mockito.when(session.getEventMask()).thenReturn(SelectionKey.OP_READ);
+
+        final LinkedList<HttpRequest> requests = new LinkedList<HttpRequest>();
+
+        Mockito.doAnswer(new RequestCapturingAnswer(requests)).when(
+            handler).requestReceived(Mockito.<NHttpServerConnection>any());
+        Mockito.doAnswer(new ConsumeContentAnswer(new SimpleInputBuffer(64))).when(
+            handler).inputReady(Mockito.<NHttpServerConnection>any(), Mockito.<ContentDecoder>any());
+
+        Assert.assertEquals(0, conn.getMetrics().getRequestCount());
+
+        conn.consumeInput(handler);
+
+        Assert.assertNull(conn.getHttpResponse());
+        Assert.assertNull(conn.contentDecoder);
+        Assert.assertEquals(1, conn.getMetrics().getRequestCount());
+        Assert.assertEquals(43, conn.getMetrics().getReceivedBytesCount());
+
+        Mockito.verify(handler, Mockito.times(1)).requestReceived(
+            Mockito.<NHttpServerConnection>any());
+        Mockito.verify(handler, Mockito.times(1)).inputReady(
+            Mockito.<NHttpServerConnection>any(), Mockito.<LengthDelimitedDecoder>any());
+        Mockito.verify(rchannel, Mockito.times(2)).read(Mockito.<ByteBuffer>any());
+        Mockito.verify(handler, Mockito.never()).exception(
+            Mockito.<NHttpServerConnection>any(), Mockito.<Exception>any());
+
+        Assert.assertFalse(requests.isEmpty());
+        final HttpRequest request = requests.getFirst();
+        Assert.assertNotNull(request);
+        Assert.assertEquals(HttpVersion.HTTP_1_1, request.getRequestLine().getProtocolVersion());
+        Assert.assertEquals("POST", request.getRequestLine().getMethod());
+        Assert.assertEquals("/", request.getRequestLine().getUri());
+        Assert.assertTrue(request instanceof HttpEntityEnclosingRequest);
+        final HttpEntity entity = ((HttpEntityEnclosingRequest) request).getEntity();
+        Assert.assertNotNull(entity);
+        Assert.assertEquals(5, entity.getContentLength());
+    }
+
+    @Test
+    public void testConsumeInputLongMessage() throws Exception {
+        conn = new DefaultNHttpServerConnection(session, 1024);
+        final ReadableByteChannelMock rchannel = Mockito.spy(new ReadableByteChannelMock(
+            new String[] {"POST / HTTP/1.1\r\nContent-Length: 100\r\n\r\na lot of stuff",
+                "", ""}, Consts.ASCII));
+        final ByteChannelMock channel = new ByteChannelMock(rchannel, null);
+        Mockito.when(session.channel()).thenReturn(channel);
+        Mockito.when(session.getEventMask()).thenReturn(SelectionKey.OP_READ);
+
+        final LinkedList<HttpRequest> requests = new LinkedList<HttpRequest>();
+
+        Mockito.doAnswer(new RequestCapturingAnswer(requests)).when(
+            handler).requestReceived(Mockito.<NHttpServerConnection>any());
+        Mockito.doAnswer(new ConsumeContentAnswer(new SimpleInputBuffer(64))).when(
+            handler).inputReady(Mockito.<NHttpServerConnection>any(), Mockito.<ContentDecoder>any());
+
+        Assert.assertEquals(0, conn.getMetrics().getResponseCount());
+
+        conn.consumeInput(handler);
+
+        Assert.assertNotNull(conn.getHttpRequest());
+        Assert.assertNotNull(conn.contentDecoder);
+        Assert.assertEquals(1, conn.getMetrics().getRequestCount());
+        Assert.assertEquals(54, conn.getMetrics().getReceivedBytesCount());
+
+        Mockito.verify(handler, Mockito.times(1)).requestReceived(
+            Mockito.<NHttpServerConnection>any());
+        Mockito.verify(handler, Mockito.times(1)).inputReady(
+            Mockito.<NHttpServerConnection>any(), Mockito.<LengthDelimitedDecoder>any());
+        Mockito.verify(rchannel, Mockito.times(2)).read(Mockito.<ByteBuffer>any());
+        Mockito.verify(handler, Mockito.never()).exception(
+            Mockito.<NHttpServerConnection>any(), Mockito.<Exception>any());
+
+        Assert.assertFalse(requests.isEmpty());
+        final HttpRequest request = requests.getFirst();
+        Assert.assertNotNull(request);
+        Assert.assertEquals(HttpVersion.HTTP_1_1, request.getRequestLine().getProtocolVersion());
+        Assert.assertEquals("POST", request.getRequestLine().getMethod());
+        Assert.assertEquals("/", request.getRequestLine().getUri());
+        Assert.assertTrue(request instanceof HttpEntityEnclosingRequest);
+        final HttpEntity entity = ((HttpEntityEnclosingRequest) request).getEntity();
+        Assert.assertNotNull(entity);
+        Assert.assertEquals(100, entity.getContentLength());
+
+        conn.consumeInput(handler);
+
+        Assert.assertEquals(1, conn.getMetrics().getRequestCount());
+        Assert.assertEquals(54, conn.getMetrics().getReceivedBytesCount());
+
+        Mockito.verify(rchannel, Mockito.times(3)).read(Mockito.<ByteBuffer>any());
+        Mockito.verify(handler, Mockito.never()).exception(
+            Mockito.<NHttpServerConnection>any(), Mockito.<Exception>any());
+    }
+
+    @Test
+    public void testConsumeInputBasicMessageNoEntity() throws Exception {
+        final ReadableByteChannelMock rchannel = Mockito.spy(new ReadableByteChannelMock(
+            new String[] {"GET / HTTP/1.1\r\n\r\n"}, Consts.ASCII));
+        final ByteChannelMock channel = new ByteChannelMock(rchannel, null);
+        Mockito.when(session.channel()).thenReturn(channel);
+        Mockito.when(session.getEventMask()).thenReturn(SelectionKey.OP_READ);
+
+        final LinkedList<HttpRequest> requests = new LinkedList<HttpRequest>();
+
+        Mockito.doAnswer(new RequestCapturingAnswer(requests)).when(
+            handler).requestReceived(Mockito.<NHttpServerConnection>any());
+        Mockito.doAnswer(new ConsumeContentAnswer(new SimpleInputBuffer(64))).when(
+            handler).inputReady(Mockito.<NHttpServerConnection>any(), Mockito.<ContentDecoder>any());
+
+        conn.consumeInput(handler);
+
+        Assert.assertNull(conn.getHttpResponse());
+        Assert.assertNull(conn.contentDecoder);
+
+        Mockito.verify(handler, Mockito.times(1)).requestReceived(
+            Mockito.<NHttpServerConnection>any());
+        Mockito.verify(handler, Mockito.never()).inputReady(
+            Mockito.<NHttpServerConnection>any(), Mockito.<LengthDelimitedDecoder>any());
+        Mockito.verify(rchannel, Mockito.times(1)).read(Mockito.<ByteBuffer>any());
+        Mockito.verify(handler, Mockito.never()).exception(
+            Mockito.<NHttpServerConnection>any(), Mockito.<Exception>any());
+
+        Assert.assertFalse(requests.isEmpty());
+        final HttpRequest request = requests.getFirst();
+        Assert.assertNotNull(request);
+        Assert.assertEquals(HttpVersion.HTTP_1_1, request.getRequestLine().getProtocolVersion());
+        Assert.assertEquals("GET", request.getRequestLine().getMethod());
+        Assert.assertEquals("/", request.getRequestLine().getUri());
+        Assert.assertFalse(request instanceof HttpEntityEnclosingRequest);
+    }
+
+    @Test
+    public void testConsumeInputNoData() throws Exception {
+        conn = new DefaultNHttpServerConnection(session, 1024);
+        final ReadableByteChannelMock rchannel = Mockito.spy(new ReadableByteChannelMock(
+            new String[] {"", ""}, Consts.ASCII));
+        final ByteChannelMock channel = new ByteChannelMock(rchannel, null);
+        Mockito.when(session.channel()).thenReturn(channel);
+        Mockito.when(session.getEventMask()).thenReturn(SelectionKey.OP_READ);
+
+        final LinkedList<HttpRequest> requests = new LinkedList<HttpRequest>();
+
+        Mockito.doAnswer(new RequestCapturingAnswer(requests)).when(
+            handler).requestReceived(Mockito.<NHttpServerConnection>any());
+        Mockito.doAnswer(new ConsumeContentAnswer(new SimpleInputBuffer(64))).when(
+            handler).inputReady(Mockito.<NHttpServerConnection>any(), Mockito.<ContentDecoder>any());
+
+        Assert.assertEquals(0, conn.getMetrics().getResponseCount());
+
+        conn.consumeInput(handler);
+
+        Assert.assertNull(conn.getHttpResponse());
+        Assert.assertNull(conn.contentDecoder);
+        Assert.assertEquals(0, conn.getMetrics().getResponseCount());
+        Assert.assertEquals(0, conn.getMetrics().getReceivedBytesCount());
+
+        Mockito.verify(handler, Mockito.never()).requestReceived(
+            Mockito.<NHttpServerConnection>any());
+        Mockito.verify(handler, Mockito.never()).inputReady(
+            Mockito.<NHttpServerConnection>any(), Mockito.<LengthDelimitedDecoder>any());
+        Mockito.verify(rchannel, Mockito.times(1)).read(Mockito.<ByteBuffer>any());
+        Mockito.verify(handler, Mockito.never()).exception(
+            Mockito.<NHttpServerConnection>any(), Mockito.<Exception>any());
+
+        conn.consumeInput(handler);
+
+        Assert.assertNull(conn.getHttpResponse());
+        Assert.assertNull(conn.contentDecoder);
+        Assert.assertEquals(0, conn.getMetrics().getResponseCount());
+        Assert.assertEquals(0, conn.getMetrics().getReceivedBytesCount());
+
+        Mockito.verify(handler, Mockito.never()).requestReceived(
+            Mockito.<NHttpServerConnection>any());
+        Mockito.verify(handler, Mockito.never()).inputReady(
+            Mockito.<NHttpServerConnection>any(), Mockito.<LengthDelimitedDecoder>any());
+        Mockito.verify(rchannel, Mockito.times(2)).read(Mockito.<ByteBuffer>any());
+        Mockito.verify(handler, Mockito.never()).exception(
+            Mockito.<NHttpServerConnection>any(), Mockito.<Exception>any());
+
+        conn.consumeInput(handler);
+        Assert.assertNull(conn.getHttpResponse());
+        Assert.assertNull(conn.contentDecoder);
+        Assert.assertEquals(0, conn.getMetrics().getResponseCount());
+        Assert.assertEquals(0, conn.getMetrics().getReceivedBytesCount());
+
+        Mockito.verify(handler, Mockito.never()).requestReceived(
+            Mockito.<NHttpServerConnection>any());
+        Mockito.verify(handler, Mockito.never()).inputReady(
+            Mockito.<NHttpServerConnection>any(), Mockito.<LengthDelimitedDecoder>any());
+        Mockito.verify(rchannel, Mockito.times(3)).read(Mockito.<ByteBuffer>any());
+        Mockito.verify(handler, Mockito.times(1)).endOfInput(
+            Mockito.<NHttpServerConnection>any());
+        Mockito.verify(handler, Mockito.never()).exception(
+            Mockito.<NHttpServerConnection>any(), Mockito.<Exception>any());
+
+    }
+
+    @Test
+    public void testConsumeInputConnectionClosed() throws Exception {
+        conn = new DefaultNHttpServerConnection(session, 1024);
+        final ReadableByteChannelMock rchannel = Mockito.spy(new ReadableByteChannelMock(
+            new String[] {"", ""}, Consts.ASCII));
+        final ByteChannelMock channel = new ByteChannelMock(rchannel, null);
+        Mockito.when(session.channel()).thenReturn(channel);
+        Mockito.when(session.getEventMask()).thenReturn(SelectionKey.OP_READ);
+
+        conn.close();
+        conn.consumeInput(handler);
+        Mockito.verify(rchannel, Mockito.never()).read(Mockito.<ByteBuffer>any());
+        Mockito.verify(session, Mockito.times(1)).clearEvent(SelectionKey.OP_READ);
+    }
+
+}
diff --git a/httpcore-nio/src/test/java/org/apache/http/impl/nio/TestNHttpConnectionBase.java b/httpcore-nio/src/test/java/org/apache/http/impl/nio/TestNHttpConnectionBase.java
new file mode 100644
index 0000000..bf9e956
--- /dev/null
+++ b/httpcore-nio/src/test/java/org/apache/http/impl/nio/TestNHttpConnectionBase.java
@@ -0,0 +1,277 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+package org.apache.http.impl.nio;
+
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.nio.channels.ByteChannel;
+import java.nio.channels.SelectionKey;
+
+import junit.framework.Assert;
+
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpVersion;
+import org.apache.http.impl.entity.LaxContentLengthStrategy;
+import org.apache.http.impl.entity.StrictContentLengthStrategy;
+import org.apache.http.impl.nio.codecs.ChunkDecoder;
+import org.apache.http.impl.nio.codecs.ChunkEncoder;
+import org.apache.http.impl.nio.codecs.IdentityDecoder;
+import org.apache.http.impl.nio.codecs.IdentityEncoder;
+import org.apache.http.impl.nio.codecs.LengthDelimitedDecoder;
+import org.apache.http.impl.nio.codecs.LengthDelimitedEncoder;
+import org.apache.http.message.BasicHttpResponse;
+import org.apache.http.nio.NHttpConnection;
+import org.apache.http.nio.reactor.IOSession;
+import org.apache.http.nio.util.HeapByteBufferAllocator;
+import org.apache.http.protocol.HTTP;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+
+public class TestNHttpConnectionBase {
+
+    @Mock
+    private IOSession session;
+    @Mock
+    private ByteChannel channel;
+
+    private NHttpConnectionBase conn;
+
+    @Before
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+        conn = new NHttpConnectionBase(session, 1024, 1024, HeapByteBufferAllocator.INSTANCE,
+            null, null,
+            LaxContentLengthStrategy.INSTANCE,
+            StrictContentLengthStrategy.INSTANCE);
+    }
+
+    @Test
+    public void testBasics() throws Exception {
+        Assert.assertEquals("[ACTIVE]", conn.toString());
+
+        Mockito.verify(session).setBufferStatus(conn);
+    }
+
+    @Test
+    public void testSessionBind() throws Exception {
+        final InetSocketAddress local = new InetSocketAddress(
+            InetAddress.getByAddress(new byte[] {127, 0, 0, 1}), 8888);
+        final InetSocketAddress remote = new InetSocketAddress(
+            InetAddress.getByAddress(new byte[] {10, 0, 0, 2}), 80);
+        Mockito.when(session.getLocalAddress()).thenReturn(local);
+        Mockito.when(session.getRemoteAddress()).thenReturn(remote);
+        Mockito.when(session.isClosed()).thenReturn(Boolean.FALSE);
+
+        conn.bind(session);
+
+        Mockito.verify(session, Mockito.times(2)).setBufferStatus(conn);
+
+        Assert.assertEquals("127.0.0.1:8888<->10.0.0.2:80[ACTIVE]", conn.toString());
+        Assert.assertTrue(conn.isOpen());
+        Assert.assertEquals(8888, conn.getLocalPort());
+        Assert.assertEquals(80, conn.getRemotePort());
+        Assert.assertEquals(InetAddress.getByAddress(new byte[] {127, 0, 0, 1}), conn.getLocalAddress());
+        Assert.assertEquals(InetAddress.getByAddress(new byte[] {10, 0, 0, 2}), conn.getRemoteAddress());
+    }
+
+    @Test
+    public void testClose() throws Exception {
+        final InetSocketAddress local = new InetSocketAddress(
+            InetAddress.getByAddress(new byte[] {127, 0, 0, 1}), 8888);
+        final InetSocketAddress remote = new InetSocketAddress(
+            InetAddress.getByAddress(new byte[] {10, 0, 0, 2}), 80);
+        Mockito.when(session.getLocalAddress()).thenReturn(local);
+        Mockito.when(session.getRemoteAddress()).thenReturn(remote);
+        Mockito.when(session.isClosed()).thenReturn(Boolean.FALSE);
+
+        conn.close();
+
+        Assert.assertEquals(NHttpConnection.CLOSED, conn.getStatus());
+        Assert.assertEquals("127.0.0.1:8888<->10.0.0.2:80[CLOSED]", conn.toString());
+
+        Mockito.verify(session).close();
+    }
+
+    @Test
+    public void testCloseWithBufferedData() throws Exception {
+        final InetSocketAddress local = new InetSocketAddress(
+            InetAddress.getByAddress(new byte[] {127, 0, 0, 1}), 8888);
+        final InetSocketAddress remote = new InetSocketAddress(
+            InetAddress.getByAddress(new byte[] {10, 0, 0, 2}), 80);
+        Mockito.when(session.getLocalAddress()).thenReturn(local);
+        Mockito.when(session.getRemoteAddress()).thenReturn(remote);
+        Mockito.when(session.isClosed()).thenReturn(Boolean.FALSE);
+
+        conn.outbuf.writeLine("stuff");
+        conn.close();
+
+        Assert.assertEquals(NHttpConnection.CLOSING, conn.getStatus());
+        conn.close();
+        Assert.assertEquals(NHttpConnection.CLOSING, conn.getStatus());
+        Assert.assertEquals("127.0.0.1:8888<->10.0.0.2:80[CLOSING]", conn.toString());
+
+        Mockito.verify(session).setEvent(SelectionKey.OP_WRITE);
+        Mockito.verify(session, Mockito.never()).close();
+    }
+
+    @Test
+    public void testShutdown() throws Exception {
+        final InetSocketAddress local = new InetSocketAddress(
+            InetAddress.getByAddress(new byte[] {127, 0, 0, 1}), 8888);
+        final InetSocketAddress remote = new InetSocketAddress(
+            InetAddress.getByAddress(new byte[] {10, 0, 0, 2}), 80);
+        Mockito.when(session.getLocalAddress()).thenReturn(local);
+        Mockito.when(session.getRemoteAddress()).thenReturn(remote);
+        Mockito.when(session.isClosed()).thenReturn(Boolean.FALSE);
+
+        conn.outbuf.writeLine("stuff");
+        conn.shutdown();
+
+        Assert.assertEquals(NHttpConnection.CLOSED, conn.getStatus());
+        Assert.assertEquals("127.0.0.1:8888<->10.0.0.2:80[CLOSED]", conn.toString());
+
+        Mockito.verify(session).shutdown();
+    }
+
+    @Test
+    public void testContextOperations() throws Exception {
+        conn.getContext().getAttribute("stuff");
+        conn.getContext().setAttribute("stuff", "blah");
+        conn.getContext().removeAttribute("other stuff");
+
+        Mockito.verify(session).getAttribute("stuff");
+        Mockito.verify(session).setAttribute("stuff", "blah");
+        Mockito.verify(session).removeAttribute("other stuff");
+    }
+
+    @Test
+    public void testIOOperations() throws Exception {
+        conn.suspendInput();
+        Mockito.verify(session).clearEvent(SelectionKey.OP_READ);
+
+        conn.suspendOutput();
+        Mockito.verify(session).clearEvent(SelectionKey.OP_WRITE);
+
+        conn.requestInput();
+        Mockito.verify(session).setEvent(SelectionKey.OP_READ);
+
+        conn.requestOutput();
+        Mockito.verify(session).setEvent(SelectionKey.OP_WRITE);
+    }
+
+    @Test
+    public void testSocketTimeout() throws Exception {
+        conn.getSocketTimeout();
+        Mockito.verify(session).getSocketTimeout();
+
+        conn.setSocketTimeout(123);
+        Mockito.verify(session).setSocketTimeout(123);
+    }
+
+    @Test
+    public void testPrepareIdentityDecoder() throws Exception {
+        final BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
+        Mockito.when(session.channel()).thenReturn(channel);
+
+        final HttpEntity entity = conn.prepareDecoder(response);
+        Assert.assertNotNull(entity);
+        Assert.assertEquals(-1, entity.getContentLength());
+        Assert.assertFalse(entity.isChunked());
+        Assert.assertTrue(conn.contentDecoder instanceof IdentityDecoder);
+    }
+
+    @Test
+    public void testPrepareLengthDelimitedDecoder() throws Exception {
+        final BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
+        response.addHeader(HTTP.CONTENT_LEN, "10");
+        response.addHeader(HTTP.CONTENT_TYPE, "stuff");
+        response.addHeader(HTTP.CONTENT_ENCODING, "identity");
+        Mockito.when(session.channel()).thenReturn(channel);
+
+        final HttpEntity entity = conn.prepareDecoder(response);
+        Assert.assertNotNull(entity);
+        Assert.assertEquals(10, entity.getContentLength());
+        Assert.assertFalse(entity.isChunked());
+        Assert.assertNotNull(entity.getContentType());
+        Assert.assertEquals("stuff", entity.getContentType().getValue());
+        Assert.assertNotNull(entity.getContentEncoding());
+        Assert.assertEquals("identity", entity.getContentEncoding().getValue());
+        Assert.assertTrue(conn.contentDecoder instanceof LengthDelimitedDecoder);
+    }
+
+    @Test
+    public void testPrepareChunkDecoder() throws Exception {
+        final BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
+        response.addHeader(HTTP.TRANSFER_ENCODING, "chunked");
+        response.addHeader(HTTP.CONTENT_TYPE, "stuff");
+        response.addHeader(HTTP.CONTENT_ENCODING, "identity");
+        Mockito.when(session.channel()).thenReturn(channel);
+
+        final HttpEntity entity = conn.prepareDecoder(response);
+        Assert.assertNotNull(entity);
+        Assert.assertEquals(-1, entity.getContentLength());
+        Assert.assertTrue(entity.isChunked());
+        Assert.assertNotNull(entity.getContentType());
+        Assert.assertEquals("stuff", entity.getContentType().getValue());
+        Assert.assertNotNull(entity.getContentEncoding());
+        Assert.assertEquals("identity", entity.getContentEncoding().getValue());
+        Assert.assertTrue(conn.contentDecoder instanceof ChunkDecoder);
+    }
+
+    @Test
+    public void testPrepareIdentityEncoder() throws Exception {
+        final BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
+        Mockito.when(session.channel()).thenReturn(channel);
+
+        conn.prepareEncoder(response);
+        Assert.assertTrue(conn.contentEncoder instanceof IdentityEncoder);
+    }
+
+    @Test
+    public void testPrepareLengthDelimitedEncoder() throws Exception {
+        final BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
+        response.addHeader(HTTP.CONTENT_LEN, "10");
+        Mockito.when(session.channel()).thenReturn(channel);
+
+        conn.prepareEncoder(response);
+        Assert.assertTrue(conn.contentEncoder instanceof LengthDelimitedEncoder);
+    }
+
+    @Test
+    public void testPrepareChunkEncoder() throws Exception {
+        final BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
+        response.addHeader(HTTP.TRANSFER_ENCODING, "chunked");
+        Mockito.when(session.channel()).thenReturn(channel);
+
+        conn.prepareEncoder(response);
+        Assert.assertTrue(conn.contentEncoder instanceof ChunkEncoder);
+    }
+
+}
diff --git a/httpcore-nio/src/test/java/org/apache/http/nio/util/ContentEncoderMock.java b/httpcore-nio/src/test/java/org/apache/http/impl/nio/codecs/CodecTestUtils.java
similarity index 52%
copy from httpcore-nio/src/test/java/org/apache/http/nio/util/ContentEncoderMock.java
copy to httpcore-nio/src/test/java/org/apache/http/impl/nio/codecs/CodecTestUtils.java
index a2d3bac..f1c1a82 100644
--- a/httpcore-nio/src/test/java/org/apache/http/nio/util/ContentEncoderMock.java
+++ b/httpcore-nio/src/test/java/org/apache/http/impl/nio/codecs/CodecTestUtils.java
@@ -25,46 +25,44 @@
  *
  */
 
-package org.apache.http.nio.util;
+package org.apache.http.impl.nio.codecs;
 
-import java.io.IOException;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStreamReader;
 import java.nio.ByteBuffer;
-import java.nio.channels.WritableByteChannel;
 
-import org.apache.http.impl.io.HttpTransportMetricsImpl;
-import org.apache.http.impl.nio.codecs.AbstractContentEncoder;
-import org.apache.http.nio.reactor.SessionOutputBuffer;
+import org.apache.http.util.EncodingUtils;
 
-public class ContentEncoderMock extends AbstractContentEncoder {
+class CodecTestUtils {
 
-    // TODO? remove this field and the complete() and isCompleted() methods
-    private boolean completed;
-
-    public ContentEncoderMock(
-            final WritableByteChannel channel,
-            final SessionOutputBuffer buffer,
-            final HttpTransportMetricsImpl metrics) {
-        super(channel, buffer, metrics);
-    }
-
-    @Override
-    public boolean isCompleted() {
-        return this.completed;
+    public static ByteBuffer wrap(final String s) {
+        return ByteBuffer.wrap(EncodingUtils.getAsciiBytes(s));
     }
 
-    @Override
-    public void complete() throws IOException {
-        this.completed = true;
+    public static String convert(final ByteBuffer src) {
+        src.flip();
+        final StringBuilder buffer = new StringBuilder(src.remaining());
+        while (src.hasRemaining()) {
+            buffer.append((char)(src.get() & 0xff));
+        }
+        return buffer.toString();
     }
 
-    public int write(final ByteBuffer src) throws IOException {
-        if (src == null) {
-            return 0;
-        }
-        if (this.completed) {
-            throw new IllegalStateException("Decoding process already completed");
+    public static String readFromFile(final File file) throws Exception {
+        final FileInputStream filestream = new FileInputStream(file);
+        final InputStreamReader reader = new InputStreamReader(filestream);
+        try {
+            final StringBuilder buffer = new StringBuilder();
+            final char[] tmp = new char[2048];
+            int l;
+            while ((l = reader.read(tmp)) != -1) {
+                buffer.append(tmp, 0, l);
+            }
+            return buffer.toString();
+        } finally {
+            reader.close();
         }
-        return this.channel.write(src);
     }
 
 }
diff --git a/httpcore-nio/src/test/java/org/apache/http/impl/nio/codecs/TestChunkDecoder.java b/httpcore-nio/src/test/java/org/apache/http/impl/nio/codecs/TestChunkDecoder.java
index cfaf4c3..008b1e8 100644
--- a/httpcore-nio/src/test/java/org/apache/http/impl/nio/codecs/TestChunkDecoder.java
+++ b/httpcore-nio/src/test/java/org/apache/http/impl/nio/codecs/TestChunkDecoder.java
@@ -31,14 +31,13 @@ import java.io.IOException;
 import java.nio.ByteBuffer;
 import java.nio.channels.ReadableByteChannel;
 
+import org.apache.http.Consts;
 import org.apache.http.Header;
 import org.apache.http.MalformedChunkCodingException;
 import org.apache.http.ReadableByteChannelMock;
 import org.apache.http.impl.io.HttpTransportMetricsImpl;
 import org.apache.http.impl.nio.reactor.SessionInputBufferImpl;
 import org.apache.http.nio.reactor.SessionInputBuffer;
-import org.apache.http.params.BasicHttpParams;
-import org.apache.http.params.HttpParams;
 import org.junit.Assert;
 import org.junit.Test;
 
@@ -47,66 +46,55 @@ import org.junit.Test;
  */
 public class TestChunkDecoder {
 
-    private static String convert(final ByteBuffer src) {
-        src.flip();
-        StringBuilder buffer = new StringBuilder(src.remaining());
-        while (src.hasRemaining()) {
-            buffer.append((char)(src.get() & 0xff));
-        }
-        return buffer.toString();
-    }
-
     @Test
     public void testBasicDecoding() throws Exception {
-        String s = "5\r\n01234\r\n5\r\n56789\r\n6\r\nabcdef\r\n0\r\n\r\n";
-        ReadableByteChannel channel = new ReadableByteChannelMock(
-                new String[] {s}, "US-ASCII");
-        HttpParams params = new BasicHttpParams();
+        final String s = "5\r\n01234\r\n5\r\n56789\r\n6\r\nabcdef\r\n0\r\n\r\n";
+        final ReadableByteChannel channel = new ReadableByteChannelMock(
+                new String[] {s}, Consts.ASCII);
+        final SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 256, Consts.ASCII);
+        final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
+        final ChunkDecoder decoder = new ChunkDecoder(channel, inbuf, metrics);
 
-        SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 256, params);
-        HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
-        ChunkDecoder decoder = new ChunkDecoder(channel, inbuf, metrics);
-
-        ByteBuffer dst = ByteBuffer.allocate(1024);
+        final ByteBuffer dst = ByteBuffer.allocate(1024);
 
         int bytesRead = decoder.read(dst);
         Assert.assertEquals(16, bytesRead);
-        Assert.assertEquals("0123456789abcdef", convert(dst));
-        Header[] footers = decoder.getFooters();
+        Assert.assertEquals("0123456789abcdef", CodecTestUtils.convert(dst));
+        final Header[] footers = decoder.getFooters();
         Assert.assertEquals(0, footers.length);
 
         dst.clear();
         bytesRead = decoder.read(dst);
         Assert.assertEquals(-1, bytesRead);
         Assert.assertTrue(decoder.isCompleted());
+        Assert.assertEquals("[chunk-coded; completed: true]", decoder.toString());
     }
 
     @Test
     public void testComplexDecoding() throws Exception {
-        String s = "10;key=\"value\"\r\n1234567890123456\r\n" +
+        final String s = "10;key=\"value\"\r\n1234567890123456\r\n" +
                 "5\r\n12345\r\n5\r\n12345\r\n0\r\nFooter1: abcde\r\nFooter2: fghij\r\n\r\n";
-        ReadableByteChannel channel = new ReadableByteChannelMock(
-                new String[] {s}, "US-ASCII");
-        HttpParams params = new BasicHttpParams();
+        final ReadableByteChannel channel = new ReadableByteChannelMock(
+                new String[] {s}, Consts.ASCII);
 
-        SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 256, params);
-        HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
-        ChunkDecoder decoder = new ChunkDecoder(channel, inbuf, metrics);
+        final SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 256, Consts.ASCII);
+        final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
+        final ChunkDecoder decoder = new ChunkDecoder(channel, inbuf, metrics);
 
-        ByteBuffer dst = ByteBuffer.allocate(1024);
+        final ByteBuffer dst = ByteBuffer.allocate(1024);
 
         int bytesRead = 0;
         while (dst.hasRemaining() && !decoder.isCompleted()) {
-            int i = decoder.read(dst);
+            final int i = decoder.read(dst);
             if (i > 0) {
                 bytesRead += i;
             }
         }
 
         Assert.assertEquals(26, bytesRead);
-        Assert.assertEquals("12345678901234561234512345", convert(dst));
+        Assert.assertEquals("12345678901234561234512345", CodecTestUtils.convert(dst));
 
-        Header[] footers = decoder.getFooters();
+        final Header[] footers = decoder.getFooters();
         Assert.assertEquals(2, footers.length);
         Assert.assertEquals("Footer1", footers[0].getName());
         Assert.assertEquals("abcde", footers[0].getValue());
@@ -121,22 +109,21 @@ public class TestChunkDecoder {
 
     @Test
     public void testDecodingWithSmallBuffer() throws Exception {
-        String s1 = "5\r\n01234\r\n5\r\n5678";
-        String s2 = "9\r\n6\r\nabcdef\r\n0\r\n\r\n";
-        ReadableByteChannel channel = new ReadableByteChannelMock(
-                new String[] {s1, s2}, "US-ASCII");
-        HttpParams params = new BasicHttpParams();
+        final String s1 = "5\r\n01234\r\n5\r\n5678";
+        final String s2 = "9\r\n6\r\nabcdef\r\n0\r\n\r\n";
+        final ReadableByteChannel channel = new ReadableByteChannelMock(
+                new String[] {s1, s2}, Consts.ASCII);
 
-        SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 256, params);
-        HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
-        ChunkDecoder decoder = new ChunkDecoder(channel, inbuf, metrics);
+        final SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 256, Consts.ASCII);
+        final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
+        final ChunkDecoder decoder = new ChunkDecoder(channel, inbuf, metrics);
 
-        ByteBuffer dst = ByteBuffer.allocate(1024);
-        ByteBuffer tmp = ByteBuffer.allocate(4);
+        final ByteBuffer dst = ByteBuffer.allocate(1024);
+        final ByteBuffer tmp = ByteBuffer.allocate(4);
 
         int bytesRead = 0;
         while (dst.hasRemaining() && !decoder.isCompleted()) {
-            int i = decoder.read(tmp);
+            final int i = decoder.read(tmp);
             if (i > 0) {
                 bytesRead += i;
             }
@@ -146,7 +133,7 @@ public class TestChunkDecoder {
         }
 
         Assert.assertEquals(16, bytesRead);
-        Assert.assertEquals("0123456789abcdef", convert(dst));
+        Assert.assertEquals("0123456789abcdef", CodecTestUtils.convert(dst));
         Assert.assertTrue(decoder.isCompleted());
 
         dst.clear();
@@ -157,7 +144,7 @@ public class TestChunkDecoder {
 
     @Test
     public void testIncompleteChunkDecoding() throws Exception {
-        String[] chunks = {
+        final String[] chunks = {
                 "10;",
                 "key=\"value\"\r",
                 "\n123456789012345",
@@ -168,29 +155,28 @@ public class TestChunkDecoder {
                 "er1: abcde\r\nFooter2: f",
                 "ghij\r\n\r\n"
         };
-        ReadableByteChannel channel = new ReadableByteChannelMock(
-                chunks, "US-ASCII");
-        HttpParams params = new BasicHttpParams();
+        final ReadableByteChannel channel = new ReadableByteChannelMock(
+                chunks, Consts.ASCII);
 
-        SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 256, params);
-        HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
-        ByteBuffer dst = ByteBuffer.allocate(1024);
+        final SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 256, Consts.ASCII);
+        final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
+        final ByteBuffer dst = ByteBuffer.allocate(1024);
 
-        ChunkDecoder decoder = new ChunkDecoder(channel, inbuf, metrics);
+        final ChunkDecoder decoder = new ChunkDecoder(channel, inbuf, metrics);
 
         int bytesRead = 0;
         while (dst.hasRemaining() && !decoder.isCompleted()) {
-            int i = decoder.read(dst);
+            final int i = decoder.read(dst);
             if (i > 0) {
                 bytesRead += i;
             }
         }
 
         Assert.assertEquals(27, bytesRead);
-        Assert.assertEquals("123456789012345612345abcdef", convert(dst));
+        Assert.assertEquals("123456789012345612345abcdef", CodecTestUtils.convert(dst));
         Assert.assertTrue(decoder.isCompleted());
 
-        Header[] footers = decoder.getFooters();
+        final Header[] footers = decoder.getFooters();
         Assert.assertEquals(2, footers.length);
         Assert.assertEquals("Footer1", footers[0].getName());
         Assert.assertEquals("abcde", footers[0].getValue());
@@ -205,86 +191,82 @@ public class TestChunkDecoder {
 
     @Test
     public void testMalformedChunkSizeDecoding() throws Exception {
-        String s = "5\r\n01234\r\n5zz\r\n56789\r\n6\r\nabcdef\r\n0\r\n\r\n";
-        ReadableByteChannel channel = new ReadableByteChannelMock(
-                new String[] {s}, "US-ASCII");
-        HttpParams params = new BasicHttpParams();
+        final String s = "5\r\n01234\r\n5zz\r\n56789\r\n6\r\nabcdef\r\n0\r\n\r\n";
+        final ReadableByteChannel channel = new ReadableByteChannelMock(
+                new String[] {s}, Consts.ASCII);
 
-        SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 256, params);
-        HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
-        ChunkDecoder decoder = new ChunkDecoder(channel, inbuf, metrics);
+        final SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 256, Consts.ASCII);
+        final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
+        final ChunkDecoder decoder = new ChunkDecoder(channel, inbuf, metrics);
 
-        ByteBuffer dst = ByteBuffer.allocate(1024);
+        final ByteBuffer dst = ByteBuffer.allocate(1024);
 
         try {
             decoder.read(dst);
             Assert.fail("MalformedChunkCodingException should have been thrown");
-        } catch (MalformedChunkCodingException ex) {
+        } catch (final MalformedChunkCodingException ex) {
             // expected
         }
     }
 
     @Test
     public void testMalformedChunkEndingDecoding() throws Exception {
-        String s = "5\r\n01234\r\n5\r\n56789\n\r6\r\nabcdef\r\n0\r\n\r\n";
-        ReadableByteChannel channel = new ReadableByteChannelMock(
-                new String[] {s}, "US-ASCII");
-        HttpParams params = new BasicHttpParams();
+        final String s = "5\r\n01234\r\n5\r\n56789\n\r6\r\nabcdef\r\n0\r\n\r\n";
+        final ReadableByteChannel channel = new ReadableByteChannelMock(
+                new String[] {s}, Consts.ASCII);
 
-        SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 256, params);
-        HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
-        ChunkDecoder decoder = new ChunkDecoder(channel, inbuf, metrics);
+        final SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 256, Consts.ASCII);
+        final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
+        final ChunkDecoder decoder = new ChunkDecoder(channel, inbuf, metrics);
 
-        ByteBuffer dst = ByteBuffer.allocate(1024);
+        final ByteBuffer dst = ByteBuffer.allocate(1024);
 
         try {
             decoder.read(dst);
             Assert.fail("MalformedChunkCodingException should have been thrown");
-        } catch (MalformedChunkCodingException ex) {
+        } catch (final MalformedChunkCodingException ex) {
             // expected
         }
     }
 
     @Test
     public void testMalformedChunkTruncatedChunk() throws Exception {
-        String s = "3\r\n12";
-        ReadableByteChannel channel = new ReadableByteChannelMock(
-                new String[] {s}, "US-ASCII");
-        HttpParams params = new BasicHttpParams();
+        final String s = "3\r\n12";
+        final ReadableByteChannel channel = new ReadableByteChannelMock(
+                new String[] {s}, Consts.ASCII);
 
-        SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 256, params);
-        HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
-        ChunkDecoder decoder = new ChunkDecoder(channel, inbuf, metrics);
+        final SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 256, Consts.ASCII);
+        final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
+        final ChunkDecoder decoder = new ChunkDecoder(channel, inbuf, metrics);
 
-        ByteBuffer dst = ByteBuffer.allocate(1024);
+        final ByteBuffer dst = ByteBuffer.allocate(1024);
         Assert.assertEquals(2, decoder.read(dst));
         try {
             decoder.read(dst);
             Assert.fail("MalformedChunkCodingException should have been thrown");
-        } catch (MalformedChunkCodingException ex) {
+        } catch (final MalformedChunkCodingException ex) {
             // expected
         }
     }
 
     @Test
     public void testFoldedFooters() throws Exception {
-        String s = "10;key=\"value\"\r\n1234567890123456\r\n" +
+        final String s = "10;key=\"value\"\r\n1234567890123456\r\n" +
                 "5\r\n12345\r\n5\r\n12345\r\n0\r\nFooter1: abcde\r\n   \r\n  fghij\r\n\r\n";
-        ReadableByteChannel channel = new ReadableByteChannelMock(
-                new String[] {s}, "US-ASCII");
-        HttpParams params = new BasicHttpParams();
+        final ReadableByteChannel channel = new ReadableByteChannelMock(
+                new String[] {s}, Consts.ASCII);
 
-        SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 256, params);
-        HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
-        ChunkDecoder decoder = new ChunkDecoder(channel, inbuf, metrics);
+        final SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 256, Consts.ASCII);
+        final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
+        final ChunkDecoder decoder = new ChunkDecoder(channel, inbuf, metrics);
 
-        ByteBuffer dst = ByteBuffer.allocate(1024);
+        final ByteBuffer dst = ByteBuffer.allocate(1024);
 
-        int bytesRead = decoder.read(dst);
+        final int bytesRead = decoder.read(dst);
         Assert.assertEquals(26, bytesRead);
-        Assert.assertEquals("12345678901234561234512345", convert(dst));
+        Assert.assertEquals("12345678901234561234512345", CodecTestUtils.convert(dst));
 
-        Header[] footers = decoder.getFooters();
+        final Header[] footers = decoder.getFooters();
         Assert.assertEquals(1, footers.length);
         Assert.assertEquals("Footer1", footers[0].getName());
         Assert.assertEquals("abcde  fghij", footers[0].getValue());
@@ -292,72 +274,69 @@ public class TestChunkDecoder {
 
     @Test
     public void testMalformedFooters() throws Exception {
-        String s = "10;key=\"value\"\r\n1234567890123456\r\n" +
+        final String s = "10;key=\"value\"\r\n1234567890123456\r\n" +
                 "5\r\n12345\r\n5\r\n12345\r\n0\r\nFooter1 abcde\r\n\r\n";
-        ReadableByteChannel channel = new ReadableByteChannelMock(
-                new String[] {s}, "US-ASCII");
-        HttpParams params = new BasicHttpParams();
+        final ReadableByteChannel channel = new ReadableByteChannelMock(
+                new String[] {s}, Consts.ASCII);
 
-        SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 256, params);
-        HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
-        ChunkDecoder decoder = new ChunkDecoder(channel, inbuf, metrics);
+        final SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 256, Consts.ASCII);
+        final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
+        final ChunkDecoder decoder = new ChunkDecoder(channel, inbuf, metrics);
 
-        ByteBuffer dst = ByteBuffer.allocate(1024);
+        final ByteBuffer dst = ByteBuffer.allocate(1024);
 
         try {
             decoder.read(dst);
             Assert.fail("MalformedChunkCodingException should have been thrown");
-        } catch (IOException ex) {
+        } catch (final IOException ex) {
             // expected
         }
     }
 
     @Test
     public void testEndOfStreamConditionReadingLastChunk() throws Exception {
-        String s = "10\r\n1234567890123456\r\n" +
+        final String s = "10\r\n1234567890123456\r\n" +
                 "5\r\n12345\r\n5\r\n12345";
-        ReadableByteChannel channel = new ReadableByteChannelMock(
-                new String[] {s}, "US-ASCII");
-        HttpParams params = new BasicHttpParams();
+        final ReadableByteChannel channel = new ReadableByteChannelMock(
+                new String[] {s}, Consts.ASCII);
 
-        SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 256, params);
-        HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
-        ChunkDecoder decoder = new ChunkDecoder(channel, inbuf, metrics);
+        final SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 256, Consts.ASCII);
+        final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
+        final ChunkDecoder decoder = new ChunkDecoder(channel, inbuf, metrics);
 
-        ByteBuffer dst = ByteBuffer.allocate(1024);
+        final ByteBuffer dst = ByteBuffer.allocate(1024);
 
         int bytesRead = 0;
         while (dst.hasRemaining() && !decoder.isCompleted()) {
-            int i = decoder.read(dst);
+            final int i = decoder.read(dst);
             if (i > 0) {
                 bytesRead += i;
             }
         }
 
         Assert.assertEquals(26, bytesRead);
-        Assert.assertEquals("12345678901234561234512345", convert(dst));
+        Assert.assertEquals("12345678901234561234512345", CodecTestUtils.convert(dst));
         Assert.assertTrue(decoder.isCompleted());
     }
 
     @Test
     public void testReadingWitSmallBuffer() throws Exception {
-        String s = "10\r\n1234567890123456\r\n" +
+        final String s = "10\r\n1234567890123456\r\n" +
                 "40\r\n12345678901234561234567890123456" +
                 "12345678901234561234567890123456\r\n0\r\n";
-        ReadableByteChannel channel = new ReadableByteChannelMock(
-                new String[] {s}, "US-ASCII");
-        HttpParams params = new BasicHttpParams();
+        final ReadableByteChannel channel = new ReadableByteChannelMock(
+                new String[] {s}, Consts.ASCII);
 
-        SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 256, params);
-        HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
-        ChunkDecoder decoder = new ChunkDecoder(channel, inbuf, metrics);
+        final SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 256, Consts.ASCII);
+        final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
+        final ChunkDecoder decoder = new ChunkDecoder(channel, inbuf, metrics);
 
-        ByteBuffer dst = ByteBuffer.allocate(1024);
-        ByteBuffer tmp = ByteBuffer.allocate(10);
+        final ByteBuffer dst = ByteBuffer.allocate(1024);
+        final ByteBuffer tmp = ByteBuffer.allocate(10);
 
         int bytesRead = 0;
         while (dst.hasRemaining() && !decoder.isCompleted()) {
-            int i = decoder.read(tmp);
+            final int i = decoder.read(tmp);
             if (i > 0) {
                 bytesRead += i;
                 tmp.flip();
@@ -369,80 +348,77 @@ public class TestChunkDecoder {
         Assert.assertEquals(80, bytesRead);
         Assert.assertEquals("12345678901234561234567890123456" +
                 "12345678901234561234567890123456" +
-                "1234567890123456", convert(dst));
+                "1234567890123456", CodecTestUtils.convert(dst));
         Assert.assertTrue(decoder.isCompleted());
     }
 
     @Test
     public void testEndOfStreamConditionReadingFooters() throws Exception {
-        String s = "10\r\n1234567890123456\r\n" +
+        final String s = "10\r\n1234567890123456\r\n" +
                 "5\r\n12345\r\n5\r\n12345\r\n0\r\n";
-        ReadableByteChannel channel = new ReadableByteChannelMock(
-                new String[] {s}, "US-ASCII");
-        HttpParams params = new BasicHttpParams();
+        final ReadableByteChannel channel = new ReadableByteChannelMock(
+                new String[] {s}, Consts.ASCII);
 
-        SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 256, params);
-        HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
-        ChunkDecoder decoder = new ChunkDecoder(channel, inbuf, metrics);
+        final SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 256, Consts.ASCII);
+        final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
+        final ChunkDecoder decoder = new ChunkDecoder(channel, inbuf, metrics);
 
-        ByteBuffer dst = ByteBuffer.allocate(1024);
+        final ByteBuffer dst = ByteBuffer.allocate(1024);
 
         int bytesRead = 0;
         while (dst.hasRemaining() && !decoder.isCompleted()) {
-            int i = decoder.read(dst);
+            final int i = decoder.read(dst);
             if (i > 0) {
                 bytesRead += i;
             }
         }
 
         Assert.assertEquals(26, bytesRead);
-        Assert.assertEquals("12345678901234561234512345", convert(dst));
+        Assert.assertEquals("12345678901234561234512345", CodecTestUtils.convert(dst));
         Assert.assertTrue(decoder.isCompleted());
     }
 
     @Test
     public void testInvalidConstructor() {
-        ReadableByteChannel channel = new ReadableByteChannelMock(
-                new String[] {"stuff;", "more stuff"}, "US-ASCII");
-        HttpParams params = new BasicHttpParams();
+        final ReadableByteChannel channel = new ReadableByteChannelMock(
+                new String[] {"stuff;", "more stuff"}, Consts.ASCII);
 
-        SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 256, params);
+        final SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 256, Consts.ASCII);
         try {
             new ChunkDecoder(null, null, null);
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
             // ignore
         }
         try {
             new ChunkDecoder(channel, null, null);
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
             // ignore
         }
         try {
             new ChunkDecoder(channel, inbuf, null);
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
             // ignore
         }
     }
 
     @Test
     public void testInvalidInput() throws Exception {
-        String s = "10;key=\"value\"\r\n1234567890123456\r\n" +
+        final String s = "10;key=\"value\"\r\n1234567890123456\r\n" +
                 "5\r\n12345\r\n5\r\n12345\r\n0\r\nFooter1 abcde\r\n\r\n";
-        ReadableByteChannel channel = new ReadableByteChannelMock(
-                new String[] {s}, "US-ASCII");
-        HttpParams params = new BasicHttpParams();
+        final ReadableByteChannel channel = new ReadableByteChannelMock(
+                new String[] {s}, Consts.ASCII);
 
-        SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 256, params);
-        HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
-        ChunkDecoder decoder = new ChunkDecoder(channel, inbuf, metrics);
+        final SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 256, Consts.ASCII);
+        final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
+        final ChunkDecoder decoder = new ChunkDecoder(channel, inbuf, metrics);
 
         try {
             decoder.read(null);
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
             // expected
         }
     }
diff --git a/httpcore-nio/src/test/java/org/apache/http/impl/nio/codecs/TestChunkEncoder.java b/httpcore-nio/src/test/java/org/apache/http/impl/nio/codecs/TestChunkEncoder.java
index 1e3a1d5..2f17738 100644
--- a/httpcore-nio/src/test/java/org/apache/http/impl/nio/codecs/TestChunkEncoder.java
+++ b/httpcore-nio/src/test/java/org/apache/http/impl/nio/codecs/TestChunkEncoder.java
@@ -27,90 +27,73 @@
 
 package org.apache.http.impl.nio.codecs;
 
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
 import java.nio.ByteBuffer;
-import java.nio.channels.Channels;
-import java.nio.channels.WritableByteChannel;
 
+import org.apache.http.Consts;
+import org.apache.http.WritableByteChannelMock;
 import org.apache.http.impl.io.HttpTransportMetricsImpl;
 import org.apache.http.impl.nio.reactor.SessionOutputBufferImpl;
 import org.apache.http.nio.reactor.SessionOutputBuffer;
-import org.apache.http.params.BasicHttpParams;
-import org.apache.http.params.HttpParams;
-import org.apache.http.util.EncodingUtils;
 import org.junit.Assert;
 import org.junit.Test;
+import org.mockito.Mockito;
 
 /**
  * Simple tests for {@link ChunkEncoder}.
  */
 public class TestChunkEncoder {
 
-    private static ByteBuffer wrap(final String s) {
-        return ByteBuffer.wrap(EncodingUtils.getAsciiBytes(s));
-    }
-
-    private static WritableByteChannel newChannel(final ByteArrayOutputStream baos) {
-        return Channels.newChannel(baos);
-    }
-
     @Test
     public void testBasicCoding() throws Exception {
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        WritableByteChannel channel = newChannel(baos);
-        HttpParams params = new BasicHttpParams();
-        SessionOutputBuffer outbuf = new SessionOutputBufferImpl(1024, 128, params);
-        HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
-        ChunkEncoder encoder = new ChunkEncoder(channel, outbuf, metrics);
-
-        encoder.write(wrap("12345"));
-        encoder.write(wrap("678"));
-        encoder.write(wrap("90"));
+        final WritableByteChannelMock channel = new WritableByteChannelMock(64);
+        final SessionOutputBuffer outbuf = new SessionOutputBufferImpl(1024, 128);
+        final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
+        final ChunkEncoder encoder = new ChunkEncoder(channel, outbuf, metrics);
+
+        encoder.write(CodecTestUtils.wrap("12345"));
+        encoder.write(CodecTestUtils.wrap("678"));
+        encoder.write(CodecTestUtils.wrap("90"));
         encoder.complete();
 
         outbuf.flush(channel);
 
-        String s = baos.toString("US-ASCII");
+        final String s = channel.dump(Consts.ASCII);
 
         Assert.assertTrue(encoder.isCompleted());
         Assert.assertEquals("5\r\n12345\r\n3\r\n678\r\n2\r\n90\r\n0\r\n\r\n", s);
+        Assert.assertEquals("[chunk-coded; completed: true]", encoder.toString());
     }
 
     @Test
     public void testChunkNoExceed() throws Exception {
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        WritableByteChannel channel = newChannel(baos);
-        HttpParams params = new BasicHttpParams();
-        SessionOutputBuffer outbuf = new SessionOutputBufferImpl(1024, 16, params);
-        HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
-        ChunkEncoder encoder = new ChunkEncoder(channel, outbuf, metrics);
-        encoder.write(wrap("1234"));
+        final WritableByteChannelMock channel = new WritableByteChannelMock(64);
+        final SessionOutputBuffer outbuf = new SessionOutputBufferImpl(1024, 16);
+        final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
+        final ChunkEncoder encoder = new ChunkEncoder(channel, outbuf, metrics);
+        encoder.write(CodecTestUtils.wrap("1234"));
         encoder.complete();
 
         outbuf.flush(channel);
 
-        String s = baos.toString("US-ASCII");
+        final String s = channel.dump(Consts.ASCII);
 
         Assert.assertTrue(encoder.isCompleted());
         Assert.assertEquals("4\r\n1234\r\n0\r\n\r\n", s);
     }
 
-    @Test
-    public void testHttpCore239() throws Exception {
-        FixedByteChannel channel = new FixedByteChannel(16);
-        HttpParams params = new BasicHttpParams();
-        SessionOutputBuffer outbuf = new SessionOutputBufferImpl(16, 16, params);
-        HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
-        ChunkEncoder encoder = new ChunkEncoder(channel, outbuf, metrics);
+    @Test // See HTTPCORE-239
+    public void testLimitedChannel() throws Exception {
+        final WritableByteChannelMock channel = new WritableByteChannelMock(16, 16);
+        final SessionOutputBuffer outbuf = new SessionOutputBufferImpl(16, 16);
+        final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
+        final ChunkEncoder encoder = new ChunkEncoder(channel, outbuf, metrics);
 
         // fill up the channel
-        channel.write(wrap("0123456789ABCDEF"));
+        channel.write(CodecTestUtils.wrap("0123456789ABCDEF"));
         // fill up the out buffer
-        outbuf.write(wrap("0123456789ABCDEF"));
+        outbuf.write(CodecTestUtils.wrap("0123456789ABCDEF"));
 
-        ByteBuffer src = wrap("0123456789ABCDEF");
+        final ByteBuffer src = CodecTestUtils.wrap("0123456789ABCDEF");
         Assert.assertEquals(0, encoder.write(src));
         Assert.assertEquals(0, encoder.write(src));
         Assert.assertEquals(0, encoder.write(src));
@@ -120,64 +103,66 @@ public class TestChunkEncoder {
         outbuf.flush(channel);
         channel.reset();
 
-        Assert.assertEquals(4, encoder.write(src));
+        Assert.assertEquals(10, encoder.write(src));
         channel.flush();
-        Assert.assertEquals(4, encoder.write(src));
-        channel.flush();
-        Assert.assertEquals(4, encoder.write(src));
-        channel.flush();
-        Assert.assertEquals(4, encoder.write(src));
+        Assert.assertEquals(6, encoder.write(src));
         channel.flush();
         Assert.assertEquals(0, encoder.write(src));
 
         outbuf.flush(channel);
-        String s = channel.toString("US-ASCII");
-        Assert.assertEquals("4\r\n0123\r\n4\r\n4567\r\n4\r\n89AB\r\n4\r\nCDEF\r\n", s);
+        final String s = channel.dump(Consts.ASCII);
+        Assert.assertEquals("4\r\n0123\r\n4\r\n4567\r\n2\r\n89\r\n4\r\nABCD\r\n2\r\nEF\r\n", s);
     }
 
     @Test
-    public void testChunkExceed() throws Exception {
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        WritableByteChannel channel = newChannel(baos);
-        HttpParams params = new BasicHttpParams();
-        SessionOutputBuffer outbuf = new SessionOutputBufferImpl(16, 16, params);
-        HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
-        ChunkEncoder encoder = new ChunkEncoder(channel, outbuf, metrics);
+    public void testBufferFragments() throws Exception {
+        final WritableByteChannelMock channel = Mockito.spy(new WritableByteChannelMock(1024));
+        final SessionOutputBuffer outbuf = new SessionOutputBufferImpl(1024, 1024);
+        final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
+        final ChunkEncoder encoder = new ChunkEncoder(channel, outbuf, metrics, 1024);
 
-        ByteBuffer src = wrap("0123456789ABCDEF");
+        Assert.assertEquals(16, encoder.write(CodecTestUtils.wrap("0123456789ABCDEF")));
+        Assert.assertEquals(16, encoder.write(CodecTestUtils.wrap("0123456789ABCDEF")));
+        Assert.assertEquals(16, encoder.write(CodecTestUtils.wrap("0123456789ABCDEF")));
 
-        Assert.assertEquals(4, encoder.write(src));
-        Assert.assertTrue(src.hasRemaining());
-        Assert.assertEquals(12, src.remaining());
+        Mockito.verify(channel, Mockito.never()).write(Mockito.<ByteBuffer>any());
 
-        Assert.assertEquals(4, encoder.write(src));
-        Assert.assertTrue(src.hasRemaining());
-        Assert.assertEquals(8, src.remaining());
+        outbuf.flush(channel);
+        final String s = channel.dump(Consts.ASCII);
+        Assert.assertEquals("10\r\n0123456789ABCDEF\r\n10\r\n0123456789ABCDEF\r\n" +
+                "10\r\n0123456789ABCDEF\r\n", s);
+    }
+
+    @Test
+    public void testChunkExceed() throws Exception {
+        final WritableByteChannelMock channel = new WritableByteChannelMock(64);
+        final SessionOutputBuffer outbuf = new SessionOutputBufferImpl(16, 16);
+        final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
+        final ChunkEncoder encoder = new ChunkEncoder(channel, outbuf, metrics);
+
+        final ByteBuffer src = CodecTestUtils.wrap("0123456789ABCDEF");
 
-        Assert.assertEquals(4, encoder.write(src));
-        Assert.assertEquals(4, encoder.write(src));
-        Assert.assertFalse(src.hasRemaining());
+        Assert.assertEquals(16, encoder.write(src));
+        Assert.assertEquals(0, src.remaining());
 
         outbuf.flush(channel);
-        String s = baos.toString("US-ASCII");
+        final String s = channel.dump(Consts.ASCII);
         Assert.assertEquals("4\r\n0123\r\n4\r\n4567\r\n4\r\n89AB\r\n4\r\nCDEF\r\n", s);
 
     }
 
     @Test
     public void testCodingEmptyBuffer() throws Exception {
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        WritableByteChannel channel = newChannel(baos);
-        HttpParams params = new BasicHttpParams();
-        SessionOutputBuffer outbuf = new SessionOutputBufferImpl(1024, 128, params);
-        HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
-        ChunkEncoder encoder = new ChunkEncoder(channel, outbuf, metrics);
-
-        encoder.write(wrap("12345"));
-        encoder.write(wrap("678"));
-        encoder.write(wrap("90"));
-
-        ByteBuffer empty = ByteBuffer.allocate(100);
+        final WritableByteChannelMock channel = new WritableByteChannelMock(64);
+        final SessionOutputBuffer outbuf = new SessionOutputBufferImpl(1024, 128);
+        final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
+        final ChunkEncoder encoder = new ChunkEncoder(channel, outbuf, metrics);
+
+        encoder.write(CodecTestUtils.wrap("12345"));
+        encoder.write(CodecTestUtils.wrap("678"));
+        encoder.write(CodecTestUtils.wrap("90"));
+
+        final ByteBuffer empty = ByteBuffer.allocate(100);
         empty.flip();
         encoder.write(empty);
         encoder.write(null);
@@ -186,7 +171,7 @@ public class TestChunkEncoder {
 
         outbuf.flush(channel);
 
-        String s = baos.toString("US-ASCII");
+        final String s = channel.dump(Consts.ASCII);
 
         Assert.assertTrue(encoder.isCompleted());
         Assert.assertEquals("5\r\n12345\r\n3\r\n678\r\n2\r\n90\r\n0\r\n\r\n", s);
@@ -194,103 +179,53 @@ public class TestChunkEncoder {
 
     @Test
     public void testCodingCompleted() throws Exception {
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        WritableByteChannel channel = newChannel(baos);
-        HttpParams params = new BasicHttpParams();
-        SessionOutputBuffer outbuf = new SessionOutputBufferImpl(1024, 128, params);
-        HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
-        ChunkEncoder encoder = new ChunkEncoder(channel, outbuf, metrics);
-
-        encoder.write(wrap("12345"));
-        encoder.write(wrap("678"));
-        encoder.write(wrap("90"));
+        final WritableByteChannelMock channel = new WritableByteChannelMock(64);
+        final SessionOutputBuffer outbuf = new SessionOutputBufferImpl(1024, 128);
+        final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
+        final ChunkEncoder encoder = new ChunkEncoder(channel, outbuf, metrics);
+
+        encoder.write(CodecTestUtils.wrap("12345"));
+        encoder.write(CodecTestUtils.wrap("678"));
+        encoder.write(CodecTestUtils.wrap("90"));
         encoder.complete();
 
         try {
-            encoder.write(wrap("more stuff"));
+            encoder.write(CodecTestUtils.wrap("more stuff"));
             Assert.fail("IllegalStateException should have been thrown");
-        } catch (IllegalStateException ex) {
+        } catch (final IllegalStateException ex) {
             // ignore
         }
         try {
             encoder.complete();
             Assert.fail("IllegalStateException should have been thrown");
-        } catch (IllegalStateException ex) {
+        } catch (final IllegalStateException ex) {
             // ignore
         }
     }
 
     @Test
     public void testInvalidConstructor() {
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        WritableByteChannel channel = newChannel(baos);
-        HttpParams params = new BasicHttpParams();
-        SessionOutputBuffer outbuf = new SessionOutputBufferImpl(1024, 128, params);
+        final WritableByteChannelMock channel = new WritableByteChannelMock(64);
+        final SessionOutputBuffer outbuf = new SessionOutputBufferImpl(1024, 128);
 
         try {
             new ChunkEncoder(null, null, null);
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
             // ignore
         }
         try {
             new ChunkEncoder(channel, null, null);
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
             // ignore
         }
         try {
             new ChunkEncoder(channel, outbuf, null);
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
             // ignore
         }
     }
 
-    public class FixedByteChannel implements WritableByteChannel {
-
-        // collect bytes written for unit test result evaluation
-        private final ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        private final ByteBuffer buffer;
-
-        public FixedByteChannel(int size) {
-            this.buffer = ByteBuffer.allocate(size);
-        }
-
-        public int write(ByteBuffer src) throws IOException {
-            // copy bytes into baos for result evaluation
-            final int start = src.position();
-            int count = 0;
-            for (int i=start; i<src.limit() && buffer.remaining() > 0; i++) {
-                final byte b = src.get(i);
-                baos.write(b);
-                buffer.put(b);
-                count++;
-            }
-            // update processed position on src buffer
-            src.position(src.position() + count);
-            return count;
-        }
-
-        public boolean isOpen() {
-            return false;
-        }
-
-        public void close() throws IOException {
-        }
-
-        public void flush() {
-            buffer.clear();
-        }
-
-        public void reset() {
-            baos.reset();
-            buffer.clear();
-        }
-
-        public String toString(String encoding) throws UnsupportedEncodingException {
-            return baos.toString(encoding);
-        }
-    }
-
 }
diff --git a/httpcore-nio/src/test/java/org/apache/http/impl/nio/codecs/TestHttpMessageParser.java b/httpcore-nio/src/test/java/org/apache/http/impl/nio/codecs/TestHttpMessageParser.java
index 2d13569..b7bfa17 100644
--- a/httpcore-nio/src/test/java/org/apache/http/impl/nio/codecs/TestHttpMessageParser.java
+++ b/httpcore-nio/src/test/java/org/apache/http/impl/nio/codecs/TestHttpMessageParser.java
@@ -33,20 +33,15 @@ import java.io.UnsupportedEncodingException;
 import java.nio.channels.Channels;
 import java.nio.channels.ReadableByteChannel;
 
+import org.apache.http.Consts;
 import org.apache.http.HttpException;
 import org.apache.http.HttpRequest;
-import org.apache.http.HttpRequestFactory;
 import org.apache.http.HttpResponse;
-import org.apache.http.HttpResponseFactory;
 import org.apache.http.HttpVersion;
-import org.apache.http.impl.DefaultHttpRequestFactory;
-import org.apache.http.impl.DefaultHttpResponseFactory;
+import org.apache.http.config.MessageConstraints;
 import org.apache.http.impl.nio.reactor.SessionInputBufferImpl;
 import org.apache.http.nio.NHttpMessageParser;
 import org.apache.http.nio.reactor.SessionInputBuffer;
-import org.apache.http.params.BasicHttpParams;
-import org.apache.http.params.CoreConnectionPNames;
-import org.apache.http.params.HttpParams;
 import org.junit.Assert;
 import org.junit.Test;
 
@@ -67,12 +62,10 @@ public class TestHttpMessageParser {
 
     @Test
     public void testSimpleParsing() throws Exception {
-        HttpParams params = new BasicHttpParams();
-        SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 128, params);
-        HttpRequestFactory requestFactory = new DefaultHttpRequestFactory();
-        NHttpMessageParser<HttpRequest> requestParser = new DefaultHttpRequestParser(inbuf, null, requestFactory, params);
+        final SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 128, Consts.ASCII);
+        final NHttpMessageParser<HttpRequest> requestParser = new DefaultHttpRequestParser(inbuf);
         requestParser.fillBuffer(newChannel("GET /whatever HTTP/1.1\r\nSome header: stuff\r\n\r\n"));
-        HttpRequest request = requestParser.parse();
+        final HttpRequest request = requestParser.parse();
         Assert.assertNotNull(request);
         Assert.assertEquals("/whatever", request.getRequestLine().getUri());
         Assert.assertEquals(1, request.getAllHeaders().length);
@@ -80,10 +73,8 @@ public class TestHttpMessageParser {
 
     @Test
     public void testParsingChunkedMessages() throws Exception {
-        HttpParams params = new BasicHttpParams();
-        SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 128, params);
-        HttpRequestFactory requestFactory = new DefaultHttpRequestFactory();
-        NHttpMessageParser<HttpRequest> requestParser = new DefaultHttpRequestParser(inbuf, null, requestFactory, params);
+        final SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 128, Consts.ASCII);
+        final NHttpMessageParser<HttpRequest> requestParser = new DefaultHttpRequestParser(inbuf);
 
         requestParser.fillBuffer(newChannel("GET /whatev"));
         HttpRequest request = requestParser.parse();
@@ -102,10 +93,8 @@ public class TestHttpMessageParser {
 
     @Test
     public void testParsingFoldedHeaders() throws Exception {
-        HttpParams params = new BasicHttpParams();
-        SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 128, params);
-        HttpRequestFactory requestFactory = new DefaultHttpRequestFactory();
-        NHttpMessageParser<HttpRequest> requestParser = new DefaultHttpRequestParser(inbuf, null, requestFactory, params);
+        final SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 128, Consts.ASCII);
+        final NHttpMessageParser<HttpRequest> requestParser = new DefaultHttpRequestParser(inbuf);
 
         requestParser.fillBuffer(newChannel("GET /whatev"));
         HttpRequest request = requestParser.parse();
@@ -133,10 +122,8 @@ public class TestHttpMessageParser {
 
     @Test
     public void testParsingBadlyFoldedFirstHeader() throws Exception {
-        HttpParams params = new BasicHttpParams();
-        SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 128, params);
-        HttpRequestFactory requestFactory = new DefaultHttpRequestFactory();
-        NHttpMessageParser<HttpRequest> requestParser = new DefaultHttpRequestParser(inbuf, null, requestFactory, params);
+        final SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 128, Consts.ASCII);
+        final NHttpMessageParser<HttpRequest> requestParser = new DefaultHttpRequestParser(inbuf);
 
         requestParser.fillBuffer(newChannel("GET /whatev"));
         HttpRequest request = requestParser.parse();
@@ -161,10 +148,8 @@ public class TestHttpMessageParser {
 
     @Test
     public void testParsingEmptyFoldedHeader() throws Exception {
-        HttpParams params = new BasicHttpParams();
-        SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 128, params);
-        HttpRequestFactory requestFactory = new DefaultHttpRequestFactory();
-        NHttpMessageParser<HttpRequest> requestParser = new DefaultHttpRequestParser(inbuf, null, requestFactory, params);
+        final SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 128, Consts.ASCII);
+        final NHttpMessageParser<HttpRequest> requestParser = new DefaultHttpRequestParser(inbuf);
 
         requestParser.fillBuffer(newChannel("GET /whatev"));
         HttpRequest request = requestParser.parse();
@@ -192,30 +177,26 @@ public class TestHttpMessageParser {
 
     @Test
     public void testParsingIncompleteRequestLine() throws Exception {
-        HttpParams params = new BasicHttpParams();
-        SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 128, params);
-        HttpRequestFactory requestFactory = new DefaultHttpRequestFactory();
-        NHttpMessageParser<HttpRequest> requestParser = new DefaultHttpRequestParser(inbuf, null, requestFactory, params);
+        final SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 128, Consts.ASCII);
+        final NHttpMessageParser<HttpRequest> requestParser = new DefaultHttpRequestParser(inbuf);
 
-        ReadableByteChannel channel = newChannel("GET /whatever HTTP/1.0");
+        final ReadableByteChannel channel = newChannel("GET /whatever HTTP/1.0");
         requestParser.fillBuffer(channel);
         requestParser.fillBuffer(channel);
-        HttpRequest request = requestParser.parse();
+        final HttpRequest request = requestParser.parse();
         Assert.assertNotNull(request);
         Assert.assertEquals(HttpVersion.HTTP_1_0, request.getRequestLine().getProtocolVersion());
     }
 
     @Test
     public void testParsingIncompleteHeader() throws Exception {
-        HttpParams params = new BasicHttpParams();
-        SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 128, params);
-        HttpRequestFactory requestFactory = new DefaultHttpRequestFactory();
-        NHttpMessageParser<HttpRequest> requestParser = new DefaultHttpRequestParser(inbuf, null, requestFactory, params);
+        final SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 128, Consts.ASCII);
+        final NHttpMessageParser<HttpRequest> requestParser = new DefaultHttpRequestParser(inbuf);
 
-        ReadableByteChannel channel = newChannel("GET /whatever HTTP/1.0\r\nHeader: whatever");
+        final ReadableByteChannel channel = newChannel("GET /whatever HTTP/1.0\r\nHeader: whatever");
         requestParser.fillBuffer(channel);
         requestParser.fillBuffer(channel);
-        HttpRequest request = requestParser.parse();
+        final HttpRequest request = requestParser.parse();
         Assert.assertNotNull(request);
         Assert.assertEquals(1, request.getAllHeaders().length);
         Assert.assertEquals("whatever", request.getFirstHeader("Header").getValue());
@@ -223,61 +204,53 @@ public class TestHttpMessageParser {
 
     @Test
     public void testParsingInvalidRequestLine() throws Exception {
-        HttpParams params = new BasicHttpParams();
-        SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 128, params);
-        HttpRequestFactory requestFactory = new DefaultHttpRequestFactory();
-        NHttpMessageParser<HttpRequest> requestParser = new DefaultHttpRequestParser(inbuf, null, requestFactory, params);
+        final SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 128, Consts.ASCII);
+        final NHttpMessageParser<HttpRequest> requestParser = new DefaultHttpRequestParser(inbuf);
 
-        ReadableByteChannel channel = newChannel("GET garbage\r\n");
+        final ReadableByteChannel channel = newChannel("GET garbage\r\n");
         requestParser.fillBuffer(channel);
         try {
             requestParser.parse();
             Assert.fail("HttpException should have been thrown");
-        } catch (HttpException ex) {
+        } catch (final HttpException ex) {
             // expected
         }
     }
 
     @Test
     public void testParsingInvalidStatusLine() throws Exception {
-        HttpParams params = new BasicHttpParams();
-        SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 128, params);
-        HttpResponseFactory responseFactory = new DefaultHttpResponseFactory();
-        NHttpMessageParser<HttpResponse> responseParser = new DefaultHttpResponseParser(inbuf, null, responseFactory, params);
+        final SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 128, Consts.ASCII);
+        final NHttpMessageParser<HttpResponse> responseParser = new DefaultHttpResponseParser(inbuf);
 
-        ReadableByteChannel channel = newChannel("HTTP 200 OK\r\n");
+        final ReadableByteChannel channel = newChannel("HTTP 200 OK\r\n");
         responseParser.fillBuffer(channel);
         try {
             responseParser.parse();
             Assert.fail("HttpException should have been thrown");
-        } catch (HttpException ex) {
+        } catch (final HttpException ex) {
             // expected
         }
     }
 
     @Test
     public void testParsingInvalidHeader() throws Exception {
-        HttpParams params = new BasicHttpParams();
-        SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 128, params);
-        HttpResponseFactory responseFactory = new DefaultHttpResponseFactory();
-        NHttpMessageParser<HttpResponse> responseParser = new DefaultHttpResponseParser(inbuf, null, responseFactory, params);
+        final SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 128, Consts.ASCII);
+        final NHttpMessageParser<HttpResponse> responseParser = new DefaultHttpResponseParser(inbuf);
 
-        ReadableByteChannel channel = newChannel("HTTP/1.0 200 OK\r\nstuff\r\n\r\n");
+        final ReadableByteChannel channel = newChannel("HTTP/1.0 200 OK\r\nstuff\r\n\r\n");
         responseParser.fillBuffer(channel);
         try {
             responseParser.parse();
             Assert.fail("HttpException should have been thrown");
-        } catch (HttpException ex) {
+        } catch (final HttpException ex) {
             // expected
         }
     }
 
     @Test
     public void testResetParser() throws Exception {
-        HttpParams params = new BasicHttpParams();
-        SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 128, params);
-        HttpRequestFactory requestFactory = new DefaultHttpRequestFactory();
-        NHttpMessageParser<HttpRequest> requestParser = new DefaultHttpRequestParser(inbuf, null, requestFactory, params);
+        final SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 128, Consts.ASCII);
+        final NHttpMessageParser<HttpRequest> requestParser = new DefaultHttpRequestParser(inbuf);
 
         ReadableByteChannel channel = newChannel("GET /whatever HTTP/1.0\r\nHeader: one\r\n\r\n");
         requestParser.fillBuffer(channel);
@@ -298,70 +271,43 @@ public class TestHttpMessageParser {
 
     @Test
     public void testInvalidConstructor() {
-        HttpParams params = new BasicHttpParams();
-        SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 128, params);
-        try {
-            new DefaultHttpRequestParser(null, null, null, params);
-            Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
-            // ignore
-        }
-        try {
-            new DefaultHttpRequestParser(inbuf, null, null, params);
-            Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
-            // ignore
-        }
-        try {
-            new DefaultHttpResponseParser(null, null, null, params);
-            Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
-            // ignore
-        }
         try {
-            new DefaultHttpResponseParser(inbuf, null, null, params);
+            new DefaultHttpRequestParser(null);
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
             // ignore
         }
     }
 
     @Test
     public void testLineLimitForStatus() throws Exception {
-        HttpParams params = new BasicHttpParams();
-        SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 128, params);
-        HttpRequestFactory requestFactory = new DefaultHttpRequestFactory();
-
-        params.setIntParameter(CoreConnectionPNames.MAX_LINE_LENGTH, 0);
-        NHttpMessageParser<HttpRequest> requestParser = new DefaultHttpRequestParser(inbuf, null, requestFactory, params);
+        final SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 128, Consts.ASCII);
+        NHttpMessageParser<HttpRequest> requestParser = new DefaultHttpRequestParser(inbuf,
+                MessageConstraints.lineLen(0));
         requestParser.fillBuffer(newChannel("GET /whatever HTTP/1.0\r\nHeader: one\r\n\r\n"));
         requestParser.parse();
         requestParser.reset();
 
-        params.setIntParameter(CoreConnectionPNames.MAX_LINE_LENGTH, 15);
-        requestParser = new DefaultHttpRequestParser(inbuf, null, requestFactory, params);
+        requestParser = new DefaultHttpRequestParser(inbuf, MessageConstraints.lineLen(15));
         try {
             requestParser.fillBuffer(newChannel("GET /loooooooooooooooong HTTP/1.0\r\nHeader: one\r\n\r\n"));
             requestParser.parse();
             Assert.fail("IOException should have been thrown");
-        } catch (IOException expected) {
+        } catch (final IOException expected) {
         }
     }
 
     @Test
     public void testLineLimitForHeader() throws Exception {
-        HttpParams params = new BasicHttpParams();
-        SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 128, params);
-        HttpRequestFactory requestFactory = new DefaultHttpRequestFactory();
+        final SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 128, Consts.ASCII);
 
-        params.setIntParameter(CoreConnectionPNames.MAX_LINE_LENGTH, 0);
-        NHttpMessageParser<HttpRequest> requestParser = new DefaultHttpRequestParser(inbuf, null, requestFactory, params);
+        NHttpMessageParser<HttpRequest> requestParser = new DefaultHttpRequestParser(inbuf,
+                MessageConstraints.lineLen(0));
         requestParser.fillBuffer(newChannel("GET /whatever HTTP/1.0\r\nHeader: one\r\n\r\n"));
         requestParser.parse();
         requestParser.reset();
 
-        params.setIntParameter(CoreConnectionPNames.MAX_LINE_LENGTH, 15);
-        requestParser = new DefaultHttpRequestParser(inbuf, null, requestFactory, params);
+        requestParser = new DefaultHttpRequestParser(inbuf, MessageConstraints.lineLen(15));
         requestParser.fillBuffer(newChannel("GET / HTTP/1.0\r\nHeader: 9012345\r\n\r\n"));
         requestParser.parse();
         requestParser.reset();
@@ -369,63 +315,60 @@ public class TestHttpMessageParser {
             requestParser.fillBuffer(newChannel("GET / HTTP/1.0\r\nHeader: 90123456\r\n\r\n"));
             requestParser.parse();
             Assert.fail("IOException should have been thrown");
-        } catch (IOException expected) {
+        } catch (final IOException expected) {
         }
     }
 
     @Test
     public void testLineLimitForFoldedHeader() throws Exception {
-        HttpParams params = new BasicHttpParams();
-        SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 128, params);
-        HttpRequestFactory requestFactory = new DefaultHttpRequestFactory();
+        final SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 128, Consts.ASCII);
 
-        params.setIntParameter(CoreConnectionPNames.MAX_HEADER_COUNT, 2);
-        params.setIntParameter(CoreConnectionPNames.MAX_LINE_LENGTH, 15);
-        NHttpMessageParser<HttpRequest> requestParser = new DefaultHttpRequestParser(inbuf, null, requestFactory, params);
+        final MessageConstraints constraints = MessageConstraints.custom()
+                .setMaxHeaderCount(2).setMaxLineLength(15).build();
+        final NHttpMessageParser<HttpRequest> requestParser = new DefaultHttpRequestParser(inbuf, constraints);
         try {
-            requestParser.fillBuffer(newChannel("GET / HTTP/1.0\r\nHeader: 9012345\r\n 23456789012345\r\n 23456789012345\r\n 23456789012345\r\n\r\n"));
+            requestParser.fillBuffer(newChannel("GET / HTTP/1.0\r\nHeader: 9012345\r\n" +
+                    " 23456789012345\r\n 23456789012345\r\n 23456789012345\r\n\r\n"));
             requestParser.parse();
             Assert.fail("IOException should have been thrown");
-        } catch (IOException expected) {
+        } catch (final IOException expected) {
         }
     }
 
     @Test
     public void testMaxHeaderCount() throws Exception {
-        HttpParams params = new BasicHttpParams();
-        SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 128, params);
-        HttpRequestFactory requestFactory = new DefaultHttpRequestFactory();
+        final SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 128, Consts.ASCII);
 
-        params.setIntParameter(CoreConnectionPNames.MAX_HEADER_COUNT, 2);
-        NHttpMessageParser<HttpRequest> requestParser = new DefaultHttpRequestParser(inbuf, null, requestFactory, params);
+        final MessageConstraints constraints = MessageConstraints.custom()
+                .setMaxHeaderCount(2).setMaxLineLength(-1).build();
+        final NHttpMessageParser<HttpRequest> requestParser = new DefaultHttpRequestParser(inbuf, constraints);
         requestParser.fillBuffer(newChannel("GET /whatever HTTP/1.0\r\nHeader: one\r\nHeader: two\r\n\r\n"));
         requestParser.parse();
         requestParser.reset();
 
         try {
-            requestParser.fillBuffer(newChannel("GET /whatever HTTP/1.0\r\nHeader: one\r\nHeader: two\r\nHeader: three\r\n\r\n"));
+            requestParser.fillBuffer(newChannel("GET /whatever HTTP/1.0\r\nHeader: one\r\n" +
+                    "Header: two\r\nHeader: three\r\n\r\n"));
             requestParser.parse();
             Assert.fail("IOException should have been thrown");
-        } catch (IOException expected) {
+        } catch (final IOException expected) {
         }
     }
 
     @Test
     public void testDetectLineLimitEarly() throws Exception {
-        HttpParams params = new BasicHttpParams();
-        SessionInputBuffer inbuf = new SessionInputBufferImpl(2, 128, params);
-        HttpRequestFactory requestFactory = new DefaultHttpRequestFactory();
+        final SessionInputBuffer inbuf = new SessionInputBufferImpl(2, 128, Consts.ASCII);
 
-        params.setIntParameter(CoreConnectionPNames.MAX_LINE_LENGTH, 2);
-        NHttpMessageParser<HttpRequest> requestParser = new DefaultHttpRequestParser(inbuf, null, requestFactory, params);
-        ReadableByteChannel channel = newChannel("GET / HTTP/1.0\r\nHeader: one\r\n\r\n");
+        final NHttpMessageParser<HttpRequest> requestParser = new DefaultHttpRequestParser(inbuf,
+                MessageConstraints.lineLen(2));
+        final ReadableByteChannel channel = newChannel("GET / HTTP/1.0\r\nHeader: one\r\n\r\n");
         Assert.assertEquals(2, requestParser.fillBuffer(channel));
         Assert.assertNull(requestParser.parse());
         Assert.assertEquals(4, requestParser.fillBuffer(channel));
         try {
             requestParser.parse();
             Assert.fail("IOException should have been thrown");
-        } catch (IOException expected) {
+        } catch (final IOException expected) {
         }
     }
 
diff --git a/httpcore-nio/src/test/java/org/apache/http/impl/nio/codecs/TestIdentityDecoder.java b/httpcore-nio/src/test/java/org/apache/http/impl/nio/codecs/TestIdentityDecoder.java
index 2ede52d..4de51a1 100644
--- a/httpcore-nio/src/test/java/org/apache/http/impl/nio/codecs/TestIdentityDecoder.java
+++ b/httpcore-nio/src/test/java/org/apache/http/impl/nio/codecs/TestIdentityDecoder.java
@@ -28,20 +28,19 @@
 package org.apache.http.impl.nio.codecs;
 
 import java.io.File;
-import java.io.FileInputStream;
 import java.io.IOException;
-import java.io.InputStreamReader;
 import java.io.RandomAccessFile;
 import java.nio.ByteBuffer;
 import java.nio.channels.FileChannel;
 import java.nio.channels.ReadableByteChannel;
 
+import org.apache.http.Consts;
 import org.apache.http.ReadableByteChannelMock;
 import org.apache.http.impl.io.HttpTransportMetricsImpl;
 import org.apache.http.impl.nio.reactor.SessionInputBufferImpl;
 import org.apache.http.nio.reactor.SessionInputBuffer;
-import org.apache.http.params.BasicHttpParams;
-import org.apache.http.params.HttpParams;
+import org.apache.http.util.EncodingUtils;
+import org.junit.After;
 import org.junit.Assert;
 import org.junit.Test;
 
@@ -50,53 +49,41 @@ import org.junit.Test;
  */
 public class TestIdentityDecoder {
 
-    private static String convert(final ByteBuffer src) {
-        src.flip();
-        StringBuilder buffer = new StringBuilder(src.remaining());
-        while (src.hasRemaining()) {
-            buffer.append((char)(src.get() & 0xff));
-        }
-        return buffer.toString();
+    private File tmpfile;
+
+    protected File createTempFile() throws IOException {
+        this.tmpfile = File.createTempFile("testFile", ".txt");
+        return this.tmpfile;
     }
 
-    private static String readFromFile(final File file) throws Exception {
-        FileInputStream filestream = new FileInputStream(file);
-        InputStreamReader reader = new InputStreamReader(filestream);
-        try {
-            StringBuilder buffer = new StringBuilder();
-            char[] tmp = new char[2048];
-            int l;
-            while ((l = reader.read(tmp)) != -1) {
-                buffer.append(tmp, 0, l);
-            }
-            return buffer.toString();
-        } finally {
-            reader.close();
+    @After
+    public void deleteTempFile() {
+        if (this.tmpfile != null && this.tmpfile.exists()) {
+            this.tmpfile.delete();
         }
     }
 
     @Test
     public void testBasicDecoding() throws Exception {
-        ReadableByteChannel channel = new ReadableByteChannelMock(
-                new String[] {"stuff;", "more stuff"}, "US-ASCII");
-        HttpParams params = new BasicHttpParams();
+        final ReadableByteChannel channel = new ReadableByteChannelMock(
+                new String[] {"stuff;", "more stuff"}, Consts.ASCII);
 
-        SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 256, params);
-        HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
-        IdentityDecoder decoder = new IdentityDecoder(channel, inbuf, metrics);
+        final SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 256, Consts.ASCII);
+        final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
+        final IdentityDecoder decoder = new IdentityDecoder(channel, inbuf, metrics);
 
-        ByteBuffer dst = ByteBuffer.allocate(1024);
+        final ByteBuffer dst = ByteBuffer.allocate(1024);
 
         int bytesRead = decoder.read(dst);
         Assert.assertEquals(6, bytesRead);
-        Assert.assertEquals("stuff;", convert(dst));
+        Assert.assertEquals("stuff;", CodecTestUtils.convert(dst));
         Assert.assertFalse(decoder.isCompleted());
         Assert.assertEquals(6, metrics.getBytesTransferred());
 
         dst.clear();
         bytesRead = decoder.read(dst);
         Assert.assertEquals(10, bytesRead);
-        Assert.assertEquals("more stuff", convert(dst));
+        Assert.assertEquals("more stuff", CodecTestUtils.convert(dst));
         Assert.assertFalse(decoder.isCompleted());
         Assert.assertEquals(16, metrics.getBytesTransferred());
 
@@ -111,35 +98,36 @@ public class TestIdentityDecoder {
         Assert.assertEquals(-1, bytesRead);
         Assert.assertTrue(decoder.isCompleted());
         Assert.assertEquals(16, metrics.getBytesTransferred());
+
+        Assert.assertEquals("[identity; completed: true]", decoder.toString());
     }
 
     @Test
     public void testDecodingFromSessionBuffer() throws Exception {
-        ReadableByteChannel channel = new ReadableByteChannelMock(
-                new String[] {"stuff;", "more stuff"}, "US-ASCII");
-        HttpParams params = new BasicHttpParams();
+        final ReadableByteChannel channel = new ReadableByteChannelMock(
+                new String[] {"stuff;", "more stuff"}, Consts.ASCII);
 
-        SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 256, params);
-        HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
+        final SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 256, Consts.ASCII);
+        final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
 
         inbuf.fill(channel);
 
         Assert.assertEquals(6, inbuf.length());
 
-        IdentityDecoder decoder = new IdentityDecoder(channel, inbuf, metrics);
+        final IdentityDecoder decoder = new IdentityDecoder(channel, inbuf, metrics);
 
-        ByteBuffer dst = ByteBuffer.allocate(1024);
+        final ByteBuffer dst = ByteBuffer.allocate(1024);
 
         int bytesRead = decoder.read(dst);
         Assert.assertEquals(6, bytesRead);
-        Assert.assertEquals("stuff;", convert(dst));
+        Assert.assertEquals("stuff;", CodecTestUtils.convert(dst));
         Assert.assertFalse(decoder.isCompleted());
         Assert.assertEquals(0, metrics.getBytesTransferred()); // doesn't count if from session buffer
 
         dst.clear();
         bytesRead = decoder.read(dst);
         Assert.assertEquals(10, bytesRead);
-        Assert.assertEquals("more stuff", convert(dst));
+        Assert.assertEquals("more stuff", CodecTestUtils.convert(dst));
         Assert.assertFalse(decoder.isCompleted());
         Assert.assertEquals(10, metrics.getBytesTransferred());
 
@@ -159,189 +147,179 @@ public class TestIdentityDecoder {
 
     @Test
     public void testBasicDecodingFile() throws Exception {
-        ReadableByteChannel channel = new ReadableByteChannelMock(
-                new String[] {"stuff; ", "more stuff; ", "a lot more stuff!"}, "US-ASCII");
-        HttpParams params = new BasicHttpParams();
+        final ReadableByteChannel channel = new ReadableByteChannelMock(
+                new String[] {"stuff; ", "more stuff; ", "a lot more stuff!"}, Consts.ASCII);
 
-        SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 256, params);
-        HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
-        IdentityDecoder decoder = new IdentityDecoder(
+        final SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 256, Consts.ASCII);
+        final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
+        final IdentityDecoder decoder = new IdentityDecoder(
                 channel, inbuf, metrics);
 
-        File fileHandle = File.createTempFile("testFile", ".txt");
-
-        RandomAccessFile testfile = new RandomAccessFile(fileHandle, "rw");
-        FileChannel fchannel = testfile.getChannel();
-
-        long pos = 0;
-        while (!decoder.isCompleted()) {
-            long bytesRead = decoder.transfer(fchannel, pos, 10);
-            if (bytesRead > 0) {
-                pos += bytesRead;
+        createTempFile();
+        final RandomAccessFile testfile = new RandomAccessFile(this.tmpfile, "rw");
+        try {
+            final FileChannel fchannel = testfile.getChannel();
+            long pos = 0;
+            while (!decoder.isCompleted()) {
+                final long bytesRead = decoder.transfer(fchannel, pos, 10);
+                if (bytesRead > 0) {
+                    pos += bytesRead;
+                }
             }
-        }
 
-        Assert.assertEquals(testfile.length(), metrics.getBytesTransferred());
-        fchannel.close();
-
-        Assert.assertEquals("stuff; more stuff; a lot more stuff!", readFromFile(fileHandle));
-
-        deleteWithCheck(fileHandle);
-    }
-
-    private void deleteWithCheck(File handle){
-        if (!handle.delete() && handle.exists()){
-            System.err.println("Failed to delete: "+handle.getPath());
+            Assert.assertEquals(testfile.length(), metrics.getBytesTransferred());
+        } finally {
+            testfile.close();
         }
+        Assert.assertEquals("stuff; more stuff; a lot more stuff!",
+            CodecTestUtils.readFromFile(this.tmpfile));
     }
 
     @Test
     public void testDecodingFileWithBufferedSessionData() throws Exception {
-        ReadableByteChannel channel = new ReadableByteChannelMock(
-                new String[] {"stuff; ", "more stuff; ", "a lot more stuff!"}, "US-ASCII");
-        HttpParams params = new BasicHttpParams();
+        final ReadableByteChannel channel = new ReadableByteChannelMock(
+                new String[] {"stuff; ", "more stuff; ", "a lot more stuff!"}, Consts.ASCII);
 
-        SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 256, params);
-        HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
-        IdentityDecoder decoder = new IdentityDecoder(
+        final SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 256, Consts.ASCII);
+        final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
+        final IdentityDecoder decoder = new IdentityDecoder(
                 channel, inbuf, metrics);
 
-        int i = inbuf.fill(channel);
+        final int i = inbuf.fill(channel);
         Assert.assertEquals(7, i);
 
-        File fileHandle = File.createTempFile("testFile", ".txt");
-
-        RandomAccessFile testfile = new RandomAccessFile(fileHandle, "rw");
-        FileChannel fchannel = testfile.getChannel();
-
-        long pos = 0;
-        while (!decoder.isCompleted()) {
-            long bytesRead = decoder.transfer(fchannel, pos, 10);
-            if (bytesRead > 0) {
-                pos += bytesRead;
+        createTempFile();
+        final RandomAccessFile testfile = new RandomAccessFile(this.tmpfile, "rw");
+        try {
+            final FileChannel fchannel = testfile.getChannel();
+            long pos = 0;
+            while (!decoder.isCompleted()) {
+                final long bytesRead = decoder.transfer(fchannel, pos, 10);
+                if (bytesRead > 0) {
+                    pos += bytesRead;
+                }
             }
-        }
 
-        // count everything except the initial 7 bytes that went to the session buffer
-        Assert.assertEquals(testfile.length() - 7, metrics.getBytesTransferred());
-        fchannel.close();
-
-        Assert.assertEquals("stuff; more stuff; a lot more stuff!", readFromFile(fileHandle));
-
-        deleteWithCheck(fileHandle);
+            // count everything except the initial 7 bytes that went to the session buffer
+            Assert.assertEquals(testfile.length() - 7, metrics.getBytesTransferred());
+        } finally {
+            testfile.close();
+        }
+        Assert.assertEquals("stuff; more stuff; a lot more stuff!",
+            CodecTestUtils.readFromFile(this.tmpfile));
     }
 
     @Test
     public void testDecodingFileWithOffsetAndBufferedSessionData() throws Exception {
-        ReadableByteChannel channel = new ReadableByteChannelMock(
-                new String[] {"stuff; ", "more stuff; ", "a lot more stuff!"}, "US-ASCII");
-        HttpParams params = new BasicHttpParams();
+        final ReadableByteChannel channel = new ReadableByteChannelMock(
+                new String[] {"stuff; ", "more stuff; ", "a lot more stuff!"}, Consts.ASCII);
 
-        SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 256, params);
-        HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
-        IdentityDecoder decoder = new IdentityDecoder(
+        final SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 256, Consts.ASCII);
+        final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
+        final IdentityDecoder decoder = new IdentityDecoder(
                 channel, inbuf, metrics);
 
-        int i = inbuf.fill(channel);
+        final int i = inbuf.fill(channel);
         Assert.assertEquals(7, i);
 
-        File fileHandle = File.createTempFile("testFile", ".txt");
-
-        RandomAccessFile testfile = new RandomAccessFile(fileHandle, "rw");
-        byte[] beginning = "beginning; ".getBytes("US-ASCII");
-        testfile.write(beginning);
-        testfile.close();
+        final byte[] beginning = EncodingUtils.getAsciiBytes("beginning; ");
 
-        testfile = new RandomAccessFile(fileHandle, "rw");
-        FileChannel fchannel = testfile.getChannel();
-
-        long pos = beginning.length;
-        while (!decoder.isCompleted()) {
-            if(testfile.length() < pos)
-                testfile.setLength(pos);
-            long bytesRead = decoder.transfer(fchannel, pos, 10);
-            if (bytesRead > 0) {
-                pos += bytesRead;
-            }
+        createTempFile();
+        RandomAccessFile testfile = new RandomAccessFile(this.tmpfile, "rw");
+        try {
+            testfile.write(beginning);
+        } finally {
+            testfile.close();
         }
 
-        // count everything except the initial 7 bytes that went to the session buffer
-        Assert.assertEquals(testfile.length() - 7 - beginning.length, metrics.getBytesTransferred());
-        fchannel.close();
+        testfile = new RandomAccessFile(this.tmpfile, "rw");
+        try {
+            final FileChannel fchannel = testfile.getChannel();
+            long pos = beginning.length;
+            while (!decoder.isCompleted()) {
+                if(testfile.length() < pos) {
+                    testfile.setLength(pos);
+                }
+                final long bytesRead = decoder.transfer(fchannel, pos, 10);
+                if (bytesRead > 0) {
+                    pos += bytesRead;
+                }
+            }
 
-        Assert.assertEquals("beginning; stuff; more stuff; a lot more stuff!", readFromFile(fileHandle));
+            // count everything except the initial 7 bytes that went to the session buffer
+            Assert.assertEquals(testfile.length() - 7 - beginning.length, metrics.getBytesTransferred());
+        } finally {
+            testfile.close();
+        }
 
-        deleteWithCheck(fileHandle);
+        Assert.assertEquals("beginning; stuff; more stuff; a lot more stuff!",
+            CodecTestUtils.readFromFile(this.tmpfile));
     }
 
     @Test
     public void testWriteBeyondFileSize() throws Exception {
-        ReadableByteChannel channel = new ReadableByteChannelMock(
-                new String[] {"a"}, "US-ASCII");
-        HttpParams params = new BasicHttpParams();
+        final ReadableByteChannel channel = new ReadableByteChannelMock(
+                new String[] {"a"}, Consts.ASCII);
 
-        SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 256, params);
-        HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
-        IdentityDecoder decoder = new IdentityDecoder(
+        final SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 256, Consts.ASCII);
+        final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
+        final IdentityDecoder decoder = new IdentityDecoder(
                 channel, inbuf, metrics);
 
-        File fileHandle = File.createTempFile("testFile", ".txt");
-
-        RandomAccessFile testfile = new RandomAccessFile(fileHandle, "rw");
-        FileChannel fchannel = testfile.getChannel();
-        Assert.assertEquals(0, testfile.length());
-
+        createTempFile();
+        final RandomAccessFile testfile = new RandomAccessFile(this.tmpfile, "rw");
         try {
-            decoder.transfer(fchannel, 5, 10);
-            Assert.fail("expected IOException");
-        } catch(IOException iox) {}
-
-        testfile.close();
-        deleteWithCheck(fileHandle);
+            Assert.assertEquals(0, testfile.length());
+            final FileChannel fchannel = testfile.getChannel();
+            try {
+                decoder.transfer(fchannel, 5, 10);
+                Assert.fail("expected IOException");
+            } catch(final IOException iox) {}
+        } finally {
+            testfile.close();
+        }
     }
 
     @Test
     public void testInvalidConstructor() {
-        ReadableByteChannel channel = new ReadableByteChannelMock(
-                new String[] {"stuff;", "more stuff"}, "US-ASCII");
-        HttpParams params = new BasicHttpParams();
+        final ReadableByteChannel channel = new ReadableByteChannelMock(
+                new String[] {"stuff;", "more stuff"}, Consts.ASCII);
 
-        SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 256, params);
+        final SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 256, Consts.ASCII);
         try {
             new IdentityDecoder(null, null, null);
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
             // ignore
         }
         try {
             new IdentityDecoder(channel, null, null);
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
             // ignore
         }
         try {
             new IdentityDecoder(channel, inbuf, null);
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
             // ignore
         }
     }
 
     @Test
     public void testInvalidInput() throws Exception {
-        String s = "stuff";
-        ReadableByteChannel channel = new ReadableByteChannelMock(
-                new String[] {s}, "US-ASCII");
-        HttpParams params = new BasicHttpParams();
+        final String s = "stuff";
+        final ReadableByteChannel channel = new ReadableByteChannelMock(
+                new String[] {s}, Consts.ASCII);
 
-        SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 256, params);
-        HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
-        IdentityDecoder decoder = new IdentityDecoder(channel, inbuf, metrics);
+        final SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 256, Consts.ASCII);
+        final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
+        final IdentityDecoder decoder = new IdentityDecoder(channel, inbuf, metrics);
 
         try {
             decoder.read(null);
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
             // expected
         }
     }
diff --git a/httpcore-nio/src/test/java/org/apache/http/impl/nio/codecs/TestIdentityEncoder.java b/httpcore-nio/src/test/java/org/apache/http/impl/nio/codecs/TestIdentityEncoder.java
index ca72360..5234975 100644
--- a/httpcore-nio/src/test/java/org/apache/http/impl/nio/codecs/TestIdentityEncoder.java
+++ b/httpcore-nio/src/test/java/org/apache/http/impl/nio/codecs/TestIdentityEncoder.java
@@ -27,70 +27,78 @@
 
 package org.apache.http.impl.nio.codecs;
 
-import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.RandomAccessFile;
 import java.nio.ByteBuffer;
-import java.nio.channels.Channels;
-import java.nio.channels.WritableByteChannel;
+import java.nio.channels.FileChannel;
 
+import org.apache.http.Consts;
+import org.apache.http.WritableByteChannelMock;
 import org.apache.http.impl.io.HttpTransportMetricsImpl;
 import org.apache.http.impl.nio.reactor.SessionOutputBufferImpl;
 import org.apache.http.nio.reactor.SessionOutputBuffer;
-import org.apache.http.params.BasicHttpParams;
-import org.apache.http.params.HttpParams;
-import org.apache.http.util.EncodingUtils;
+import org.junit.After;
 import org.junit.Assert;
 import org.junit.Test;
+import org.mockito.Mockito;
 
 /**
  * Simple tests for {@link IdentityEncoder}.
  */
 public class TestIdentityEncoder {
 
-    private static ByteBuffer wrap(final String s) {
-        return ByteBuffer.wrap(EncodingUtils.getAsciiBytes(s));
+    private File tmpfile;
+
+    protected File createTempFile() throws IOException {
+        this.tmpfile = File.createTempFile("testFile", ".txt");
+        return this.tmpfile;
     }
 
-    private static WritableByteChannel newChannel(final ByteArrayOutputStream baos) {
-        return Channels.newChannel(baos);
+    @After
+    public void deleteTempFile() {
+        if (this.tmpfile != null && this.tmpfile.exists()) {
+            this.tmpfile.delete();
+        }
     }
 
     @Test
     public void testBasicCoding() throws Exception {
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        WritableByteChannel channel = newChannel(baos);
-        HttpParams params = new BasicHttpParams();
-        SessionOutputBuffer outbuf = new SessionOutputBufferImpl(1024, 128, params);
-        HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
-
-        IdentityEncoder encoder = new IdentityEncoder(channel, outbuf, metrics);
-        encoder.write(wrap("stuff"));
-        encoder.complete();
+        final WritableByteChannelMock channel = new WritableByteChannelMock(64);
+        final SessionOutputBuffer outbuf = new SessionOutputBufferImpl(1024, 128);
+        final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
 
-        String s = baos.toString("US-ASCII");
+        final IdentityEncoder encoder = new IdentityEncoder(channel, outbuf, metrics);
+        Assert.assertEquals(5, encoder.write(CodecTestUtils.wrap("stuff")));
+        encoder.complete();
 
         Assert.assertTrue(encoder.isCompleted());
+        Assert.assertEquals(5, metrics.getBytesTransferred());
+
+        outbuf.flush(channel);
+        final String s = channel.dump(Consts.ASCII);
+
         Assert.assertEquals("stuff", s);
+        Assert.assertEquals("[identity; completed: true]", encoder.toString());
     }
 
     @Test
-    public void testCodingEmptyBuffer() throws Exception {
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        WritableByteChannel channel = newChannel(baos);
-        HttpParams params = new BasicHttpParams();
-        SessionOutputBuffer outbuf = new SessionOutputBufferImpl(1024, 128, params);
-        HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
+    public void testCodingEmptySrcBuffer() throws Exception {
+        final WritableByteChannelMock channel = new WritableByteChannelMock(64);
+        final SessionOutputBuffer outbuf = new SessionOutputBufferImpl(1024, 128);
+        final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
 
-        IdentityEncoder encoder = new IdentityEncoder(channel, outbuf, metrics);
-        encoder.write(wrap("stuff"));
+        final IdentityEncoder encoder = new IdentityEncoder(channel, outbuf, metrics);
+        encoder.write(CodecTestUtils.wrap("stuff"));
 
-        ByteBuffer empty = ByteBuffer.allocate(100);
+        final ByteBuffer empty = ByteBuffer.allocate(100);
         empty.flip();
         encoder.write(empty);
         encoder.write(null);
-
         encoder.complete();
 
-        String s = baos.toString("US-ASCII");
+        outbuf.flush(channel);
+        final String s = channel.dump(Consts.ASCII);
 
         Assert.assertTrue(encoder.isCompleted());
         Assert.assertEquals("stuff", s);
@@ -98,49 +106,465 @@ public class TestIdentityEncoder {
 
     @Test
     public void testCodingCompleted() throws Exception {
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        WritableByteChannel channel = newChannel(baos);
-        HttpParams params = new BasicHttpParams();
-        SessionOutputBuffer outbuf = new SessionOutputBufferImpl(1024, 128, params);
-        HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
-
-        IdentityEncoder encoder = new IdentityEncoder(channel, outbuf, metrics);
-        encoder.write(wrap("stuff"));
+        final WritableByteChannelMock channel = new WritableByteChannelMock(64);
+        final SessionOutputBuffer outbuf = new SessionOutputBufferImpl(1024, 128);
+        final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
+
+        final IdentityEncoder encoder = new IdentityEncoder(channel, outbuf, metrics);
+        encoder.write(CodecTestUtils.wrap("stuff"));
         encoder.complete();
 
         try {
-            encoder.write(wrap("more stuff"));
+            encoder.write(CodecTestUtils.wrap("more stuff"));
             Assert.fail("IllegalStateException should have been thrown");
-        } catch (IllegalStateException ex) {
+        } catch (final IllegalStateException ex) {
             // ignore
         }
     }
 
     @Test
     public void testInvalidConstructor() {
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        WritableByteChannel channel = newChannel(baos);
-        HttpParams params = new BasicHttpParams();
-        SessionOutputBuffer outbuf = new SessionOutputBufferImpl(1024, 128, params);
+        final WritableByteChannelMock channel = new WritableByteChannelMock(64);
+        final SessionOutputBuffer outbuf = new SessionOutputBufferImpl(1024, 128);
 
         try {
             new IdentityEncoder(null, null, null);
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
             // ignore
         }
         try {
             new IdentityEncoder(channel, null, null);
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
             // ignore
         }
         try {
             new IdentityEncoder(channel, outbuf, null);
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
             // ignore
         }
     }
 
+    @Test
+    public void testCodingFromFile() throws Exception {
+        final WritableByteChannelMock channel = new WritableByteChannelMock(64);
+        final SessionOutputBuffer outbuf = new SessionOutputBufferImpl(1024, 128);
+        final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
+
+        final IdentityEncoder encoder = new IdentityEncoder(channel, outbuf, metrics);
+
+        createTempFile();
+        RandomAccessFile testfile = new RandomAccessFile(this.tmpfile, "rw");
+        try {
+            testfile.write("stuff;".getBytes("US-ASCII"));
+            testfile.write("more stuff".getBytes("US-ASCII"));
+        } finally {
+            testfile.close();
+        }
+
+        testfile = new RandomAccessFile(this.tmpfile, "rw");
+        try {
+            final FileChannel fchannel = testfile.getChannel();
+            encoder.transfer(fchannel, 0, 20);
+        } finally {
+            testfile.close();
+        }
+
+        final String s = channel.dump(Consts.ASCII);
+
+        Assert.assertFalse(encoder.isCompleted());
+        Assert.assertEquals("stuff;more stuff", s);
+    }
+
+    @Test
+    public void testCodingEmptyFile() throws Exception {
+        final WritableByteChannelMock channel = new WritableByteChannelMock(64);
+        final SessionOutputBuffer outbuf = new SessionOutputBufferImpl(1024, 128);
+        final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
+
+        final IdentityEncoder encoder = new IdentityEncoder(channel, outbuf, metrics);
+        encoder.write(CodecTestUtils.wrap("stuff;"));
+
+        //Create an empty file
+        createTempFile();
+        RandomAccessFile testfile = new RandomAccessFile(this.tmpfile, "rw");
+        testfile.close();
+
+        testfile = new RandomAccessFile(this.tmpfile, "rw");
+        try {
+            final FileChannel fchannel = testfile.getChannel();
+            encoder.transfer(fchannel, 0, 20);
+            encoder.write(CodecTestUtils.wrap("more stuff"));
+        } finally {
+            testfile.close();
+        }
+
+        final String s = channel.dump(Consts.ASCII);
+
+        Assert.assertFalse(encoder.isCompleted());
+        Assert.assertEquals("stuff;more stuff", s);
+    }
+
+    @Test
+    public void testCodingFromFileSmaller() throws Exception {
+        final WritableByteChannelMock channel = new WritableByteChannelMock(64);
+        final SessionOutputBuffer outbuf = new SessionOutputBufferImpl(1024, 128);
+        final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
+
+        final IdentityEncoder encoder = new IdentityEncoder(channel, outbuf, metrics);
+
+        createTempFile();
+        RandomAccessFile testfile = new RandomAccessFile(this.tmpfile, "rw");
+        try {
+            testfile.write("stuff;".getBytes("US-ASCII"));
+            testfile.write("more stuff".getBytes("US-ASCII"));
+        } finally {
+            testfile.close();
+        }
+
+        testfile = new RandomAccessFile(this.tmpfile, "rw");
+        try {
+            final FileChannel fchannel = testfile.getChannel();
+            encoder.transfer(fchannel, 0, 20);
+        } finally {
+            testfile.close();
+        }
+        final String s = channel.dump(Consts.ASCII);
+
+        Assert.assertFalse(encoder.isCompleted());
+        Assert.assertEquals("stuff;more stuff", s);
+    }
+
+    @Test
+    public void testCodingFromFileFlushBuffer() throws Exception {
+        final WritableByteChannelMock channel = new WritableByteChannelMock(64);
+        final SessionOutputBuffer outbuf = new SessionOutputBufferImpl(1024, 128);
+        final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
+
+        final IdentityEncoder encoder = new IdentityEncoder(channel, outbuf, metrics);
+
+        outbuf.writeLine("header");
+
+        createTempFile();
+        RandomAccessFile testfile = new RandomAccessFile(this.tmpfile, "rw");
+        try {
+            testfile.write("stuff;".getBytes("US-ASCII"));
+            testfile.write("more stuff".getBytes("US-ASCII"));
+        } finally {
+            testfile.close();
+        }
+
+        testfile = new RandomAccessFile(this.tmpfile, "rw");
+        try {
+            final FileChannel fchannel = testfile.getChannel();
+            encoder.transfer(fchannel, 0, 20);
+        } finally {
+            testfile.close();
+        }
+        final String s = channel.dump(Consts.ASCII);
+
+        Assert.assertFalse(encoder.isCompleted());
+        Assert.assertEquals("header\r\nstuff;more stuff", s);
+    }
+
+    @Test
+    public void testCodingFromFileChannelSaturated() throws Exception {
+        final WritableByteChannelMock channel = new WritableByteChannelMock(64, 4);
+        final SessionOutputBuffer outbuf = new SessionOutputBufferImpl(1024, 128);
+        final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
+
+        final IdentityEncoder encoder = new IdentityEncoder(channel, outbuf, metrics);
+
+        outbuf.writeLine("header");
+
+        createTempFile();
+        RandomAccessFile testfile = new RandomAccessFile(this.tmpfile, "rw");
+        try {
+            testfile.write("stuff".getBytes("US-ASCII"));
+        } finally {
+            testfile.close();
+        }
+
+        testfile = new RandomAccessFile(this.tmpfile, "rw");
+        try {
+            final FileChannel fchannel = testfile.getChannel();
+            encoder.transfer(fchannel, 0, 20);
+            encoder.transfer(fchannel, 0, 20);
+        } finally {
+            testfile.close();
+        }
+        final String s = channel.dump(Consts.ASCII);
+
+        Assert.assertFalse(encoder.isCompleted());
+        Assert.assertEquals("head", s);
+    }
+
+    @Test
+    public void testCodingNoFragmentBuffering() throws Exception {
+        final WritableByteChannelMock channel = Mockito.spy(new WritableByteChannelMock(64));
+        final SessionOutputBuffer outbuf = Mockito.spy(new SessionOutputBufferImpl(1024, 128));
+        final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
+
+        outbuf.writeLine("header");
+        final IdentityEncoder encoder = new IdentityEncoder(channel, outbuf, metrics, 0);
+        Assert.assertEquals(5, encoder.write(CodecTestUtils.wrap("stuff")));
+
+        Mockito.verify(channel, Mockito.times(2)).write(Mockito.<ByteBuffer>any());
+        Mockito.verify(outbuf, Mockito.never()).write(Mockito.<ByteBuffer>any());
+        Mockito.verify(outbuf, Mockito.times(1)).flush(channel);
+
+        Assert.assertEquals(13, metrics.getBytesTransferred());
+
+        outbuf.flush(channel);
+        final String s = channel.dump(Consts.ASCII);
+
+        Assert.assertEquals("header\r\nstuff", s);
+    }
+
+    @Test
+    public void testCodingFragmentBuffering() throws Exception {
+        final WritableByteChannelMock channel = Mockito.spy(new WritableByteChannelMock(64));
+        final SessionOutputBuffer outbuf = Mockito.spy(new SessionOutputBufferImpl(1024, 128));
+        final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
+
+        outbuf.writeLine("header");
+        final IdentityEncoder encoder = new IdentityEncoder(channel, outbuf, metrics, 32);
+        Assert.assertEquals(5, encoder.write(CodecTestUtils.wrap("stuff")));
+
+        Mockito.verify(channel, Mockito.never()).write(Mockito.<ByteBuffer>any());
+        Mockito.verify(outbuf, Mockito.times(1)).write(Mockito.<ByteBuffer>any());
+        Mockito.verify(outbuf, Mockito.never()).flush(channel);
+
+        Assert.assertEquals(0, metrics.getBytesTransferred());
+
+        outbuf.flush(channel);
+        final String s = channel.dump(Consts.ASCII);
+
+        Assert.assertEquals("header\r\nstuff", s);
+    }
+
+    @Test
+    public void testCodingFragmentBufferingMultipleFragments() throws Exception {
+        final WritableByteChannelMock channel = Mockito.spy(new WritableByteChannelMock(64));
+        final SessionOutputBuffer outbuf = Mockito.spy(new SessionOutputBufferImpl(1024, 128));
+        final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
+
+        final IdentityEncoder encoder = new IdentityEncoder(channel, outbuf, metrics, 32);
+        Assert.assertEquals(5, encoder.write(CodecTestUtils.wrap("stuff")));
+        Assert.assertEquals(1, encoder.write(CodecTestUtils.wrap("-")));
+        Assert.assertEquals(10, encoder.write(CodecTestUtils.wrap("more stuff")));
+
+        Mockito.verify(channel, Mockito.never()).write(Mockito.<ByteBuffer>any());
+        Mockito.verify(outbuf, Mockito.times(3)).write(Mockito.<ByteBuffer>any());
+        Mockito.verify(outbuf, Mockito.never()).flush(channel);
+
+        Assert.assertEquals(0, metrics.getBytesTransferred());
+
+        outbuf.flush(channel);
+        final String s = channel.dump(Consts.ASCII);
+
+        Assert.assertEquals("stuff-more stuff", s);
+    }
+
+    @Test
+    public void testCodingFragmentBufferingLargeFragment() throws Exception {
+        final WritableByteChannelMock channel = Mockito.spy(new WritableByteChannelMock(64));
+        final SessionOutputBuffer outbuf = Mockito.spy(new SessionOutputBufferImpl(1024, 128));
+        final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
+
+        outbuf.writeLine("header");
+        final IdentityEncoder encoder = new IdentityEncoder(channel, outbuf, metrics, 2);
+        Assert.assertEquals(5, encoder.write(CodecTestUtils.wrap("stuff")));
+
+        Mockito.verify(channel, Mockito.times(2)).write(Mockito.<ByteBuffer>any());
+        Mockito.verify(outbuf, Mockito.never()).write(Mockito.<ByteBuffer>any());
+        Mockito.verify(outbuf, Mockito.times(1)).flush(channel);
+
+        Assert.assertEquals(13, metrics.getBytesTransferred());
+
+        outbuf.flush(channel);
+        final String s = channel.dump(Consts.ASCII);
+        Assert.assertEquals("header\r\nstuff", s);
+    }
+
+    @Test
+    public void testCodingFragmentBufferingTinyFragments() throws Exception {
+        final WritableByteChannelMock channel = Mockito.spy(new WritableByteChannelMock(64));
+        final SessionOutputBuffer outbuf = Mockito.spy(new SessionOutputBufferImpl(1024, 128));
+        final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
+
+        final IdentityEncoder encoder = new IdentityEncoder(channel, outbuf, metrics, 1);
+        Assert.assertEquals(5, encoder.write(CodecTestUtils.wrap("stuff")));
+        Assert.assertEquals(1, encoder.write(CodecTestUtils.wrap("-")));
+        Assert.assertEquals(1, encoder.write(CodecTestUtils.wrap("-")));
+        Assert.assertEquals(1, encoder.write(CodecTestUtils.wrap("-")));
+        Assert.assertEquals(10, encoder.write(CodecTestUtils.wrap("more stuff")));
+
+        Mockito.verify(channel, Mockito.times(5)).write(Mockito.<ByteBuffer>any());
+        Mockito.verify(outbuf, Mockito.times(3)).write(Mockito.<ByteBuffer>any());
+        Mockito.verify(outbuf, Mockito.times(3)).flush(channel);
+
+        Assert.assertEquals(18, metrics.getBytesTransferred());
+
+        outbuf.flush(channel);
+        final String s = channel.dump(Consts.ASCII);
+
+        Assert.assertEquals("stuff---more stuff", s);
+    }
+
+    @Test
+    public void testCodingFragmentBufferingTinyFragments2() throws Exception {
+        final WritableByteChannelMock channel = Mockito.spy(new WritableByteChannelMock(64));
+        final SessionOutputBuffer outbuf = Mockito.spy(new SessionOutputBufferImpl(1024, 128));
+        final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
+
+        final IdentityEncoder encoder = new IdentityEncoder(channel, outbuf, metrics, 2);
+        Assert.assertEquals(5, encoder.write(CodecTestUtils.wrap("stuff")));
+        Assert.assertEquals(1, encoder.write(CodecTestUtils.wrap("-")));
+        Assert.assertEquals(1, encoder.write(CodecTestUtils.wrap("-")));
+        Assert.assertEquals(1, encoder.write(CodecTestUtils.wrap("-")));
+        Assert.assertEquals(10, encoder.write(CodecTestUtils.wrap("more stuff")));
+
+        Mockito.verify(channel, Mockito.times(4)).write(Mockito.<ByteBuffer>any());
+        Mockito.verify(outbuf, Mockito.times(3)).write(Mockito.<ByteBuffer>any());
+        Mockito.verify(outbuf, Mockito.times(2)).flush(channel);
+
+        Assert.assertEquals(18, metrics.getBytesTransferred());
+
+        outbuf.flush(channel);
+        final String s = channel.dump(Consts.ASCII);
+
+        Assert.assertEquals("stuff---more stuff", s);
+    }
+
+    @Test
+    public void testCodingFragmentBufferingTinyFragments3() throws Exception {
+        final WritableByteChannelMock channel = Mockito.spy(new WritableByteChannelMock(64));
+        final SessionOutputBuffer outbuf = Mockito.spy(new SessionOutputBufferImpl(1024, 128));
+        final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
+
+        final IdentityEncoder encoder = new IdentityEncoder(channel, outbuf, metrics, 3);
+        Assert.assertEquals(5, encoder.write(CodecTestUtils.wrap("stuff")));
+        Assert.assertEquals(1, encoder.write(CodecTestUtils.wrap("-")));
+        Assert.assertEquals(1, encoder.write(CodecTestUtils.wrap("-")));
+        Assert.assertEquals(1, encoder.write(CodecTestUtils.wrap("-")));
+        Assert.assertEquals(1, encoder.write(CodecTestUtils.wrap("-")));
+        Assert.assertEquals(2, encoder.write(CodecTestUtils.wrap("--")));
+        Assert.assertEquals(10, encoder.write(CodecTestUtils.wrap("more stuff")));
+
+        Mockito.verify(channel, Mockito.times(4)).write(Mockito.<ByteBuffer>any());
+        Mockito.verify(outbuf, Mockito.times(5)).write(Mockito.<ByteBuffer>any());
+        Mockito.verify(outbuf, Mockito.times(2)).flush(channel);
+
+        Assert.assertEquals(21, metrics.getBytesTransferred());
+
+        outbuf.flush(channel);
+        final String s = channel.dump(Consts.ASCII);
+
+        Assert.assertEquals("stuff------more stuff", s);
+    }
+
+    @Test
+    public void testCodingFragmentBufferingBufferFlush() throws Exception {
+        final WritableByteChannelMock channel = Mockito.spy(new WritableByteChannelMock(64));
+        final SessionOutputBuffer outbuf = Mockito.spy(new SessionOutputBufferImpl(1024, 128));
+        final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
+
+        final IdentityEncoder encoder = new IdentityEncoder(channel, outbuf, metrics, 8);
+        Assert.assertEquals(5, encoder.write(CodecTestUtils.wrap("stuff")));
+        Assert.assertEquals(6, encoder.write(CodecTestUtils.wrap("-stuff")));
+
+        Mockito.verify(channel, Mockito.times(1)).write(Mockito.<ByteBuffer>any());
+        Mockito.verify(outbuf, Mockito.times(3)).write(Mockito.<ByteBuffer>any());
+        Mockito.verify(outbuf, Mockito.times(1)).flush(channel);
+
+        Assert.assertEquals(8, metrics.getBytesTransferred());
+        Assert.assertEquals(3, outbuf.length());
+
+        outbuf.flush(channel);
+        final String s = channel.dump(Consts.ASCII);
+
+        Assert.assertEquals("stuff-stuff", s);
+    }
+
+    @Test
+    public void testCodingFragmentBufferingBufferFlush2() throws Exception {
+        final WritableByteChannelMock channel = Mockito.spy(new WritableByteChannelMock(64));
+        final SessionOutputBuffer outbuf = Mockito.spy(new SessionOutputBufferImpl(1024, 128));
+        final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
+
+        final IdentityEncoder encoder = new IdentityEncoder(channel, outbuf, metrics, 8);
+        Assert.assertEquals(5, encoder.write(CodecTestUtils.wrap("stuff")));
+        Assert.assertEquals(16, encoder.write(CodecTestUtils.wrap("-much more stuff")));
+
+        Mockito.verify(channel, Mockito.times(2)).write(Mockito.<ByteBuffer>any());
+        Mockito.verify(outbuf, Mockito.times(1)).write(Mockito.<ByteBuffer>any());
+        Mockito.verify(outbuf, Mockito.times(1)).flush(channel);
+
+        Assert.assertEquals(21, metrics.getBytesTransferred());
+        Assert.assertEquals(0, outbuf.length());
+
+        outbuf.flush(channel);
+        final String s = channel.dump(Consts.ASCII);
+
+        Assert.assertEquals("stuff-much more stuff", s);
+    }
+
+    @Test
+    public void testCodingFragmentBufferingChannelSaturated() throws Exception {
+        final WritableByteChannelMock channel = Mockito.spy(new WritableByteChannelMock(64, 8));
+        final SessionOutputBuffer outbuf = Mockito.spy(new SessionOutputBufferImpl(1024, 128));
+        final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
+
+        final IdentityEncoder encoder = new IdentityEncoder(channel, outbuf, metrics, 3);
+        Assert.assertEquals(5, encoder.write(CodecTestUtils.wrap("stuff")));
+        Assert.assertEquals(1, encoder.write(CodecTestUtils.wrap("-")));
+        Assert.assertEquals(1, encoder.write(CodecTestUtils.wrap("-")));
+        Assert.assertEquals(1, encoder.write(CodecTestUtils.wrap("-")));
+        Assert.assertEquals(1, encoder.write(CodecTestUtils.wrap("-")));
+        Assert.assertEquals(1, encoder.write(CodecTestUtils.wrap("-")));
+        Assert.assertEquals(1, encoder.write(CodecTestUtils.wrap("-")));
+        Assert.assertEquals(0, encoder.write(CodecTestUtils.wrap("-")));
+        Assert.assertEquals(0, encoder.write(CodecTestUtils.wrap("more stuff")));
+
+        Mockito.verify(channel, Mockito.times(5)).write(Mockito.<ByteBuffer>any());
+        Mockito.verify(outbuf, Mockito.times(6)).write(Mockito.<ByteBuffer>any());
+        Mockito.verify(outbuf, Mockito.times(4)).flush(channel);
+
+        Assert.assertEquals(8, metrics.getBytesTransferred());
+
+        outbuf.flush(channel);
+        final String s = channel.dump(Consts.ASCII);
+
+        Assert.assertEquals("stuff---", s);
+        Assert.assertEquals(3, outbuf.length());
+    }
+
+    @Test
+    public void testCodingFragmentBufferingChannelSaturated2() throws Exception {
+        final WritableByteChannelMock channel = Mockito.spy(new WritableByteChannelMock(64, 8));
+        final SessionOutputBuffer outbuf = Mockito.spy(new SessionOutputBufferImpl(1024, 128));
+        final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
+
+        final IdentityEncoder encoder = new IdentityEncoder(channel, outbuf, metrics, 8);
+        Assert.assertEquals(5, encoder.write(CodecTestUtils.wrap("stuff")));
+        Assert.assertEquals(1, encoder.write(CodecTestUtils.wrap("-")));
+        Assert.assertEquals(1, encoder.write(CodecTestUtils.wrap("-")));
+        Assert.assertEquals(1, encoder.write(CodecTestUtils.wrap("much more stuff")));
+
+        Mockito.verify(channel, Mockito.times(3)).write(Mockito.<ByteBuffer>any());
+        Mockito.verify(outbuf, Mockito.times(3)).write(Mockito.<ByteBuffer>any());
+        Mockito.verify(outbuf, Mockito.times(1)).flush(channel);
+
+        Assert.assertEquals(8, metrics.getBytesTransferred());
+
+        outbuf.flush(channel);
+        final String s = channel.dump(Consts.ASCII);
+
+        Assert.assertEquals("stuff--m", s);
+        Assert.assertEquals(0, outbuf.length());
+    }
+
 }
diff --git a/httpcore-nio/src/test/java/org/apache/http/impl/nio/codecs/TestLengthDelimitedDecoder.java b/httpcore-nio/src/test/java/org/apache/http/impl/nio/codecs/TestLengthDelimitedDecoder.java
index eea4112..2e52de4 100644
--- a/httpcore-nio/src/test/java/org/apache/http/impl/nio/codecs/TestLengthDelimitedDecoder.java
+++ b/httpcore-nio/src/test/java/org/apache/http/impl/nio/codecs/TestLengthDelimitedDecoder.java
@@ -28,21 +28,19 @@
 package org.apache.http.impl.nio.codecs;
 
 import java.io.File;
-import java.io.FileInputStream;
 import java.io.IOException;
-import java.io.InputStreamReader;
 import java.io.RandomAccessFile;
 import java.nio.ByteBuffer;
 import java.nio.channels.FileChannel;
 import java.nio.channels.ReadableByteChannel;
 
 import org.apache.http.ConnectionClosedException;
+import org.apache.http.Consts;
 import org.apache.http.ReadableByteChannelMock;
 import org.apache.http.impl.io.HttpTransportMetricsImpl;
 import org.apache.http.impl.nio.reactor.SessionInputBufferImpl;
 import org.apache.http.nio.reactor.SessionInputBuffer;
-import org.apache.http.params.BasicHttpParams;
-import org.apache.http.params.HttpParams;
+import org.apache.http.util.EncodingUtils;
 import org.junit.After;
 import org.junit.Assert;
 import org.junit.Test;
@@ -66,54 +64,28 @@ public class TestLengthDelimitedDecoder {
         }
     }
 
-    private static String convert(final ByteBuffer src) {
-        src.flip();
-        StringBuilder buffer = new StringBuilder(src.remaining());
-        while (src.hasRemaining()) {
-            buffer.append((char)(src.get() & 0xff));
-        }
-        return buffer.toString();
-    }
-
-    private static String readFromFile(final File file) throws Exception {
-        FileInputStream filestream = new FileInputStream(file);
-        InputStreamReader reader = new InputStreamReader(filestream);
-        try {
-            StringBuilder buffer = new StringBuilder();
-            char[] tmp = new char[2048];
-            int l;
-            while ((l = reader.read(tmp)) != -1) {
-                buffer.append(tmp, 0, l);
-            }
-            return buffer.toString();
-        } finally {
-            reader.close();
-        }
-    }
-
     @Test
     public void testBasicDecoding() throws Exception {
-        ReadableByteChannel channel = new ReadableByteChannelMock(
-                new String[] {"stuff;", "more stuff"}, "US-ASCII");
-        HttpParams params = new BasicHttpParams();
+        final ReadableByteChannel channel = new ReadableByteChannelMock(
+                new String[] {"stuff;", "more stuff"}, Consts.ASCII);
 
-        SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 256, params);
-        HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
-        LengthDelimitedDecoder decoder = new LengthDelimitedDecoder(
+        final SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 256, Consts.ASCII);
+        final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
+        final LengthDelimitedDecoder decoder = new LengthDelimitedDecoder(
                 channel, inbuf, metrics, 16);
 
-        ByteBuffer dst = ByteBuffer.allocate(1024);
+        final ByteBuffer dst = ByteBuffer.allocate(1024);
 
         int bytesRead = decoder.read(dst);
         Assert.assertEquals(6, bytesRead);
-        Assert.assertEquals("stuff;", convert(dst));
+        Assert.assertEquals("stuff;", CodecTestUtils.convert(dst));
         Assert.assertFalse(decoder.isCompleted());
         Assert.assertEquals(6, metrics.getBytesTransferred());
 
         dst.clear();
         bytesRead = decoder.read(dst);
         Assert.assertEquals(10, bytesRead);
-        Assert.assertEquals("more stuff", convert(dst));
+        Assert.assertEquals("more stuff", CodecTestUtils.convert(dst));
         Assert.assertTrue(decoder.isCompleted());
         Assert.assertEquals(16, metrics.getBytesTransferred());
 
@@ -122,33 +94,34 @@ public class TestLengthDelimitedDecoder {
         Assert.assertEquals(-1, bytesRead);
         Assert.assertTrue(decoder.isCompleted());
         Assert.assertEquals(16, metrics.getBytesTransferred());
+
+        Assert.assertEquals("[content length: 16; pos: 16; completed: true]", decoder.toString());
     }
 
     @Test
     public void testCodingBeyondContentLimit() throws Exception {
-        ReadableByteChannel channel = new ReadableByteChannelMock(
+        final ReadableByteChannel channel = new ReadableByteChannelMock(
                 new String[] {
                         "stuff;",
-                        "more stuff; and a lot more stuff"}, "US-ASCII");
-        HttpParams params = new BasicHttpParams();
+                        "more stuff; and a lot more stuff"}, Consts.ASCII);
 
-        SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 256, params);
-        HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
-        LengthDelimitedDecoder decoder = new LengthDelimitedDecoder(
+        final SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 256, Consts.ASCII);
+        final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
+        final LengthDelimitedDecoder decoder = new LengthDelimitedDecoder(
                 channel, inbuf, metrics, 16);
 
-        ByteBuffer dst = ByteBuffer.allocate(1024);
+        final ByteBuffer dst = ByteBuffer.allocate(1024);
 
         int bytesRead = decoder.read(dst);
         Assert.assertEquals(6, bytesRead);
-        Assert.assertEquals("stuff;", convert(dst));
+        Assert.assertEquals("stuff;", CodecTestUtils.convert(dst));
         Assert.assertFalse(decoder.isCompleted());
         Assert.assertEquals(6, metrics.getBytesTransferred());
 
         dst.clear();
         bytesRead = decoder.read(dst);
         Assert.assertEquals(10, bytesRead);
-        Assert.assertEquals("more stuff", convert(dst));
+        Assert.assertEquals("more stuff", CodecTestUtils.convert(dst));
         Assert.assertTrue(decoder.isCompleted());
         Assert.assertEquals(16, metrics.getBytesTransferred());
 
@@ -161,48 +134,47 @@ public class TestLengthDelimitedDecoder {
 
     @Test
     public void testBasicDecodingSmallBuffer() throws Exception {
-        ReadableByteChannel channel = new ReadableByteChannelMock(
-                new String[] {"stuff;", "more stuff"}, "US-ASCII");
-        HttpParams params = new BasicHttpParams();
+        final ReadableByteChannel channel = new ReadableByteChannelMock(
+                new String[] {"stuff;", "more stuff"}, Consts.ASCII);
 
-        SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 256, params);
-        HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
-        LengthDelimitedDecoder decoder = new LengthDelimitedDecoder(
+        final SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 256, Consts.ASCII);
+        final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
+        final LengthDelimitedDecoder decoder = new LengthDelimitedDecoder(
                 channel, inbuf, metrics, 16);
 
-        ByteBuffer dst = ByteBuffer.allocate(4);
+        final ByteBuffer dst = ByteBuffer.allocate(4);
 
         int bytesRead = decoder.read(dst);
         Assert.assertEquals(4, bytesRead);
-        Assert.assertEquals("stuf", convert(dst));
+        Assert.assertEquals("stuf", CodecTestUtils.convert(dst));
         Assert.assertFalse(decoder.isCompleted());
         Assert.assertEquals(4, metrics.getBytesTransferred());
 
         dst.clear();
         bytesRead = decoder.read(dst);
         Assert.assertEquals(2, bytesRead);
-        Assert.assertEquals("f;", convert(dst));
+        Assert.assertEquals("f;", CodecTestUtils.convert(dst));
         Assert.assertFalse(decoder.isCompleted());
         Assert.assertEquals(6, metrics.getBytesTransferred());
 
         dst.clear();
         bytesRead = decoder.read(dst);
         Assert.assertEquals(4, bytesRead);
-        Assert.assertEquals("more", convert(dst));
+        Assert.assertEquals("more", CodecTestUtils.convert(dst));
         Assert.assertFalse(decoder.isCompleted());
         Assert.assertEquals(10, metrics.getBytesTransferred());
 
         dst.clear();
         bytesRead = decoder.read(dst);
         Assert.assertEquals(4, bytesRead);
-        Assert.assertEquals(" stu", convert(dst));
+        Assert.assertEquals(" stu", CodecTestUtils.convert(dst));
         Assert.assertFalse(decoder.isCompleted());
         Assert.assertEquals(14, metrics.getBytesTransferred());
 
         dst.clear();
         bytesRead = decoder.read(dst);
         Assert.assertEquals(2, bytesRead);
-        Assert.assertEquals("ff", convert(dst));
+        Assert.assertEquals("ff", CodecTestUtils.convert(dst));
         Assert.assertTrue(decoder.isCompleted());
         Assert.assertEquals(16, metrics.getBytesTransferred());
 
@@ -215,32 +187,31 @@ public class TestLengthDelimitedDecoder {
 
     @Test
     public void testDecodingFromSessionBuffer1() throws Exception {
-        ReadableByteChannel channel = new ReadableByteChannelMock(
-                new String[] {"stuff;", "more stuff"}, "US-ASCII");
-        HttpParams params = new BasicHttpParams();
+        final ReadableByteChannel channel = new ReadableByteChannelMock(
+                new String[] {"stuff;", "more stuff"}, Consts.ASCII);
 
-        SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 256, params);
-        HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
+        final SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 256, Consts.ASCII);
+        final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
 
         inbuf.fill(channel);
 
         Assert.assertEquals(6, inbuf.length());
 
-        LengthDelimitedDecoder decoder = new LengthDelimitedDecoder(
+        final LengthDelimitedDecoder decoder = new LengthDelimitedDecoder(
                 channel, inbuf, metrics, 16);
 
-        ByteBuffer dst = ByteBuffer.allocate(1024);
+        final ByteBuffer dst = ByteBuffer.allocate(1024);
 
         int bytesRead = decoder.read(dst);
         Assert.assertEquals(6, bytesRead);
-        Assert.assertEquals("stuff;", convert(dst));
+        Assert.assertEquals("stuff;", CodecTestUtils.convert(dst));
         Assert.assertFalse(decoder.isCompleted());
         Assert.assertEquals(0, metrics.getBytesTransferred());
 
         dst.clear();
         bytesRead = decoder.read(dst);
         Assert.assertEquals(10, bytesRead);
-        Assert.assertEquals("more stuff", convert(dst));
+        Assert.assertEquals("more stuff", CodecTestUtils.convert(dst));
         Assert.assertTrue(decoder.isCompleted());
         Assert.assertEquals(10, metrics.getBytesTransferred());
 
@@ -253,28 +224,27 @@ public class TestLengthDelimitedDecoder {
 
     @Test
     public void testDecodingFromSessionBuffer2() throws Exception {
-        ReadableByteChannel channel = new ReadableByteChannelMock(
+        final ReadableByteChannel channel = new ReadableByteChannelMock(
                 new String[] {
                         "stuff;",
-                        "more stuff; and a lot more stuff"}, "US-ASCII");
-        HttpParams params = new BasicHttpParams();
+                        "more stuff; and a lot more stuff"}, Consts.ASCII);
 
-        SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 256, params);
-        HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
+        final SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 256, Consts.ASCII);
+        final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
 
         inbuf.fill(channel);
         inbuf.fill(channel);
 
         Assert.assertEquals(38, inbuf.length());
 
-        LengthDelimitedDecoder decoder = new LengthDelimitedDecoder(
+        final LengthDelimitedDecoder decoder = new LengthDelimitedDecoder(
                 channel, inbuf, metrics, 16);
 
-        ByteBuffer dst = ByteBuffer.allocate(1024);
+        final ByteBuffer dst = ByteBuffer.allocate(1024);
 
         int bytesRead = decoder.read(dst);
         Assert.assertEquals(16, bytesRead);
-        Assert.assertEquals("stuff;more stuff", convert(dst));
+        Assert.assertEquals("stuff;more stuff", CodecTestUtils.convert(dst));
         Assert.assertTrue(decoder.isCompleted());
         Assert.assertEquals(0, metrics.getBytesTransferred());
 
@@ -285,24 +255,24 @@ public class TestLengthDelimitedDecoder {
         Assert.assertEquals(0, metrics.getBytesTransferred());
     }
 
+    /* ----------------- FileChannel Part testing --------------------------- */
     @Test
     public void testBasicDecodingFile() throws Exception {
-        ReadableByteChannel channel = new ReadableByteChannelMock(
-                new String[] {"stuff; ", "more stuff; ", "a lot more stuff!!!"}, "US-ASCII");
-        HttpParams params = new BasicHttpParams();
+        final ReadableByteChannel channel = new ReadableByteChannelMock(
+                new String[] {"stuff; ", "more stuff; ", "a lot more stuff!!!"}, Consts.ASCII);
 
-        SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 256, params);
-        HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
-        LengthDelimitedDecoder decoder = new LengthDelimitedDecoder(
+        final SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 256, Consts.ASCII);
+        final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
+        final LengthDelimitedDecoder decoder = new LengthDelimitedDecoder(
                 channel, inbuf, metrics, 36);
 
         createTempFile();
-        RandomAccessFile testfile = new RandomAccessFile(this.tmpfile, "rw");
+        final RandomAccessFile testfile = new RandomAccessFile(this.tmpfile, "rw");
         try {
-            FileChannel fchannel = testfile.getChannel();
+            final FileChannel fchannel = testfile.getChannel();
             long pos = 0;
             while (!decoder.isCompleted()) {
-                long bytesRead = decoder.transfer(fchannel, pos, 10);
+                final long bytesRead = decoder.transfer(fchannel, pos, 10);
                 if (bytesRead > 0) {
                     pos += bytesRead;
                 }
@@ -311,30 +281,30 @@ public class TestLengthDelimitedDecoder {
             testfile.close();
         }
         Assert.assertEquals(this.tmpfile.length(), metrics.getBytesTransferred());
-        Assert.assertEquals("stuff; more stuff; a lot more stuff!", readFromFile(this.tmpfile));
+        Assert.assertEquals("stuff; more stuff; a lot more stuff!",
+            CodecTestUtils.readFromFile(this.tmpfile));
     }
 
     @Test
     public void testDecodingFileWithBufferedSessionData() throws Exception {
-        ReadableByteChannel channel = new ReadableByteChannelMock(
-                new String[] {"stuff; ", "more stuff; ", "a lot more stuff!!!"}, "US-ASCII");
-        HttpParams params = new BasicHttpParams();
+        final ReadableByteChannel channel = new ReadableByteChannelMock(
+                new String[] {"stuff; ", "more stuff; ", "a lot more stuff!!!"}, Consts.ASCII);
 
-        SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 256, params);
-        HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
-        LengthDelimitedDecoder decoder = new LengthDelimitedDecoder(
+        final SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 256, Consts.ASCII);
+        final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
+        final LengthDelimitedDecoder decoder = new LengthDelimitedDecoder(
                 channel, inbuf, metrics, 36);
 
-        int i = inbuf.fill(channel);
+        final int i = inbuf.fill(channel);
         Assert.assertEquals(7, i);
 
         createTempFile();
-        RandomAccessFile testfile = new RandomAccessFile(this.tmpfile, "rw");
+        final RandomAccessFile testfile = new RandomAccessFile(this.tmpfile, "rw");
         try {
-            FileChannel fchannel = testfile.getChannel();
+            final FileChannel fchannel = testfile.getChannel();
             long pos = 0;
             while (!decoder.isCompleted()) {
-                long bytesRead = decoder.transfer(fchannel, pos, 10);
+                final long bytesRead = decoder.transfer(fchannel, pos, 10);
                 if (bytesRead > 0) {
                     pos += bytesRead;
                 }
@@ -343,24 +313,24 @@ public class TestLengthDelimitedDecoder {
             testfile.close();
         }
         Assert.assertEquals(this.tmpfile.length() - 7, metrics.getBytesTransferred());
-        Assert.assertEquals("stuff; more stuff; a lot more stuff!", readFromFile(this.tmpfile));
+        Assert.assertEquals("stuff; more stuff; a lot more stuff!",
+            CodecTestUtils.readFromFile(this.tmpfile));
     }
 
     @Test
     public void testDecodingFileWithOffsetAndBufferedSessionData() throws Exception {
-        ReadableByteChannel channel = new ReadableByteChannelMock(
-                new String[] {"stuff; ", "more stuff; ", "a lot more stuff!"}, "US-ASCII");
-        HttpParams params = new BasicHttpParams();
+        final ReadableByteChannel channel = new ReadableByteChannelMock(
+                new String[] {"stuff; ", "more stuff; ", "a lot more stuff!"}, Consts.ASCII);
 
-        SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 256, params);
-        HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
-        LengthDelimitedDecoder decoder = new LengthDelimitedDecoder(
+        final SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 256, Consts.ASCII);
+        final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
+        final LengthDelimitedDecoder decoder = new LengthDelimitedDecoder(
                 channel, inbuf, metrics, 36);
 
-        int i = inbuf.fill(channel);
+        final int i = inbuf.fill(channel);
         Assert.assertEquals(7, i);
 
-        byte[] beginning = "beginning; ".getBytes("US-ASCII");
+        final byte[] beginning =  EncodingUtils.getAsciiBytes("beginning; ");
 
         createTempFile();
         RandomAccessFile testfile = new RandomAccessFile(this.tmpfile, "rw");
@@ -372,13 +342,14 @@ public class TestLengthDelimitedDecoder {
 
         testfile = new RandomAccessFile(this.tmpfile, "rw");
         try {
-            FileChannel fchannel = testfile.getChannel();
+            final FileChannel fchannel = testfile.getChannel();
 
             long pos = beginning.length;
             while (!decoder.isCompleted()) {
-                if(testfile.length() < pos)
+                if(testfile.length() < pos) {
                     testfile.setLength(pos);
-                long bytesRead = decoder.transfer(fchannel, pos, 10);
+                }
+                final long bytesRead = decoder.transfer(fchannel, pos, 10);
                 if (bytesRead > 0) {
                     pos += bytesRead;
                 }
@@ -389,29 +360,29 @@ public class TestLengthDelimitedDecoder {
 
         // count everything except the initial 7 bytes that went to the session buffer
         Assert.assertEquals(this.tmpfile.length() - 7 - beginning.length, metrics.getBytesTransferred());
-        Assert.assertEquals("beginning; stuff; more stuff; a lot more stuff!", readFromFile(this.tmpfile));
+        Assert.assertEquals("beginning; stuff; more stuff; a lot more stuff!",
+            CodecTestUtils.readFromFile(this.tmpfile));
     }
 
     @Test
     public void testWriteBeyondFileSize() throws Exception {
-        ReadableByteChannel channel = new ReadableByteChannelMock(
-                new String[] {"a"}, "US-ASCII");
-        HttpParams params = new BasicHttpParams();
+        final ReadableByteChannel channel = new ReadableByteChannelMock(
+                new String[] {"a"}, Consts.ASCII);
 
-        SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 256, params);
-        HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
-        LengthDelimitedDecoder decoder = new LengthDelimitedDecoder(
+        final SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 256, Consts.ASCII);
+        final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
+        final LengthDelimitedDecoder decoder = new LengthDelimitedDecoder(
                 channel, inbuf, metrics, 1);
 
         createTempFile();
-        RandomAccessFile testfile = new RandomAccessFile(this.tmpfile, "rw");
+        final RandomAccessFile testfile = new RandomAccessFile(this.tmpfile, "rw");
         try {
-            FileChannel fchannel = testfile.getChannel();
+            final FileChannel fchannel = testfile.getChannel();
             Assert.assertEquals(0, testfile.length());
             try {
                 decoder.transfer(fchannel, 5, 10);
                 Assert.fail("IOException should have been thrown");
-            } catch(IOException expected) {
+            } catch(final IOException expected) {
             }
         } finally {
             testfile.close();
@@ -420,21 +391,20 @@ public class TestLengthDelimitedDecoder {
 
     @Test
     public void testCodingBeyondContentLimitFile() throws Exception {
-        ReadableByteChannel channel = new ReadableByteChannelMock(
+        final ReadableByteChannel channel = new ReadableByteChannelMock(
                 new String[] {
                         "stuff;",
-                        "more stuff; and a lot more stuff"}, "US-ASCII");
-        HttpParams params = new BasicHttpParams();
+                        "more stuff; and a lot more stuff"}, Consts.ASCII);
 
-        SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 256, params);
-        HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
-        LengthDelimitedDecoder decoder = new LengthDelimitedDecoder(
+        final SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 256, Consts.ASCII);
+        final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
+        final LengthDelimitedDecoder decoder = new LengthDelimitedDecoder(
                 channel, inbuf, metrics, 16);
 
         createTempFile();
-        RandomAccessFile testfile  = new RandomAccessFile(this.tmpfile, "rw");
+        final RandomAccessFile testfile  = new RandomAccessFile(this.tmpfile, "rw");
         try {
-            FileChannel fchannel = testfile.getChannel();
+            final FileChannel fchannel = testfile.getChannel();
 
             long bytesRead = decoder.transfer(fchannel, 0, 6);
             Assert.assertEquals(6, bytesRead);
@@ -457,72 +427,69 @@ public class TestLengthDelimitedDecoder {
 
     @Test
     public void testInvalidConstructor() {
-        ReadableByteChannel channel = new ReadableByteChannelMock(
-                new String[] {"stuff;", "more stuff"}, "US-ASCII");
-        HttpParams params = new BasicHttpParams();
+        final ReadableByteChannel channel = new ReadableByteChannelMock(
+                new String[] {"stuff;", "more stuff"}, Consts.ASCII);
 
-        SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 256, params);
-        HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
+        final SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 256, Consts.ASCII);
+        final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
         try {
             new LengthDelimitedDecoder(null, null, null, 10);
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
             // ignore
         }
         try {
             new LengthDelimitedDecoder(channel, null, null, 10);
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
             // ignore
         }
         try {
             new LengthDelimitedDecoder(channel, inbuf, null, 10);
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
             // ignore
         }
         try {
             new LengthDelimitedDecoder(channel, inbuf, metrics, -10);
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
             // ignore
         }
     }
 
     @Test
     public void testInvalidInput() throws Exception {
-        String s = "stuff";
-        ReadableByteChannel channel = new ReadableByteChannelMock(
-                new String[] {s}, "US-ASCII");
-        HttpParams params = new BasicHttpParams();
-
-        SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 256, params);
-        HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
-        LengthDelimitedDecoder decoder = new LengthDelimitedDecoder(
+        final String s = "stuff";
+        final ReadableByteChannel channel = new ReadableByteChannelMock(
+                new String[] {s}, Consts.ASCII);
+
+        final SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 256, Consts.ASCII);
+        final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
+        final LengthDelimitedDecoder decoder = new LengthDelimitedDecoder(
                 channel, inbuf, metrics, 3);
 
         try {
             decoder.read(null);
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
             // expected
         }
     }
 
     @Test
     public void testZeroLengthDecoding() throws Exception {
-        ReadableByteChannel channel = new ReadableByteChannelMock(
-                new String[] {"stuff"}, "US-ASCII");
-        HttpParams params = new BasicHttpParams();
+        final ReadableByteChannel channel = new ReadableByteChannelMock(
+                new String[] {"stuff"}, Consts.ASCII);
 
-        SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 256, params);
-        HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
-        LengthDelimitedDecoder decoder = new LengthDelimitedDecoder(
+        final SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 256, Consts.ASCII);
+        final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
+        final LengthDelimitedDecoder decoder = new LengthDelimitedDecoder(
                 channel, inbuf, metrics, 0);
 
-        ByteBuffer dst = ByteBuffer.allocate(1024);
+        final ByteBuffer dst = ByteBuffer.allocate(1024);
 
-        int bytesRead = decoder.read(dst);
+        final int bytesRead = decoder.read(dst);
         Assert.assertEquals(-1, bytesRead);
         Assert.assertTrue(decoder.isCompleted());
         Assert.assertEquals(0, metrics.getBytesTransferred());
@@ -530,38 +497,36 @@ public class TestLengthDelimitedDecoder {
 
     @Test(expected=ConnectionClosedException.class)
     public void testTruncatedContent() throws Exception {
-        ReadableByteChannel channel = new ReadableByteChannelMock(
-                new String[] {"1234567890"}, "US-ASCII");
-        HttpParams params = new BasicHttpParams();
+        final ReadableByteChannel channel = new ReadableByteChannelMock(
+                new String[] {"1234567890"}, Consts.ASCII);
 
-        SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 256, params);
-        HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
-        LengthDelimitedDecoder decoder = new LengthDelimitedDecoder(
+        final SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 256, Consts.ASCII);
+        final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
+        final LengthDelimitedDecoder decoder = new LengthDelimitedDecoder(
                 channel, inbuf, metrics, 20);
 
-        ByteBuffer dst = ByteBuffer.allocate(1024);
+        final ByteBuffer dst = ByteBuffer.allocate(1024);
 
-        int bytesRead = decoder.read(dst);
+        final int bytesRead = decoder.read(dst);
         Assert.assertEquals(10, bytesRead);
         decoder.read(dst);
     }
 
     @Test(expected=ConnectionClosedException.class)
     public void testTruncatedContentWithFile() throws Exception {
-        ReadableByteChannel channel = new ReadableByteChannelMock(
-                new String[] {"1234567890"}, "US-ASCII");
-        HttpParams params = new BasicHttpParams();
+        final ReadableByteChannel channel = new ReadableByteChannelMock(
+                new String[] {"1234567890"}, Consts.ASCII);
 
-        SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 256, params);
-        HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
-        LengthDelimitedDecoder decoder = new LengthDelimitedDecoder(
+        final SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 256, Consts.ASCII);
+        final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
+        final LengthDelimitedDecoder decoder = new LengthDelimitedDecoder(
                 channel, inbuf, metrics, 20);
 
         createTempFile();
-        RandomAccessFile testfile  = new RandomAccessFile(this.tmpfile, "rw");
+        final RandomAccessFile testfile  = new RandomAccessFile(this.tmpfile, "rw");
         try {
-            FileChannel fchannel = testfile.getChannel();
-            long bytesRead = decoder.transfer(fchannel, 0, Integer.MAX_VALUE);
+            final FileChannel fchannel = testfile.getChannel();
+            final long bytesRead = decoder.transfer(fchannel, 0, Integer.MAX_VALUE);
             Assert.assertEquals(10, bytesRead);
             decoder.transfer(fchannel, 0, Integer.MAX_VALUE);
         } finally {
diff --git a/httpcore-nio/src/test/java/org/apache/http/impl/nio/codecs/TestLengthDelimitedEncoder.java b/httpcore-nio/src/test/java/org/apache/http/impl/nio/codecs/TestLengthDelimitedEncoder.java
index ac622e6..be7824f 100644
--- a/httpcore-nio/src/test/java/org/apache/http/impl/nio/codecs/TestLengthDelimitedEncoder.java
+++ b/httpcore-nio/src/test/java/org/apache/http/impl/nio/codecs/TestLengthDelimitedEncoder.java
@@ -27,71 +27,71 @@
 
 package org.apache.http.impl.nio.codecs;
 
-import java.io.ByteArrayOutputStream;
 import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.OutputStreamWriter;
+import java.io.IOException;
+import java.io.RandomAccessFile;
 import java.nio.ByteBuffer;
-import java.nio.channels.Channels;
 import java.nio.channels.FileChannel;
-import java.nio.channels.WritableByteChannel;
 
+import org.apache.http.Consts;
+import org.apache.http.WritableByteChannelMock;
 import org.apache.http.impl.io.HttpTransportMetricsImpl;
 import org.apache.http.impl.nio.reactor.SessionOutputBufferImpl;
 import org.apache.http.nio.reactor.SessionOutputBuffer;
-import org.apache.http.params.BasicHttpParams;
-import org.apache.http.params.HttpParams;
-import org.apache.http.util.EncodingUtils;
+import org.junit.After;
 import org.junit.Assert;
 import org.junit.Test;
+import org.mockito.Mockito;
 
 /**
  * Simple tests for {@link LengthDelimitedEncoder}.
  */
 public class TestLengthDelimitedEncoder {
 
-    private static ByteBuffer wrap(final String s) {
-        return ByteBuffer.wrap(EncodingUtils.getAsciiBytes(s));
+    private File tmpfile;
+
+    protected File createTempFile() throws IOException {
+        this.tmpfile = File.createTempFile("testFile", ".txt");
+        return this.tmpfile;
     }
 
-    private static WritableByteChannel newChannel(final ByteArrayOutputStream baos) {
-        return Channels.newChannel(baos);
+    @After
+    public void deleteTempFile() {
+        if (this.tmpfile != null && this.tmpfile.exists()) {
+            this.tmpfile.delete();
+        }
     }
 
     @Test
     public void testBasicCoding() throws Exception {
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        WritableByteChannel channel = newChannel(baos);
-        HttpParams params = new BasicHttpParams();
-        SessionOutputBuffer outbuf = new SessionOutputBufferImpl(1024, 128, params);
-        HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
+        final WritableByteChannelMock channel = new WritableByteChannelMock(64);
+        final SessionOutputBuffer outbuf = new SessionOutputBufferImpl(1024, 128);
+        final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
 
-        LengthDelimitedEncoder encoder = new LengthDelimitedEncoder(
+        final LengthDelimitedEncoder encoder = new LengthDelimitedEncoder(
                 channel, outbuf, metrics, 16);
-        encoder.write(wrap("stuff;"));
-        encoder.write(wrap("more stuff"));
+        encoder.write(CodecTestUtils.wrap("stuff;"));
+        encoder.write(CodecTestUtils.wrap("more stuff"));
 
-        String s = baos.toString("US-ASCII");
+        final String s = channel.dump(Consts.ASCII);
 
         Assert.assertTrue(encoder.isCompleted());
         Assert.assertEquals("stuff;more stuff", s);
+        Assert.assertEquals("[content length: 16; pos: 16; completed: true]", encoder.toString());
     }
 
     @Test
     public void testCodingBeyondContentLimit() throws Exception {
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        WritableByteChannel channel = newChannel(baos);
-        HttpParams params = new BasicHttpParams();
-        SessionOutputBuffer outbuf = new SessionOutputBufferImpl(1024, 128, params);
-        HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
+        final WritableByteChannelMock channel = new WritableByteChannelMock(64);
+        final SessionOutputBuffer outbuf = new SessionOutputBufferImpl(1024, 128);
+        final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
 
-        LengthDelimitedEncoder encoder = new LengthDelimitedEncoder(
+        final LengthDelimitedEncoder encoder = new LengthDelimitedEncoder(
                 channel, outbuf, metrics, 16);
-        encoder.write(wrap("stuff;"));
-        encoder.write(wrap("more stuff; and a lot more stuff"));
+        encoder.write(CodecTestUtils.wrap("stuff;"));
+        encoder.write(CodecTestUtils.wrap("more stuff; and a lot more stuff"));
 
-        String s = baos.toString("US-ASCII");
+        final String s = channel.dump(Consts.ASCII);
 
         Assert.assertTrue(encoder.isCompleted());
         Assert.assertEquals("stuff;more stuff", s);
@@ -99,24 +99,22 @@ public class TestLengthDelimitedEncoder {
 
     @Test
     public void testCodingEmptyBuffer() throws Exception {
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        WritableByteChannel channel = newChannel(baos);
-        HttpParams params = new BasicHttpParams();
-        SessionOutputBuffer outbuf = new SessionOutputBufferImpl(1024, 128, params);
-        HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
+        final WritableByteChannelMock channel = new WritableByteChannelMock(64);
+        final SessionOutputBuffer outbuf = new SessionOutputBufferImpl(1024, 128);
+        final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
 
-        LengthDelimitedEncoder encoder = new LengthDelimitedEncoder(
+        final LengthDelimitedEncoder encoder = new LengthDelimitedEncoder(
                 channel, outbuf, metrics, 16);
-        encoder.write(wrap("stuff;"));
+        encoder.write(CodecTestUtils.wrap("stuff;"));
 
-        ByteBuffer empty = ByteBuffer.allocate(100);
+        final ByteBuffer empty = ByteBuffer.allocate(100);
         empty.flip();
         encoder.write(empty);
         encoder.write(null);
 
-        encoder.write(wrap("more stuff"));
+        encoder.write(CodecTestUtils.wrap("more stuff"));
 
-        String s = baos.toString("US-ASCII");
+        final String s = channel.dump(Consts.ASCII);
 
         Assert.assertTrue(encoder.isCompleted());
         Assert.assertEquals("stuff;more stuff", s);
@@ -124,200 +122,542 @@ public class TestLengthDelimitedEncoder {
 
     @Test
     public void testCodingCompleted() throws Exception {
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        WritableByteChannel channel = newChannel(baos);
-        HttpParams params = new BasicHttpParams();
-        SessionOutputBuffer outbuf = new SessionOutputBufferImpl(1024, 128, params);
-        HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
+        final WritableByteChannelMock channel = new WritableByteChannelMock(64);
+        final SessionOutputBuffer outbuf = new SessionOutputBufferImpl(1024, 128);
+        final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
 
-        LengthDelimitedEncoder encoder = new LengthDelimitedEncoder(
+        final LengthDelimitedEncoder encoder = new LengthDelimitedEncoder(
                 channel, outbuf, metrics, 5);
-        encoder.write(wrap("stuff"));
+        encoder.write(CodecTestUtils.wrap("stuff"));
 
         try {
-            encoder.write(wrap("more stuff"));
+            encoder.write(CodecTestUtils.wrap("more stuff"));
             Assert.fail("IllegalStateException should have been thrown");
-        } catch (IllegalStateException ex) {
+        } catch (final IllegalStateException ex) {
             // ignore
         }
     }
 
-    /* ----------------- FileChannel Part testing --------------------------- */
     @Test
-    public void testCodingBeyondContentLimitFromFile() throws Exception {
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        WritableByteChannel channel = newChannel(baos);
-        HttpParams params = new BasicHttpParams();
-        SessionOutputBuffer outbuf = new SessionOutputBufferImpl(1024, 128, params);
-        HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
-
-        LengthDelimitedEncoder encoder = new LengthDelimitedEncoder(
-                channel, outbuf, metrics, 16);
+    public void testInvalidConstructor() {
+        final WritableByteChannelMock channel = new WritableByteChannelMock(64);
+        final SessionOutputBuffer outbuf = new SessionOutputBufferImpl(1024, 128);
+        final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
 
-        File tmpFile = File.createTempFile("testFile", ".txt");
-        FileOutputStream fout = new FileOutputStream(tmpFile);
-        OutputStreamWriter wrtout = new OutputStreamWriter(fout);
+        try {
+            new LengthDelimitedEncoder(null, null, null, 10);
+            Assert.fail("IllegalArgumentException should have been thrown");
+        } catch (final IllegalArgumentException ex) {
+            // ignore
+        }
+        try {
+            new LengthDelimitedEncoder(channel, null, null, 10);
+            Assert.fail("IllegalArgumentException should have been thrown");
+        } catch (final IllegalArgumentException ex) {
+            // ignore
+        }
+        try {
+            new LengthDelimitedEncoder(channel, outbuf, null, 10);
+            Assert.fail("IllegalArgumentException should have been thrown");
+        } catch (final IllegalArgumentException ex) {
+            // ignore
+        }
+        try {
+            new LengthDelimitedEncoder(channel, outbuf, metrics, -10);
+            Assert.fail("IllegalArgumentException should have been thrown");
+        } catch (final IllegalArgumentException ex) {
+            // ignore
+        }
+    }
 
-        wrtout.write("stuff;");
-        wrtout.write("more stuff; and a lot more stuff");
+    @Test
+    public void testCodingBeyondContentLimitFromFile() throws Exception {
+        final WritableByteChannelMock channel = new WritableByteChannelMock(64);
+        final SessionOutputBuffer outbuf = new SessionOutputBufferImpl(1024, 128);
+        final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
 
-        wrtout.flush();
-        wrtout.close();
+        final LengthDelimitedEncoder encoder = new LengthDelimitedEncoder(
+                channel, outbuf, metrics, 16);
 
-        FileChannel fchannel = new FileInputStream(tmpFile).getChannel();
+        createTempFile();
+        RandomAccessFile testfile = new RandomAccessFile(this.tmpfile, "rw");
+        try {
+            testfile.write("stuff;".getBytes("US-ASCII"));
+            testfile.write("more stuff; and a lot more stuff".getBytes("US-ASCII"));
+        } finally {
+            testfile.close();
+        }
 
-        encoder.transfer(fchannel, 0, 20);
+        testfile = new RandomAccessFile(this.tmpfile, "rw");
+        try {
+            final FileChannel fchannel = testfile.getChannel();
+            encoder.transfer(fchannel, 0, 20);
+        } finally {
+            testfile.close();
+        }
 
-        String s = baos.toString("US-ASCII");
+        final String s = channel.dump(Consts.ASCII);
 
         Assert.assertTrue(encoder.isCompleted());
         Assert.assertEquals("stuff;more stuff", s);
-
-        fchannel.close();
-
-        deleteWithCheck(tmpFile);
-    }
-
-    private void deleteWithCheck(File handle){
-        if (!handle.delete() && handle.exists()){
-            System.err.println("Failed to delete: "+handle.getPath());
-        }
     }
 
     @Test
     public void testCodingEmptyFile() throws Exception {
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        WritableByteChannel channel = newChannel(baos);
-        HttpParams params = new BasicHttpParams();
-        SessionOutputBuffer outbuf = new SessionOutputBufferImpl(1024, 128, params);
-        HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
+        final WritableByteChannelMock channel = new WritableByteChannelMock(64);
+        final SessionOutputBuffer outbuf = new SessionOutputBufferImpl(1024, 128);
+        final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
 
-        LengthDelimitedEncoder encoder = new LengthDelimitedEncoder(
+        final LengthDelimitedEncoder encoder = new LengthDelimitedEncoder(
                 channel, outbuf, metrics, 16);
-        encoder.write(wrap("stuff;"));
+        encoder.write(CodecTestUtils.wrap("stuff;"));
 
         //Create an empty file
-        File tmpFile = File.createTempFile("testFile", ".txt");
-        FileOutputStream fout = new FileOutputStream(tmpFile);
-        OutputStreamWriter wrtout = new OutputStreamWriter(fout);
+        createTempFile();
+        RandomAccessFile testfile = new RandomAccessFile(this.tmpfile, "rw");
+        testfile.close();
 
-        wrtout.flush();
-        wrtout.close();
-
-        FileChannel fchannel = new FileInputStream(tmpFile).getChannel();
-
-        encoder.transfer(fchannel, 0, 20);
-
-        encoder.write(wrap("more stuff"));
+        testfile = new RandomAccessFile(this.tmpfile, "rw");
+        try {
+            final FileChannel fchannel = testfile.getChannel();
+            encoder.transfer(fchannel, 0, 20);
+            encoder.write(CodecTestUtils.wrap("more stuff"));
+        } finally {
+            testfile.close();
+        }
 
-        String s = baos.toString("US-ASCII");
+        final String s = channel.dump(Consts.ASCII);
 
         Assert.assertTrue(encoder.isCompleted());
         Assert.assertEquals("stuff;more stuff", s);
-
-        fchannel.close();
-        deleteWithCheck(tmpFile);
     }
 
     @Test
     public void testCodingCompletedFromFile() throws Exception {
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        WritableByteChannel channel = newChannel(baos);
-        HttpParams params = new BasicHttpParams();
-        SessionOutputBuffer outbuf = new SessionOutputBufferImpl(1024, 128, params);
-        HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
+        final WritableByteChannelMock channel = new WritableByteChannelMock(64);
+        final SessionOutputBuffer outbuf = new SessionOutputBufferImpl(1024, 128);
+        final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
 
-        LengthDelimitedEncoder encoder = new LengthDelimitedEncoder(
+        final LengthDelimitedEncoder encoder = new LengthDelimitedEncoder(
                 channel, outbuf, metrics, 5);
-        encoder.write(wrap("stuff"));
-
-        File tmpFile = File.createTempFile("testFile", ".txt");
-        FileOutputStream fout = new FileOutputStream(tmpFile);
-        OutputStreamWriter wrtout = new OutputStreamWriter(fout);
+        encoder.write(CodecTestUtils.wrap("stuff"));
 
-        wrtout.write("more stuff");
-
-        wrtout.flush();
-        wrtout.close();
+        createTempFile();
+        RandomAccessFile testfile = new RandomAccessFile(this.tmpfile, "rw");
+        try {
+            testfile.write("more stuff".getBytes("US-ASCII"));
+        } finally {
+            testfile.close();
+        }
 
-        FileChannel fchannel = new FileInputStream(tmpFile).getChannel();
+        testfile = new RandomAccessFile(this.tmpfile, "rw");
         try {
+            final FileChannel fchannel = testfile.getChannel();
             encoder.transfer(fchannel, 0, 10);
             Assert.fail("IllegalStateException should have been thrown");
-        } catch (IllegalStateException ex) {
+        } catch (final IllegalStateException ex) {
             // ignore
         } finally {
-            fchannel.close();
-            deleteWithCheck(tmpFile);
+            testfile.close();
         }
     }
 
     @Test
     public void testCodingFromFileSmaller() throws Exception {
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        WritableByteChannel channel = newChannel(baos);
-        HttpParams params = new BasicHttpParams();
-        SessionOutputBuffer outbuf = new SessionOutputBufferImpl(1024, 128, params);
-        HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
+        final WritableByteChannelMock channel = new WritableByteChannelMock(64);
+        final SessionOutputBuffer outbuf = new SessionOutputBufferImpl(1024, 128);
+        final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
 
-        LengthDelimitedEncoder encoder = new LengthDelimitedEncoder(
+        final LengthDelimitedEncoder encoder = new LengthDelimitedEncoder(
                 channel, outbuf, metrics, 16);
 
-        File tmpFile = File.createTempFile("testFile", ".txt");
-        FileOutputStream fout = new FileOutputStream(tmpFile);
-        OutputStreamWriter wrtout = new OutputStreamWriter(fout);
-
-        wrtout.write("stuff;");
-        wrtout.write("more stuff;");
-
-        wrtout.flush();
-        wrtout.close();
-
-        FileChannel fchannel = new FileInputStream(tmpFile).getChannel();
-
-        encoder.transfer(fchannel, 0, 20);
+        createTempFile();
+        RandomAccessFile testfile = new RandomAccessFile(this.tmpfile, "rw");
+        try {
+            testfile.write("stuff;".getBytes("US-ASCII"));
+            testfile.write("more stuff".getBytes("US-ASCII"));
+        } finally {
+            testfile.close();
+        }
 
-        String s = baos.toString("US-ASCII");
+        testfile = new RandomAccessFile(this.tmpfile, "rw");
+        try {
+            final FileChannel fchannel = testfile.getChannel();
+            encoder.transfer(fchannel, 0, 20);
+        } finally {
+            testfile.close();
+        }
+        final String s = channel.dump(Consts.ASCII);
 
         Assert.assertTrue(encoder.isCompleted());
         Assert.assertEquals("stuff;more stuff", s);
-
-        fchannel.close();
-        deleteWithCheck(tmpFile);
     }
 
     @Test
-    public void testInvalidConstructor() {
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        WritableByteChannel channel = newChannel(baos);
-        HttpParams params = new BasicHttpParams();
-        SessionOutputBuffer outbuf = new SessionOutputBufferImpl(1024, 128, params);
-        HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
+    public void testCodingFromFileFlushBuffer() throws Exception {
+        final WritableByteChannelMock channel = new WritableByteChannelMock(64);
+        final SessionOutputBuffer outbuf = new SessionOutputBufferImpl(1024, 128);
+        final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
+
+        final LengthDelimitedEncoder encoder = new LengthDelimitedEncoder(
+                channel, outbuf, metrics, 16);
 
+        outbuf.writeLine("header");
+
+        createTempFile();
+        RandomAccessFile testfile = new RandomAccessFile(this.tmpfile, "rw");
         try {
-            new LengthDelimitedEncoder(null, null, null, 10);
-            Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
-            // ignore
+            testfile.write("stuff;".getBytes("US-ASCII"));
+            testfile.write("more stuff".getBytes("US-ASCII"));
+        } finally {
+            testfile.close();
         }
+
+        testfile = new RandomAccessFile(this.tmpfile, "rw");
         try {
-            new LengthDelimitedEncoder(channel, null, null, 10);
-            Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
-            // ignore
+            final FileChannel fchannel = testfile.getChannel();
+            encoder.transfer(fchannel, 0, 20);
+        } finally {
+            testfile.close();
         }
+        final String s = channel.dump(Consts.ASCII);
+
+        Assert.assertTrue(encoder.isCompleted());
+        Assert.assertEquals("header\r\nstuff;more stuff", s);
+    }
+
+    @Test
+    public void testCodingFromFileChannelSaturated() throws Exception {
+        final WritableByteChannelMock channel = new WritableByteChannelMock(64, 4);
+        final SessionOutputBuffer outbuf = new SessionOutputBufferImpl(1024, 128);
+        final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
+
+        final LengthDelimitedEncoder encoder = new LengthDelimitedEncoder(
+                channel, outbuf, metrics, 16);
+
+        outbuf.writeLine("header");
+
+        createTempFile();
+        RandomAccessFile testfile = new RandomAccessFile(this.tmpfile, "rw");
         try {
-            new LengthDelimitedEncoder(channel, outbuf, null, 10);
-            Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
-            // ignore
+            testfile.write("stuff".getBytes("US-ASCII"));
+        } finally {
+            testfile.close();
         }
+
+        testfile = new RandomAccessFile(this.tmpfile, "rw");
         try {
-            new LengthDelimitedEncoder(channel, outbuf, metrics, -10);
-            Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
-            // ignore
+            final FileChannel fchannel = testfile.getChannel();
+            encoder.transfer(fchannel, 0, 20);
+            encoder.transfer(fchannel, 0, 20);
+        } finally {
+            testfile.close();
         }
+        final String s = channel.dump(Consts.ASCII);
+
+        Assert.assertFalse(encoder.isCompleted());
+        Assert.assertEquals("head", s);
+    }
+
+    @Test
+    public void testCodingNoFragmentBuffering() throws Exception {
+        final WritableByteChannelMock channel = Mockito.spy(new WritableByteChannelMock(64));
+        final SessionOutputBuffer outbuf = Mockito.spy(new SessionOutputBufferImpl(1024, 128));
+        final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
+
+        outbuf.writeLine("header");
+        final LengthDelimitedEncoder encoder = new LengthDelimitedEncoder(channel, outbuf, metrics,
+            100, 0);
+        Assert.assertEquals(5, encoder.write(CodecTestUtils.wrap("stuff")));
+
+        Mockito.verify(channel, Mockito.times(2)).write(Mockito.<ByteBuffer>any());
+        Mockito.verify(outbuf, Mockito.never()).write(Mockito.<ByteBuffer>any());
+        Mockito.verify(outbuf, Mockito.times(1)).flush(channel);
+
+        Assert.assertEquals(13, metrics.getBytesTransferred());
+
+        outbuf.flush(channel);
+        final String s = channel.dump(Consts.ASCII);
+
+        Assert.assertEquals("header\r\nstuff", s);
+    }
+
+    @Test
+    public void testCodingFragmentBuffering() throws Exception {
+        final WritableByteChannelMock channel = Mockito.spy(new WritableByteChannelMock(64));
+        final SessionOutputBuffer outbuf = Mockito.spy(new SessionOutputBufferImpl(1024, 128));
+        final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
+
+        outbuf.writeLine("header");
+        final LengthDelimitedEncoder encoder = new LengthDelimitedEncoder(channel, outbuf, metrics,
+            100, 32);
+        Assert.assertEquals(5, encoder.write(CodecTestUtils.wrap("stuff")));
+
+        Mockito.verify(channel, Mockito.never()).write(Mockito.<ByteBuffer>any());
+        Mockito.verify(outbuf, Mockito.times(1)).write(Mockito.<ByteBuffer>any());
+        Mockito.verify(outbuf, Mockito.never()).flush(channel);
+
+        Assert.assertEquals(0, metrics.getBytesTransferred());
+
+        outbuf.flush(channel);
+        final String s = channel.dump(Consts.ASCII);
+
+        Assert.assertEquals("header\r\nstuff", s);
+    }
+
+    @Test
+    public void testCodingFragmentBufferingMultipleFragments() throws Exception {
+        final WritableByteChannelMock channel = Mockito.spy(new WritableByteChannelMock(64));
+        final SessionOutputBuffer outbuf = Mockito.spy(new SessionOutputBufferImpl(1024, 128));
+        final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
+
+        final LengthDelimitedEncoder encoder = new LengthDelimitedEncoder(channel, outbuf, metrics,
+            100, 32);
+        Assert.assertEquals(5, encoder.write(CodecTestUtils.wrap("stuff")));
+        Assert.assertEquals(1, encoder.write(CodecTestUtils.wrap("-")));
+        Assert.assertEquals(10, encoder.write(CodecTestUtils.wrap("more stuff")));
+
+        Mockito.verify(channel, Mockito.never()).write(Mockito.<ByteBuffer>any());
+        Mockito.verify(outbuf, Mockito.times(3)).write(Mockito.<ByteBuffer>any());
+        Mockito.verify(outbuf, Mockito.never()).flush(channel);
+
+        Assert.assertEquals(0, metrics.getBytesTransferred());
+
+        outbuf.flush(channel);
+        final String s = channel.dump(Consts.ASCII);
+
+        Assert.assertEquals("stuff-more stuff", s);
+    }
+
+    @Test
+    public void testCodingFragmentBufferingMultipleFragmentsBeyondContentLimit() throws Exception {
+        final WritableByteChannelMock channel = Mockito.spy(new WritableByteChannelMock(64));
+        final SessionOutputBuffer outbuf = Mockito.spy(new SessionOutputBufferImpl(1024, 128));
+        final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
+
+        final LengthDelimitedEncoder encoder = new LengthDelimitedEncoder(channel, outbuf, metrics,
+            16, 32);
+        Assert.assertEquals(5, encoder.write(CodecTestUtils.wrap("stuff")));
+        Assert.assertEquals(1, encoder.write(CodecTestUtils.wrap("-")));
+        Assert.assertEquals(10, encoder.write(CodecTestUtils.wrap("more stuff; and a lot more stuff")));
+
+        Mockito.verify(channel, Mockito.never()).write(Mockito.<ByteBuffer>any());
+        Mockito.verify(outbuf, Mockito.times(3)).write(Mockito.<ByteBuffer>any());
+        Mockito.verify(outbuf, Mockito.never()).flush(channel);
+
+        Assert.assertEquals(0, metrics.getBytesTransferred());
+
+        outbuf.flush(channel);
+        final String s = channel.dump(Consts.ASCII);
+
+        Assert.assertEquals("stuff-more stuff", s);
+    }
+
+    @Test
+    public void testCodingFragmentBufferingLargeFragment() throws Exception {
+        final WritableByteChannelMock channel = Mockito.spy(new WritableByteChannelMock(64));
+        final SessionOutputBuffer outbuf = Mockito.spy(new SessionOutputBufferImpl(1024, 128));
+        final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
+
+        outbuf.writeLine("header");
+        final LengthDelimitedEncoder encoder = new LengthDelimitedEncoder(channel, outbuf, metrics,
+            100, 2);
+        Assert.assertEquals(5, encoder.write(CodecTestUtils.wrap("stuff")));
+
+        Mockito.verify(channel, Mockito.times(2)).write(Mockito.<ByteBuffer>any());
+        Mockito.verify(outbuf, Mockito.never()).write(Mockito.<ByteBuffer>any());
+        Mockito.verify(outbuf, Mockito.times(1)).flush(channel);
+
+        Assert.assertEquals(13, metrics.getBytesTransferred());
+
+        outbuf.flush(channel);
+        final String s = channel.dump(Consts.ASCII);
+        Assert.assertEquals("header\r\nstuff", s);
+    }
+
+    @Test
+    public void testCodingFragmentBufferingTinyFragments() throws Exception {
+        final WritableByteChannelMock channel = Mockito.spy(new WritableByteChannelMock(64));
+        final SessionOutputBuffer outbuf = Mockito.spy(new SessionOutputBufferImpl(1024, 128));
+        final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
+
+        final LengthDelimitedEncoder encoder = new LengthDelimitedEncoder(channel, outbuf, metrics,
+            100, 1);
+        Assert.assertEquals(5, encoder.write(CodecTestUtils.wrap("stuff")));
+        Assert.assertEquals(1, encoder.write(CodecTestUtils.wrap("-")));
+        Assert.assertEquals(1, encoder.write(CodecTestUtils.wrap("-")));
+        Assert.assertEquals(1, encoder.write(CodecTestUtils.wrap("-")));
+        Assert.assertEquals(10, encoder.write(CodecTestUtils.wrap("more stuff")));
+
+        Mockito.verify(channel, Mockito.times(5)).write(Mockito.<ByteBuffer>any());
+        Mockito.verify(outbuf, Mockito.times(3)).write(Mockito.<ByteBuffer>any());
+        Mockito.verify(outbuf, Mockito.times(3)).flush(channel);
+
+        Assert.assertEquals(18, metrics.getBytesTransferred());
+
+        outbuf.flush(channel);
+        final String s = channel.dump(Consts.ASCII);
+
+        Assert.assertEquals("stuff---more stuff", s);
+    }
+
+    @Test
+    public void testCodingFragmentBufferingTinyFragments2() throws Exception {
+        final WritableByteChannelMock channel = Mockito.spy(new WritableByteChannelMock(64));
+        final SessionOutputBuffer outbuf = Mockito.spy(new SessionOutputBufferImpl(1024, 128));
+        final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
+
+        final LengthDelimitedEncoder encoder = new LengthDelimitedEncoder(channel, outbuf, metrics,
+            100, 2);
+        Assert.assertEquals(5, encoder.write(CodecTestUtils.wrap("stuff")));
+        Assert.assertEquals(1, encoder.write(CodecTestUtils.wrap("-")));
+        Assert.assertEquals(1, encoder.write(CodecTestUtils.wrap("-")));
+        Assert.assertEquals(1, encoder.write(CodecTestUtils.wrap("-")));
+        Assert.assertEquals(10, encoder.write(CodecTestUtils.wrap("more stuff")));
+
+        Mockito.verify(channel, Mockito.times(4)).write(Mockito.<ByteBuffer>any());
+        Mockito.verify(outbuf, Mockito.times(3)).write(Mockito.<ByteBuffer>any());
+        Mockito.verify(outbuf, Mockito.times(2)).flush(channel);
+
+        Assert.assertEquals(18, metrics.getBytesTransferred());
+
+        outbuf.flush(channel);
+        final String s = channel.dump(Consts.ASCII);
+
+        Assert.assertEquals("stuff---more stuff", s);
+    }
+
+    @Test
+    public void testCodingFragmentBufferingTinyFragments3() throws Exception {
+        final WritableByteChannelMock channel = Mockito.spy(new WritableByteChannelMock(64));
+        final SessionOutputBuffer outbuf = Mockito.spy(new SessionOutputBufferImpl(1024, 128));
+        final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
+
+        final LengthDelimitedEncoder encoder = new LengthDelimitedEncoder(channel, outbuf, metrics,
+            100, 3);
+        Assert.assertEquals(5, encoder.write(CodecTestUtils.wrap("stuff")));
+        Assert.assertEquals(1, encoder.write(CodecTestUtils.wrap("-")));
+        Assert.assertEquals(1, encoder.write(CodecTestUtils.wrap("-")));
+        Assert.assertEquals(1, encoder.write(CodecTestUtils.wrap("-")));
+        Assert.assertEquals(1, encoder.write(CodecTestUtils.wrap("-")));
+        Assert.assertEquals(2, encoder.write(CodecTestUtils.wrap("--")));
+        Assert.assertEquals(10, encoder.write(CodecTestUtils.wrap("more stuff")));
+
+        Mockito.verify(channel, Mockito.times(4)).write(Mockito.<ByteBuffer>any());
+        Mockito.verify(outbuf, Mockito.times(5)).write(Mockito.<ByteBuffer>any());
+        Mockito.verify(outbuf, Mockito.times(2)).flush(channel);
+
+        Assert.assertEquals(21, metrics.getBytesTransferred());
+
+        outbuf.flush(channel);
+        final String s = channel.dump(Consts.ASCII);
+
+        Assert.assertEquals("stuff------more stuff", s);
+    }
+
+    @Test
+    public void testCodingFragmentBufferingBufferFlush() throws Exception {
+        final WritableByteChannelMock channel = Mockito.spy(new WritableByteChannelMock(64));
+        final SessionOutputBuffer outbuf = Mockito.spy(new SessionOutputBufferImpl(1024, 128));
+        final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
+
+        final LengthDelimitedEncoder encoder = new LengthDelimitedEncoder(channel, outbuf, metrics,
+            100, 8);
+        Assert.assertEquals(5, encoder.write(CodecTestUtils.wrap("stuff")));
+        Assert.assertEquals(6, encoder.write(CodecTestUtils.wrap("-stuff")));
+
+        Mockito.verify(channel, Mockito.times(1)).write(Mockito.<ByteBuffer>any());
+        Mockito.verify(outbuf, Mockito.times(3)).write(Mockito.<ByteBuffer>any());
+        Mockito.verify(outbuf, Mockito.times(1)).flush(channel);
+
+        Assert.assertEquals(8, metrics.getBytesTransferred());
+        Assert.assertEquals(3, outbuf.length());
+
+        outbuf.flush(channel);
+        final String s = channel.dump(Consts.ASCII);
+
+        Assert.assertEquals("stuff-stuff", s);
+    }
+
+    @Test
+    public void testCodingFragmentBufferingBufferFlush2() throws Exception {
+        final WritableByteChannelMock channel = Mockito.spy(new WritableByteChannelMock(64));
+        final SessionOutputBuffer outbuf = Mockito.spy(new SessionOutputBufferImpl(1024, 128));
+        final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
+
+        final LengthDelimitedEncoder encoder = new LengthDelimitedEncoder(channel, outbuf, metrics,
+            100, 8);
+        Assert.assertEquals(5, encoder.write(CodecTestUtils.wrap("stuff")));
+        Assert.assertEquals(16, encoder.write(CodecTestUtils.wrap("-much more stuff")));
+
+        Mockito.verify(channel, Mockito.times(2)).write(Mockito.<ByteBuffer>any());
+        Mockito.verify(outbuf, Mockito.times(1)).write(Mockito.<ByteBuffer>any());
+        Mockito.verify(outbuf, Mockito.times(1)).flush(channel);
+
+        Assert.assertEquals(21, metrics.getBytesTransferred());
+        Assert.assertEquals(0, outbuf.length());
+
+        outbuf.flush(channel);
+        final String s = channel.dump(Consts.ASCII);
+
+        Assert.assertEquals("stuff-much more stuff", s);
+    }
+
+    @Test
+    public void testCodingFragmentBufferingChannelSaturated() throws Exception {
+        final WritableByteChannelMock channel = Mockito.spy(new WritableByteChannelMock(64, 8));
+        final SessionOutputBuffer outbuf = Mockito.spy(new SessionOutputBufferImpl(1024, 128));
+        final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
+
+        final LengthDelimitedEncoder encoder = new LengthDelimitedEncoder(channel, outbuf, metrics,
+            100, 3);
+        Assert.assertEquals(5, encoder.write(CodecTestUtils.wrap("stuff")));
+        Assert.assertEquals(1, encoder.write(CodecTestUtils.wrap("-")));
+        Assert.assertEquals(1, encoder.write(CodecTestUtils.wrap("-")));
+        Assert.assertEquals(1, encoder.write(CodecTestUtils.wrap("-")));
+        Assert.assertEquals(1, encoder.write(CodecTestUtils.wrap("-")));
+        Assert.assertEquals(1, encoder.write(CodecTestUtils.wrap("-")));
+        Assert.assertEquals(1, encoder.write(CodecTestUtils.wrap("-")));
+        Assert.assertEquals(0, encoder.write(CodecTestUtils.wrap("-")));
+        Assert.assertEquals(0, encoder.write(CodecTestUtils.wrap("more stuff")));
+
+        Mockito.verify(channel, Mockito.times(5)).write(Mockito.<ByteBuffer>any());
+        Mockito.verify(outbuf, Mockito.times(6)).write(Mockito.<ByteBuffer>any());
+        Mockito.verify(outbuf, Mockito.times(4)).flush(channel);
+
+        Assert.assertEquals(8, metrics.getBytesTransferred());
+
+        outbuf.flush(channel);
+        final String s = channel.dump(Consts.ASCII);
+
+        Assert.assertEquals("stuff---", s);
+        Assert.assertEquals(3, outbuf.length());
+    }
+
+    @Test
+    public void testCodingFragmentBufferingChannelSaturated2() throws Exception {
+        final WritableByteChannelMock channel = Mockito.spy(new WritableByteChannelMock(64, 8));
+        final SessionOutputBuffer outbuf = Mockito.spy(new SessionOutputBufferImpl(1024, 128));
+        final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
+
+        final LengthDelimitedEncoder encoder = new LengthDelimitedEncoder(channel, outbuf, metrics,
+            100, 8);
+        Assert.assertEquals(5, encoder.write(CodecTestUtils.wrap("stuff")));
+        Assert.assertEquals(1, encoder.write(CodecTestUtils.wrap("-")));
+        Assert.assertEquals(1, encoder.write(CodecTestUtils.wrap("-")));
+        Assert.assertEquals(1, encoder.write(CodecTestUtils.wrap("much more stuff")));
+
+        Mockito.verify(channel, Mockito.times(3)).write(Mockito.<ByteBuffer>any());
+        Mockito.verify(outbuf, Mockito.times(3)).write(Mockito.<ByteBuffer>any());
+        Mockito.verify(outbuf, Mockito.times(1)).flush(channel);
+
+        Assert.assertEquals(8, metrics.getBytesTransferred());
+
+        outbuf.flush(channel);
+        final String s = channel.dump(Consts.ASCII);
+
+        Assert.assertEquals("stuff--m", s);
+        Assert.assertEquals(0, outbuf.length());
     }
 
 }
diff --git a/httpcore-nio/src/test/java/org/apache/http/impl/nio/pool/TestBasicNIOConnPool.java b/httpcore-nio/src/test/java/org/apache/http/impl/nio/pool/TestBasicNIOConnPool.java
index 792daea..7b58374 100644
--- a/httpcore-nio/src/test/java/org/apache/http/impl/nio/pool/TestBasicNIOConnPool.java
+++ b/httpcore-nio/src/test/java/org/apache/http/impl/nio/pool/TestBasicNIOConnPool.java
@@ -27,22 +27,51 @@
 package org.apache.http.impl.nio.pool;
 
 import org.apache.http.HttpHost;
+import org.apache.http.config.ConnectionConfig;
 import org.apache.http.nio.NHttpClientConnection;
+import org.apache.http.nio.pool.NIOConnFactory;
 import org.apache.http.nio.reactor.ConnectingIOReactor;
 import org.apache.http.nio.reactor.IOSession;
-import org.apache.http.params.BasicHttpParams;
-import org.apache.http.params.HttpParams;
+import org.apache.http.nio.reactor.SessionRequest;
+import org.apache.http.nio.reactor.SessionRequestCallback;
 import org.junit.After;
+import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
 import org.mockito.Mock;
+import org.mockito.Mockito;
 import org.mockito.MockitoAnnotations;
 
+import java.net.SocketAddress;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+
 public class TestBasicNIOConnPool {
 
-    private HttpParams params;
+    static class LocalPool extends BasicNIOConnPool {
+
+        public LocalPool(
+                final ConnectingIOReactor ioreactor,
+                final NIOConnFactory<HttpHost, NHttpClientConnection> connFactory,
+                final int connectTimeout) {
+            super(ioreactor, connFactory, connectTimeout);
+        }
+
+        public LocalPool(
+                final ConnectingIOReactor ioreactor,
+                final ConnectionConfig config) {
+            super(ioreactor, config);
+        }
+
+        @Override
+        public void requestCompleted(final SessionRequest request) {
+            super.requestCompleted(request);
+        }
+
+    }
+
     private BasicNIOConnFactory connFactory;
-    private BasicNIOConnPool pool;
+    private LocalPool pool;
     private HttpHost route;
     @Mock private ConnectingIOReactor reactor;
     @Mock private IOSession session;
@@ -52,9 +81,8 @@ public class TestBasicNIOConnPool {
         MockitoAnnotations.initMocks(this);
 
         route = new HttpHost("localhost", 80, "http");
-        params = new BasicHttpParams();
-        connFactory = new BasicNIOConnFactory(params);
-        pool = new BasicNIOConnPool(reactor, connFactory, params);
+        connFactory = new BasicNIOConnFactory(ConnectionConfig.DEFAULT);
+        pool = new LocalPool(reactor, connFactory, 0);
     }
 
     @After
@@ -63,12 +91,7 @@ public class TestBasicNIOConnPool {
 
     @Test(expected=IllegalArgumentException.class)
     public void testNullConstructor() throws Exception {
-        pool = new BasicNIOConnPool(null, new BasicHttpParams());
-    }
-
-    @Test(expected=IllegalArgumentException.class)
-    public void testNullConstructor2() throws Exception {
-        pool = new BasicNIOConnPool(reactor, null);
+        pool = new LocalPool(null, ConnectionConfig.DEFAULT);
     }
 
     @Test
@@ -78,8 +101,53 @@ public class TestBasicNIOConnPool {
 
     @Test
     public void testCreateEntry() throws Exception {
-        NHttpClientConnection conn = connFactory.create(route, session);
-        BasicNIOPoolEntry entry = pool.createEntry(route, conn);
+        final NHttpClientConnection conn = connFactory.create(route, session);
+        final BasicNIOPoolEntry entry = pool.createEntry(route, conn);
         entry.close();
     }
+
+    @Test
+    public void testTimeoutOnLeaseRelease() throws Exception {
+        final HttpHost host = new HttpHost("somehost");
+        final SessionRequest sessionRequest = Mockito.mock(SessionRequest.class);
+        Mockito.when(sessionRequest.getSession()).thenReturn(session);
+        Mockito.when(sessionRequest.getAttachment()).thenReturn(host);
+        Mockito.when(reactor.connect(
+                Mockito.any(SocketAddress.class),
+                Mockito.any(SocketAddress.class),
+                Mockito.eq(host),
+                Mockito.any(SessionRequestCallback.class))).
+                thenReturn(sessionRequest);
+
+        Mockito.when(session.getSocketTimeout()).thenReturn(999);
+
+        final Future<BasicNIOPoolEntry> future1 = pool.lease(host, null, 10, TimeUnit.SECONDS, null);
+        Mockito.verify(sessionRequest).setConnectTimeout(10000);
+
+        pool.requestCompleted(sessionRequest);
+
+        final BasicNIOPoolEntry entry1 = future1.get();
+        final NHttpClientConnection conn1 = entry1.getConnection();
+        Assert.assertNotNull(entry1);
+        Assert.assertNotNull(conn1);
+        Assert.assertEquals(999, entry1.getSocketTimeout());
+        Assert.assertEquals(999, conn1.getSocketTimeout());
+
+        Mockito.when(session.getSocketTimeout()).thenReturn(888);
+
+        pool.release(entry1, true);
+        Assert.assertEquals(888, entry1.getSocketTimeout());
+        Mockito.verify(session).setSocketTimeout(0);
+
+        final Future<BasicNIOPoolEntry> future2 = pool.lease(host, null, 10, TimeUnit.SECONDS, null);
+        final BasicNIOPoolEntry entry2 = future2.get();
+        final NHttpClientConnection conn2 = entry2.getConnection();
+        Assert.assertNotNull(entry2);
+        Assert.assertNotNull(conn2);
+
+        Assert.assertEquals(888, entry1.getSocketTimeout());
+        Mockito.verify(session).setSocketTimeout(888);
+    }
+
+
 }
diff --git a/httpcore-nio/src/test/java/org/apache/http/impl/nio/reactor/ExceptionEventTest.java b/httpcore-nio/src/test/java/org/apache/http/impl/nio/reactor/ExceptionEventTest.java
index 5ccb5ba..0292f6d 100644
--- a/httpcore-nio/src/test/java/org/apache/http/impl/nio/reactor/ExceptionEventTest.java
+++ b/httpcore-nio/src/test/java/org/apache/http/impl/nio/reactor/ExceptionEventTest.java
@@ -36,7 +36,7 @@ public class ExceptionEventTest {
 
     @Test
     public void testGetCause() {
-        NullPointerException npe = new NullPointerException("npe");
+        final NullPointerException npe = new NullPointerException("npe");
         ExceptionEvent ee = new ExceptionEvent(npe);
         Assert.assertSame(npe, ee.getCause());
         ee = new ExceptionEvent(npe, new Date());
@@ -45,7 +45,7 @@ public class ExceptionEventTest {
 
     @Test
     public void testGetTimestamp() {
-        NullPointerException npe = new NullPointerException("npe");
+        final NullPointerException npe = new NullPointerException("npe");
         ExceptionEvent ee = new ExceptionEvent(npe);
         Assert.assertNotNull(ee.getTimestamp());
         ee = new ExceptionEvent(npe, new Date(1234567890L));
diff --git a/httpcore-nio/src/test/java/org/apache/http/impl/nio/reactor/TestBaseIOReactorSSL.java b/httpcore-nio/src/test/java/org/apache/http/impl/nio/reactor/TestBaseIOReactorSSL.java
deleted file mode 100644
index 552ffad..0000000
--- a/httpcore-nio/src/test/java/org/apache/http/impl/nio/reactor/TestBaseIOReactorSSL.java
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * ====================================================================
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- *
- */
-package org.apache.http.impl.nio.reactor;
-
-import java.io.BufferedWriter;
-import java.io.IOException;
-import java.io.OutputStreamWriter;
-import java.net.InetSocketAddress;
-import java.net.Socket;
-import java.net.URL;
-import java.security.KeyStore;
-import java.security.NoSuchAlgorithmException;
-
-import javax.net.ssl.SSLContext;
-import javax.net.ssl.TrustManager;
-import javax.net.ssl.TrustManagerFactory;
-
-import org.apache.http.HttpCoreNIOTestBase;
-import org.apache.http.HttpException;
-import org.apache.http.HttpRequest;
-import org.apache.http.HttpResponse;
-import org.apache.http.LoggingSSLClientConnectionFactory;
-import org.apache.http.LoggingSSLServerConnectionFactory;
-import org.apache.http.SSLTestContexts;
-import org.apache.http.impl.DefaultConnectionReuseStrategy;
-import org.apache.http.impl.DefaultHttpResponseFactory;
-import org.apache.http.impl.nio.DefaultNHttpClientConnection;
-import org.apache.http.impl.nio.DefaultNHttpServerConnection;
-import org.apache.http.nio.NHttpConnectionFactory;
-import org.apache.http.nio.NHttpServiceHandler;
-import org.apache.http.nio.protocol.BufferingHttpServiceHandler;
-import org.apache.http.nio.protocol.EventListener;
-import org.apache.http.nio.reactor.ListenerEndpoint;
-import org.apache.http.params.HttpParams;
-import org.apache.http.protocol.HttpContext;
-import org.apache.http.protocol.HttpExpectationVerifier;
-import org.apache.http.protocol.HttpRequestHandler;
-import org.apache.http.testserver.SimpleHttpRequestHandlerResolver;
-import org.junit.After;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-
- at Deprecated
-public class TestBaseIOReactorSSL extends HttpCoreNIOTestBase {
-
-    @Before
-    public void setUp() throws Exception {
-        initServer();
-    }
-
-    @After
-    public void tearDown() throws Exception {
-        shutDownServer();
-    }
-
-    @Override
-    protected NHttpConnectionFactory<DefaultNHttpServerConnection> createServerConnectionFactory(
-            final HttpParams params) throws Exception {
-        return new LoggingSSLServerConnectionFactory(SSLTestContexts.createServerSSLContext(), params);
-    }
-
-    @Override
-    protected NHttpConnectionFactory<DefaultNHttpClientConnection> createClientConnectionFactory(
-            final HttpParams params) throws Exception {
-        return new LoggingSSLClientConnectionFactory(SSLTestContexts.createClientSSLContext(), params);
-    }
-
-    private NHttpServiceHandler createHttpServiceHandler(
-            final HttpRequestHandler requestHandler,
-            final HttpExpectationVerifier expectationVerifier,
-            final EventListener eventListener) {
-        BufferingHttpServiceHandler serviceHandler = new BufferingHttpServiceHandler(
-                this.serverHttpProc,
-                new DefaultHttpResponseFactory(),
-                new DefaultConnectionReuseStrategy(),
-                this.serverParams);
-
-        serviceHandler.setHandlerResolver(
-                new SimpleHttpRequestHandlerResolver(requestHandler));
-        serviceHandler.setExpectationVerifier(expectationVerifier);
-        serviceHandler.setEventListener(eventListener);
-
-        return serviceHandler;
-    }
-
-    private TrustManagerFactory createTrustManagerFactory() throws NoSuchAlgorithmException {
-        String algo = TrustManagerFactory.getDefaultAlgorithm();
-        try {
-            return TrustManagerFactory.getInstance(algo);
-        } catch (NoSuchAlgorithmException ex) {
-            return TrustManagerFactory.getInstance("SunX509");
-        }
-    }
-
-    @Test
-    public void testBufferedInput() throws Exception {
-        final int[] result = new int[1];
-        HttpRequestHandler requestHandler = new HttpRequestHandler() {
-            public void handle(HttpRequest request, HttpResponse response,
-                    HttpContext context) throws HttpException, IOException {
-                result[0]++;
-                synchronized (result) {
-                    result.notify();
-                }
-            }
-        };
-
-        NHttpServiceHandler serviceHandler = createHttpServiceHandler(
-                requestHandler,
-                null,
-                null);
-
-        this.server.start(serviceHandler);
-
-        ClassLoader cl = getClass().getClassLoader();
-        URL url = cl.getResource("test.keystore");
-        KeyStore keystore  = KeyStore.getInstance("jks");
-        keystore.load(url.openStream(), "nopassword".toCharArray());
-        TrustManagerFactory tmfactory = createTrustManagerFactory();
-        tmfactory.init(keystore);
-        TrustManager[] trustmanagers = tmfactory.getTrustManagers();
-        SSLContext sslcontext = SSLContext.getInstance("TLS");
-        sslcontext.init(null, trustmanagers, null);
-
-        ListenerEndpoint endpoint = this.server.getListenerEndpoint();
-        endpoint.waitFor();
-        InetSocketAddress serverAddress = (InetSocketAddress) endpoint.getAddress();
-
-        Socket socket = sslcontext.getSocketFactory().createSocket("localhost", serverAddress.getPort());
-        BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
-        //            123456789012345678901234567890
-        writer.write("GET / HTTP/1.1\r\n");
-        writer.write("Header:                   \r\n");
-        writer.write("Header:                   \r\n");
-        writer.write("Header:                   \r\n");
-        writer.write("\r\n");
-        writer.flush();
-
-        synchronized (result) {
-            result.wait(500);
-        }
-        Assert.assertEquals(1, result[0]);
-    }
-
-}
diff --git a/httpcore-nio/src/test/java/org/apache/http/impl/nio/reactor/TestDefaultIOReactors.java b/httpcore-nio/src/test/java/org/apache/http/impl/nio/reactor/TestDefaultIOReactors.java
index 1de87a2..3274c47 100644
--- a/httpcore-nio/src/test/java/org/apache/http/impl/nio/reactor/TestDefaultIOReactors.java
+++ b/httpcore-nio/src/test/java/org/apache/http/impl/nio/reactor/TestDefaultIOReactors.java
@@ -37,15 +37,11 @@ import java.util.concurrent.Future;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicInteger;
 
-import org.apache.http.HttpCoreNIOTestBase;
 import org.apache.http.HttpException;
 import org.apache.http.HttpHost;
 import org.apache.http.HttpRequest;
 import org.apache.http.HttpResponse;
-import org.apache.http.LoggingClientConnectionFactory;
-import org.apache.http.LoggingServerConnectionFactory;
 import org.apache.http.OoopsieRuntimeException;
-import org.apache.http.impl.DefaultConnectionReuseStrategy;
 import org.apache.http.impl.nio.DefaultNHttpClientConnection;
 import org.apache.http.impl.nio.DefaultNHttpServerConnection;
 import org.apache.http.impl.nio.pool.BasicNIOPoolEntry;
@@ -53,17 +49,18 @@ import org.apache.http.message.BasicHttpRequest;
 import org.apache.http.nio.NHttpClientConnection;
 import org.apache.http.nio.NHttpConnectionFactory;
 import org.apache.http.nio.NHttpServerConnection;
-import org.apache.http.nio.protocol.BasicAsyncRequestProducer;
-import org.apache.http.nio.protocol.BasicAsyncResponseConsumer;
 import org.apache.http.nio.protocol.BasicAsyncRequestHandler;
 import org.apache.http.nio.protocol.HttpAsyncRequestExecutor;
-import org.apache.http.nio.protocol.HttpAsyncRequestHandlerRegistry;
 import org.apache.http.nio.protocol.HttpAsyncService;
+import org.apache.http.nio.protocol.UriHttpAsyncRequestHandlerMapper;
 import org.apache.http.nio.reactor.IOReactorException;
 import org.apache.http.nio.reactor.IOReactorExceptionHandler;
 import org.apache.http.nio.reactor.IOReactorStatus;
 import org.apache.http.nio.reactor.ListenerEndpoint;
-import org.apache.http.params.HttpParams;
+import org.apache.http.nio.testserver.HttpCoreNIOTestBase;
+import org.apache.http.nio.testserver.HttpServerNio;
+import org.apache.http.nio.testserver.LoggingClientConnectionFactory;
+import org.apache.http.nio.testserver.LoggingServerConnectionFactory;
 import org.apache.http.protocol.HttpContext;
 import org.apache.http.protocol.HttpRequestHandler;
 import org.junit.After;
@@ -80,26 +77,22 @@ public class TestDefaultIOReactors extends HttpCoreNIOTestBase {
     public void setUp() throws Exception {
         initServer();
         initClient();
-        initConnPool();
     }
 
     @After
     public void tearDown() throws Exception {
-        shutDownConnPool();
         shutDownClient();
         shutDownServer();
     }
 
     @Override
-    protected NHttpConnectionFactory<DefaultNHttpServerConnection> createServerConnectionFactory(
-            final HttpParams params) throws Exception {
-        return new LoggingServerConnectionFactory(params);
+    protected NHttpConnectionFactory<DefaultNHttpServerConnection> createServerConnectionFactory() throws Exception {
+        return new LoggingServerConnectionFactory();
     }
 
     @Override
-    protected NHttpConnectionFactory<DefaultNHttpClientConnection> createClientConnectionFactory(
-            final HttpParams params) throws Exception {
-        return new LoggingClientConnectionFactory(params);
+    protected NHttpConnectionFactory<DefaultNHttpClientConnection> createClientConnectionFactory() throws Exception {
+        return new LoggingClientConnectionFactory();
     }
 
     @Test
@@ -110,15 +103,12 @@ public class TestDefaultIOReactors extends HttpCoreNIOTestBase {
         final AtomicInteger closedClientConns = new AtomicInteger(0);
         final AtomicInteger closedServerConns = new AtomicInteger(0);
 
-        this.connpool.setDefaultMaxPerRoute(connNo);
-        this.connpool.setMaxTotal(connNo);
+        this.client.setMaxPerRoute(connNo);
+        this.client.setMaxTotal(connNo);
 
-        HttpAsyncRequestHandlerRegistry registry = new HttpAsyncRequestHandlerRegistry();
-        HttpAsyncService serviceHandler = new HttpAsyncService(
-                this.serverHttpProc,
-                new DefaultConnectionReuseStrategy(),
-                registry,
-                this.serverParams) {
+        final UriHttpAsyncRequestHandlerMapper registry = new UriHttpAsyncRequestHandlerMapper();
+        final HttpAsyncService serviceHandler = new HttpAsyncService(
+                HttpServerNio.DEFAULT_HTTP_PROC, registry) {
 
             @Override
             public void connected(final NHttpServerConnection conn) {
@@ -133,7 +123,7 @@ public class TestDefaultIOReactors extends HttpCoreNIOTestBase {
             }
 
         };
-        HttpAsyncRequestExecutor clientHandler = new HttpAsyncRequestExecutor() {
+        final HttpAsyncRequestExecutor clientHandler = new HttpAsyncRequestExecutor() {
 
             @Override
             public void connected(
@@ -153,21 +143,21 @@ public class TestDefaultIOReactors extends HttpCoreNIOTestBase {
         this.server.start(serviceHandler);
         this.client.start(clientHandler);
 
-        ListenerEndpoint endpoint = this.server.getListenerEndpoint();
+        final ListenerEndpoint endpoint = this.server.getListenerEndpoint();
         endpoint.waitFor();
-        InetSocketAddress address = (InetSocketAddress) endpoint.getAddress();
-        HttpHost target = new HttpHost("localhost", address.getPort());
+        final InetSocketAddress address = (InetSocketAddress) endpoint.getAddress();
+        final HttpHost target = new HttpHost("localhost", address.getPort());
 
         Assert.assertEquals("Test server status", IOReactorStatus.ACTIVE, this.server.getStatus());
 
-        Queue<Future<BasicNIOPoolEntry>> queue = new LinkedList<Future<BasicNIOPoolEntry>>();
+        final Queue<Future<BasicNIOPoolEntry>> queue = new LinkedList<Future<BasicNIOPoolEntry>>();
         for (int i = 0; i < connNo; i++) {
-            queue.add(this.connpool.lease(target, null));
+            queue.add(this.client.lease(target, null));
         }
 
         while (!queue.isEmpty()) {
-            Future<BasicNIOPoolEntry> future = queue.remove();
-            BasicNIOPoolEntry poolEntry = future.get();
+            final Future<BasicNIOPoolEntry> future = queue.remove();
+            final BasicNIOPoolEntry poolEntry = future.get();
             Assert.assertNotNull(poolEntry);
         }
 
@@ -176,7 +166,6 @@ public class TestDefaultIOReactors extends HttpCoreNIOTestBase {
         openClientConns.await(15, TimeUnit.SECONDS);
         openServerConns.await(15, TimeUnit.SECONDS);
 
-        this.connpool.shutdown(2000);
         this.client.shutdown();
         this.server.shutdown();
 
@@ -187,7 +176,7 @@ public class TestDefaultIOReactors extends HttpCoreNIOTestBase {
     @Test
     public void testRuntimeException() throws Exception {
 
-        HttpRequestHandler requestHandler = new HttpRequestHandler() {
+        final HttpRequestHandler requestHandler = new HttpRequestHandler() {
 
             public void handle(
                     final HttpRequest request,
@@ -198,13 +187,10 @@ public class TestDefaultIOReactors extends HttpCoreNIOTestBase {
 
         };
 
-        HttpAsyncRequestHandlerRegistry registry = new HttpAsyncRequestHandlerRegistry();
+        final UriHttpAsyncRequestHandlerMapper registry = new UriHttpAsyncRequestHandlerMapper();
         registry.register("*", new BasicAsyncRequestHandler(requestHandler));
-        HttpAsyncService serviceHandler = new HttpAsyncService(
-                this.serverHttpProc,
-                new DefaultConnectionReuseStrategy(),
-                registry,
-                this.serverParams) {
+        final HttpAsyncService serviceHandler = new HttpAsyncService(
+                HttpServerNio.DEFAULT_HTTP_PROC, registry) {
 
                     @Override
                     public void exception(
@@ -217,32 +203,28 @@ public class TestDefaultIOReactors extends HttpCoreNIOTestBase {
                     }
 
         };
-        HttpAsyncRequestExecutor clientHandler = new HttpAsyncRequestExecutor();
         this.server.start(serviceHandler);
-        this.client.start(clientHandler);
+        this.client.start();
 
-        ListenerEndpoint endpoint = this.server.getListenerEndpoint();
+        final ListenerEndpoint endpoint = this.server.getListenerEndpoint();
         endpoint.waitFor();
-        InetSocketAddress address = (InetSocketAddress) endpoint.getAddress();
-        HttpHost target = new HttpHost("localhost", address.getPort());
+        final InetSocketAddress address = (InetSocketAddress) endpoint.getAddress();
+        final HttpHost target = new HttpHost("localhost", address.getPort());
 
         Assert.assertEquals("Test server status", IOReactorStatus.ACTIVE, this.server.getStatus());
 
-        BasicHttpRequest request = new BasicHttpRequest("GET", "/");
-        this.executor.execute(
-                new BasicAsyncRequestProducer(target, request),
-                new BasicAsyncResponseConsumer(),
-                this.connpool);
+        final BasicHttpRequest request = new BasicHttpRequest("GET", "/");
+        this.client.execute(target, request);
 
         this.server.join(20000);
 
-        Exception ex = this.server.getException();
+        final Exception ex = this.server.getException();
         Assert.assertNotNull(ex);
         Assert.assertTrue(ex instanceof IOReactorException);
         Assert.assertNotNull(ex.getCause());
         Assert.assertTrue(ex.getCause() instanceof OoopsieRuntimeException);
 
-        List<ExceptionEvent> auditlog = this.server.getAuditLog();
+        final List<ExceptionEvent> auditlog = this.server.getAuditLog();
         Assert.assertNotNull(auditlog);
         Assert.assertEquals(1, auditlog.size());
 
@@ -257,7 +239,7 @@ public class TestDefaultIOReactors extends HttpCoreNIOTestBase {
     public void testUnhandledRuntimeException() throws Exception {
         final CountDownLatch requestConns = new CountDownLatch(1);
 
-        HttpRequestHandler requestHandler = new HttpRequestHandler() {
+        final HttpRequestHandler requestHandler = new HttpRequestHandler() {
 
             public void handle(
                     final HttpRequest request,
@@ -268,7 +250,7 @@ public class TestDefaultIOReactors extends HttpCoreNIOTestBase {
 
         };
 
-        IOReactorExceptionHandler exceptionHandler = new IOReactorExceptionHandler() {
+        final IOReactorExceptionHandler exceptionHandler = new IOReactorExceptionHandler() {
 
             public boolean handle(final IOException ex) {
                 return false;
@@ -281,13 +263,10 @@ public class TestDefaultIOReactors extends HttpCoreNIOTestBase {
 
         };
 
-        HttpAsyncRequestHandlerRegistry registry = new HttpAsyncRequestHandlerRegistry();
+        final UriHttpAsyncRequestHandlerMapper registry = new UriHttpAsyncRequestHandlerMapper();
         registry.register("*", new BasicAsyncRequestHandler(requestHandler));
-        HttpAsyncService serviceHandler = new HttpAsyncService(
-                this.serverHttpProc,
-                new DefaultConnectionReuseStrategy(),
-                registry,
-                this.serverParams) {
+        final HttpAsyncService serviceHandler = new HttpAsyncService(
+                HttpServerNio.DEFAULT_HTTP_PROC, registry) {
 
             @Override
             public void exception(
@@ -300,33 +279,29 @@ public class TestDefaultIOReactors extends HttpCoreNIOTestBase {
             }
 
         };
-        HttpAsyncRequestExecutor clientHandler = new HttpAsyncRequestExecutor();
         this.server.setExceptionHandler(exceptionHandler);
         this.server.start(serviceHandler);
-        this.client.start(clientHandler);
+        this.client.start();
 
-        ListenerEndpoint endpoint = this.server.getListenerEndpoint();
+        final ListenerEndpoint endpoint = this.server.getListenerEndpoint();
         endpoint.waitFor();
-        InetSocketAddress address = (InetSocketAddress) endpoint.getAddress();
-        HttpHost target = new HttpHost("localhost", address.getPort());
+        final InetSocketAddress address = (InetSocketAddress) endpoint.getAddress();
+        final HttpHost target = new HttpHost("localhost", address.getPort());
 
         Assert.assertEquals("Test server status", IOReactorStatus.ACTIVE, this.server.getStatus());
 
-        BasicHttpRequest request = new BasicHttpRequest("GET", "/");
-        this.executor.execute(
-                new BasicAsyncRequestProducer(target, request),
-                new BasicAsyncResponseConsumer(),
-                this.connpool);
+        final BasicHttpRequest request = new BasicHttpRequest("GET", "/");
+        this.client.execute(target, request);
 
         this.server.join(20000);
 
-        Exception ex = this.server.getException();
+        final Exception ex = this.server.getException();
         Assert.assertNotNull(ex);
         Assert.assertTrue(ex instanceof IOReactorException);
         Assert.assertNotNull(ex.getCause());
         Assert.assertTrue(ex.getCause() instanceof OoopsieRuntimeException);
 
-        List<ExceptionEvent> auditlog = this.server.getAuditLog();
+        final List<ExceptionEvent> auditlog = this.server.getAuditLog();
         Assert.assertNotNull(auditlog);
         Assert.assertEquals(1, auditlog.size());
 
@@ -341,7 +316,7 @@ public class TestDefaultIOReactors extends HttpCoreNIOTestBase {
     public void testHandledRuntimeException() throws Exception {
         final CountDownLatch requestConns = new CountDownLatch(1);
 
-        HttpRequestHandler requestHandler = new HttpRequestHandler() {
+        final HttpRequestHandler requestHandler = new HttpRequestHandler() {
 
             public void handle(
                     final HttpRequest request,
@@ -352,7 +327,7 @@ public class TestDefaultIOReactors extends HttpCoreNIOTestBase {
 
         };
 
-        IOReactorExceptionHandler exceptionHandler = new IOReactorExceptionHandler() {
+        final IOReactorExceptionHandler exceptionHandler = new IOReactorExceptionHandler() {
 
             public boolean handle(final IOException ex) {
                 return false;
@@ -365,13 +340,10 @@ public class TestDefaultIOReactors extends HttpCoreNIOTestBase {
 
         };
 
-        HttpAsyncRequestHandlerRegistry registry = new HttpAsyncRequestHandlerRegistry();
+        final UriHttpAsyncRequestHandlerMapper registry = new UriHttpAsyncRequestHandlerMapper();
         registry.register("*", new BasicAsyncRequestHandler(requestHandler));
-        HttpAsyncService serviceHandler = new HttpAsyncService(
-                this.serverHttpProc,
-                new DefaultConnectionReuseStrategy(),
-                registry,
-                this.serverParams) {
+        final HttpAsyncService serviceHandler = new HttpAsyncService(
+                HttpServerNio.DEFAULT_HTTP_PROC, registry) {
 
             @Override
             public void exception(
@@ -384,23 +356,19 @@ public class TestDefaultIOReactors extends HttpCoreNIOTestBase {
             }
 
         };
-        HttpAsyncRequestExecutor clientHandler = new HttpAsyncRequestExecutor();
         this.server.setExceptionHandler(exceptionHandler);
         this.server.start(serviceHandler);
-        this.client.start(clientHandler);
+        this.client.start();
 
-        ListenerEndpoint endpoint = this.server.getListenerEndpoint();
+        final ListenerEndpoint endpoint = this.server.getListenerEndpoint();
         endpoint.waitFor();
-        InetSocketAddress address = (InetSocketAddress) endpoint.getAddress();
-        HttpHost target = new HttpHost("localhost", address.getPort());
+        final InetSocketAddress address = (InetSocketAddress) endpoint.getAddress();
+        final HttpHost target = new HttpHost("localhost", address.getPort());
 
         Assert.assertEquals("Test server status", IOReactorStatus.ACTIVE, this.server.getStatus());
 
-        BasicHttpRequest request = new BasicHttpRequest("GET", "/");
-        this.executor.execute(
-                new BasicAsyncRequestProducer(target, request),
-                new BasicAsyncResponseConsumer(),
-                this.connpool);
+        final BasicHttpRequest request = new BasicHttpRequest("GET", "/");
+        this.client.execute(target, request);
 
         requestConns.await();
         Assert.assertEquals(0, requestConns.getCount());
diff --git a/httpcore-nio/src/test/java/org/apache/http/impl/nio/reactor/TestDefaultIOReactorsSSL.java b/httpcore-nio/src/test/java/org/apache/http/impl/nio/reactor/TestDefaultIOReactorsSSL.java
index dd01b0d..7d15cef 100644
--- a/httpcore-nio/src/test/java/org/apache/http/impl/nio/reactor/TestDefaultIOReactorsSSL.java
+++ b/httpcore-nio/src/test/java/org/apache/http/impl/nio/reactor/TestDefaultIOReactorsSSL.java
@@ -27,13 +27,12 @@
 
 package org.apache.http.impl.nio.reactor;
 
-import org.apache.http.LoggingSSLClientConnectionFactory;
-import org.apache.http.LoggingSSLServerConnectionFactory;
-import org.apache.http.SSLTestContexts;
 import org.apache.http.impl.nio.DefaultNHttpClientConnection;
 import org.apache.http.impl.nio.DefaultNHttpServerConnection;
 import org.apache.http.nio.NHttpConnectionFactory;
-import org.apache.http.params.HttpParams;
+import org.apache.http.nio.testserver.LoggingSSLClientConnectionFactory;
+import org.apache.http.nio.testserver.LoggingSSLServerConnectionFactory;
+import org.apache.http.nio.testserver.SSLTestContexts;
 
 /**
  * Basic functionality tests for SSL I/O reactors.
@@ -42,15 +41,13 @@ import org.apache.http.params.HttpParams;
 public class TestDefaultIOReactorsSSL extends TestDefaultIOReactors {
 
     @Override
-    protected NHttpConnectionFactory<DefaultNHttpServerConnection> createServerConnectionFactory(
-            final HttpParams params) throws Exception {
-        return new LoggingSSLServerConnectionFactory(SSLTestContexts.createServerSSLContext(), params);
+    protected NHttpConnectionFactory<DefaultNHttpServerConnection> createServerConnectionFactory() throws Exception {
+        return new LoggingSSLServerConnectionFactory(SSLTestContexts.createServerSSLContext());
     }
 
     @Override
-    protected NHttpConnectionFactory<DefaultNHttpClientConnection> createClientConnectionFactory(
-            final HttpParams params) throws Exception {
-        return new LoggingSSLClientConnectionFactory(SSLTestContexts.createClientSSLContext(), params);
+    protected NHttpConnectionFactory<DefaultNHttpClientConnection> createClientConnectionFactory() throws Exception {
+        return new LoggingSSLClientConnectionFactory(SSLTestContexts.createClientSSLContext());
     }
 
 }
diff --git a/httpcore-nio/src/test/java/org/apache/http/impl/nio/reactor/TestDefaultListeningIOReactor.java b/httpcore-nio/src/test/java/org/apache/http/impl/nio/reactor/TestDefaultListeningIOReactor.java
index 046cf61..3de3471 100644
--- a/httpcore-nio/src/test/java/org/apache/http/impl/nio/reactor/TestDefaultListeningIOReactor.java
+++ b/httpcore-nio/src/test/java/org/apache/http/impl/nio/reactor/TestDefaultListeningIOReactor.java
@@ -35,17 +35,15 @@ import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
 
 import org.apache.http.HttpResponseInterceptor;
-import org.apache.http.impl.DefaultConnectionReuseStrategy;
+import org.apache.http.config.ConnectionConfig;
 import org.apache.http.impl.nio.DefaultHttpServerIODispatch;
-import org.apache.http.nio.protocol.HttpAsyncRequestHandlerRegistry;
 import org.apache.http.nio.protocol.HttpAsyncService;
+import org.apache.http.nio.protocol.UriHttpAsyncRequestHandlerMapper;
 import org.apache.http.nio.reactor.IOEventDispatch;
 import org.apache.http.nio.reactor.IOReactorExceptionHandler;
 import org.apache.http.nio.reactor.IOReactorStatus;
 import org.apache.http.nio.reactor.ListenerEndpoint;
 import org.apache.http.nio.reactor.ListeningIOReactor;
-import org.apache.http.params.HttpParams;
-import org.apache.http.params.SyncBasicHttpParams;
 import org.apache.http.protocol.HttpProcessor;
 import org.apache.http.protocol.ImmutableHttpProcessor;
 import org.apache.http.protocol.ResponseConnControl;
@@ -61,34 +59,29 @@ import org.junit.Test;
 public class TestDefaultListeningIOReactor {
 
     private static IOEventDispatch createIOEventDispatch() {
-        HttpParams params = new SyncBasicHttpParams();
-        HttpProcessor httpproc = new ImmutableHttpProcessor(new HttpResponseInterceptor[] {
+        final HttpProcessor httpproc = new ImmutableHttpProcessor(new HttpResponseInterceptor[] {
                 new ResponseDate(),
                 new ResponseServer(),
                 new ResponseContent(),
                 new ResponseConnControl()
         });
-        HttpAsyncService serviceHandler = new HttpAsyncService(
-                httpproc,
-                new DefaultConnectionReuseStrategy(),
-                new HttpAsyncRequestHandlerRegistry(),
-                params);
-        return new DefaultHttpServerIODispatch(serviceHandler, params);
+        final HttpAsyncService serviceHandler = new HttpAsyncService(httpproc,
+                new UriHttpAsyncRequestHandlerMapper());
+        return new DefaultHttpServerIODispatch(serviceHandler, ConnectionConfig.DEFAULT);
     }
 
     @Test
     public void testEndpointUpAndDown() throws Exception {
         final IOEventDispatch eventDispatch = createIOEventDispatch();
-        IOReactorConfig config = new IOReactorConfig();
-        config.setIoThreadCount(1);
+        final IOReactorConfig config = IOReactorConfig.custom().setIoThreadCount(1).build();
         final ListeningIOReactor ioreactor = new DefaultListeningIOReactor(config);
 
-        Thread t = new Thread(new Runnable() {
+        final Thread t = new Thread(new Runnable() {
 
             public void run() {
                 try {
                     ioreactor.execute(eventDispatch);
-                } catch (IOException ex) {
+                } catch (final IOException ex) {
                 }
             }
 
@@ -100,12 +93,12 @@ public class TestDefaultListeningIOReactor {
         Assert.assertNotNull(endpoints);
         Assert.assertEquals(0, endpoints.size());
 
-        ListenerEndpoint endpoint1 = ioreactor.listen(new InetSocketAddress(0));
+        final ListenerEndpoint endpoint1 = ioreactor.listen(new InetSocketAddress(0));
         endpoint1.waitFor();
 
-        ListenerEndpoint endpoint2 = ioreactor.listen(new InetSocketAddress(0));
+        final ListenerEndpoint endpoint2 = ioreactor.listen(new InetSocketAddress(0));
         endpoint2.waitFor();
-        int port = ((InetSocketAddress) endpoint2.getAddress()).getPort();
+        final int port = ((InetSocketAddress) endpoint2.getAddress()).getPort();
 
         endpoints = ioreactor.getEndpoints();
         Assert.assertNotNull(endpoints);
@@ -117,7 +110,7 @@ public class TestDefaultListeningIOReactor {
         Assert.assertNotNull(endpoints);
         Assert.assertEquals(1, endpoints.size());
 
-        ListenerEndpoint endpoint = endpoints.iterator().next();
+        final ListenerEndpoint endpoint = endpoints.iterator().next();
 
         Assert.assertEquals(port, ((InetSocketAddress) endpoint.getAddress()).getPort());
 
@@ -130,19 +123,18 @@ public class TestDefaultListeningIOReactor {
     @Test
     public void testEndpointAlreadyBoundFatal() throws Exception {
         final IOEventDispatch eventDispatch = createIOEventDispatch();
-        IOReactorConfig config = new IOReactorConfig();
-        config.setIoThreadCount(1);
+        final IOReactorConfig config = IOReactorConfig.custom().setIoThreadCount(1).build();
         final ListeningIOReactor ioreactor = new DefaultListeningIOReactor(config);
 
         final CountDownLatch latch = new CountDownLatch(1);
 
-        Thread t = new Thread(new Runnable() {
+        final Thread t = new Thread(new Runnable() {
 
             public void run() {
                 try {
                     ioreactor.execute(eventDispatch);
                     Assert.fail("IOException should have been thrown");
-                } catch (IOException ex) {
+                } catch (final IOException ex) {
                     latch.countDown();
                 }
             }
@@ -151,11 +143,11 @@ public class TestDefaultListeningIOReactor {
 
         t.start();
 
-        ListenerEndpoint endpoint1 = ioreactor.listen(new InetSocketAddress(0));
+        final ListenerEndpoint endpoint1 = ioreactor.listen(new InetSocketAddress(0));
         endpoint1.waitFor();
-        int port = ((InetSocketAddress) endpoint1.getAddress()).getPort();
+        final int port = ((InetSocketAddress) endpoint1.getAddress()).getPort();
 
-        ListenerEndpoint endpoint2 = ioreactor.listen(new InetSocketAddress(port));
+        final ListenerEndpoint endpoint2 = ioreactor.listen(new InetSocketAddress(port));
         endpoint2.waitFor();
         Assert.assertNotNull(endpoint2.getException());
 
@@ -163,7 +155,7 @@ public class TestDefaultListeningIOReactor {
         latch.await(2000, TimeUnit.MILLISECONDS);
         Assert.assertTrue(ioreactor.getStatus().compareTo(IOReactorStatus.SHUTTING_DOWN) >= 0);
 
-        Set<ListenerEndpoint> endpoints = ioreactor.getEndpoints();
+        final Set<ListenerEndpoint> endpoints = ioreactor.getEndpoints();
         Assert.assertNotNull(endpoints);
         Assert.assertEquals(0, endpoints.size());
 
@@ -176,8 +168,7 @@ public class TestDefaultListeningIOReactor {
     @Test
     public void testEndpointAlreadyBoundNonFatal() throws Exception {
         final IOEventDispatch eventDispatch = createIOEventDispatch();
-        IOReactorConfig config = new IOReactorConfig();
-        config.setIoThreadCount(1);
+        final IOReactorConfig config = IOReactorConfig.custom().setIoThreadCount(1).build();
         final DefaultListeningIOReactor ioreactor = new DefaultListeningIOReactor(config);
 
         ioreactor.setExceptionHandler(new IOReactorExceptionHandler() {
@@ -192,12 +183,12 @@ public class TestDefaultListeningIOReactor {
 
         });
 
-        Thread t = new Thread(new Runnable() {
+        final Thread t = new Thread(new Runnable() {
 
             public void run() {
                 try {
                     ioreactor.execute(eventDispatch);
-                } catch (IOException ex) {
+                } catch (final IOException ex) {
                 }
             }
 
@@ -205,10 +196,10 @@ public class TestDefaultListeningIOReactor {
 
         t.start();
 
-        ListenerEndpoint endpoint1 = ioreactor.listen(new InetSocketAddress(9999));
+        final ListenerEndpoint endpoint1 = ioreactor.listen(new InetSocketAddress(9999));
         endpoint1.waitFor();
 
-        ListenerEndpoint endpoint2 = ioreactor.listen(new InetSocketAddress(9999));
+        final ListenerEndpoint endpoint2 = ioreactor.listen(new InetSocketAddress(9999));
         endpoint2.waitFor();
         Assert.assertNotNull(endpoint2.getException());
 
diff --git a/httpcore-nio/src/test/java/org/apache/http/impl/nio/reactor/TestSessionInOutBuffers.java b/httpcore-nio/src/test/java/org/apache/http/impl/nio/reactor/TestSessionInOutBuffers.java
index 859efd9..0576d3f 100644
--- a/httpcore-nio/src/test/java/org/apache/http/impl/nio/reactor/TestSessionInOutBuffers.java
+++ b/httpcore-nio/src/test/java/org/apache/http/impl/nio/reactor/TestSessionInOutBuffers.java
@@ -35,22 +35,46 @@ import java.nio.channels.Channels;
 import java.nio.channels.ReadableByteChannel;
 import java.nio.channels.WritableByteChannel;
 import java.nio.charset.CharacterCodingException;
+import java.nio.charset.CharsetDecoder;
+import java.nio.charset.CharsetEncoder;
 import java.nio.charset.CodingErrorAction;
+import java.util.Arrays;
+import java.util.Collection;
 
+import org.apache.http.Consts;
 import org.apache.http.nio.reactor.SessionInputBuffer;
 import org.apache.http.nio.reactor.SessionOutputBuffer;
-import org.apache.http.params.BasicHttpParams;
-import org.apache.http.params.HttpParams;
-import org.apache.http.params.HttpProtocolParams;
+import org.apache.http.nio.util.ByteBufferAllocator;
+import org.apache.http.nio.util.DirectByteBufferAllocator;
+import org.apache.http.nio.util.HeapByteBufferAllocator;
 import org.apache.http.util.CharArrayBuffer;
 import org.junit.Assert;
 import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
 
 /**
  * Simple tests for {@link SessionInputBuffer} and {@link SessionOutputBuffer}.
  */
+ at RunWith(Parameterized.class)
 public class TestSessionInOutBuffers {
 
+    private final ByteBufferAllocator allocator;
+
+    public TestSessionInOutBuffers(final ByteBufferAllocator allocator) {
+        super();
+        this.allocator = allocator;
+    }
+
+    @Parameters
+    public static Collection<Object[]> getParameters() {
+
+        return Arrays.asList(
+                new Object[] { HeapByteBufferAllocator.INSTANCE },
+                new Object[] { DirectByteBufferAllocator.INSTANCE });
+    }
+
     private static WritableByteChannel newChannel(final ByteArrayOutputStream outstream) {
         return Channels.newChannel(outstream);
     }
@@ -71,15 +95,13 @@ public class TestSessionInOutBuffers {
 
     @Test
     public void testReadLineChunks() throws Exception {
-
-        HttpParams params = new BasicHttpParams();
-        SessionInputBuffer inbuf = new SessionInputBufferImpl(16, 16, params);
+        final SessionInputBuffer inbuf = new SessionInputBufferImpl(16, 16, null, this.allocator);
 
         ReadableByteChannel channel = newChannel("One\r\nTwo\r\nThree");
 
         inbuf.fill(channel);
 
-        CharArrayBuffer line = new CharArrayBuffer(64);
+        final CharArrayBuffer line = new CharArrayBuffer(64);
 
         line.clear();
         Assert.assertTrue(inbuf.readLine(line, false));
@@ -111,16 +133,14 @@ public class TestSessionInOutBuffers {
 
     @Test
     public void testWriteLineChunks() throws Exception {
-
-        HttpParams params = new BasicHttpParams();
-        SessionOutputBuffer outbuf = new SessionOutputBufferImpl(16, 16, params);
-        SessionInputBuffer inbuf = new SessionInputBufferImpl(16, 16, params);
+        final SessionOutputBuffer outbuf = new SessionOutputBufferImpl(16, 16, null, this.allocator);
+        final SessionInputBuffer inbuf = new SessionInputBufferImpl(16, 16, null, this.allocator);
 
         ReadableByteChannel inChannel = newChannel("One\r\nTwo\r\nThree");
 
         inbuf.fill(inChannel);
 
-        CharArrayBuffer line = new CharArrayBuffer(64);
+        final CharArrayBuffer line = new CharArrayBuffer(64);
 
         line.clear();
         Assert.assertTrue(inbuf.readLine(line, false));
@@ -157,22 +177,22 @@ public class TestSessionInOutBuffers {
         line.clear();
         Assert.assertFalse(inbuf.readLine(line, true));
 
-        ByteArrayOutputStream outstream = new ByteArrayOutputStream();
-        WritableByteChannel outChannel = newChannel(outstream);
+        final ByteArrayOutputStream outstream = new ByteArrayOutputStream();
+        final WritableByteChannel outChannel = newChannel(outstream);
         outbuf.flush(outChannel);
 
-        String s = new String(outstream.toByteArray(), "US-ASCII");
+        final String s = new String(outstream.toByteArray(), "US-ASCII");
         Assert.assertEquals("One\r\nTwo\r\nThree\r\nFour\r\n", s);
     }
 
     @Test
     public void testBasicReadWriteLine() throws Exception {
 
-        String[] teststrs = new String[5];
+        final String[] teststrs = new String[5];
         teststrs[0] = "Hello";
         teststrs[1] = "This string should be much longer than the size of the line buffer " +
                 "which is only 16 bytes for this test";
-        StringBuilder buffer = new StringBuilder();
+        final StringBuilder buffer = new StringBuilder();
         for (int i = 0; i < 15; i++) {
             buffer.append("123456789 ");
         }
@@ -181,27 +201,25 @@ public class TestSessionInOutBuffers {
         teststrs[3] = "";
         teststrs[4] = "And goodbye";
 
-        HttpParams params = new BasicHttpParams();
-
-        SessionOutputBuffer outbuf = new SessionOutputBufferImpl(1024, 16, params);
-        for (int i = 0; i < teststrs.length; i++) {
-            outbuf.writeLine(teststrs[i]);
+        final SessionOutputBuffer outbuf = new SessionOutputBufferImpl(1024, 16, null, this.allocator);
+        for (final String teststr : teststrs) {
+            outbuf.writeLine(teststr);
         }
         //this write operation should have no effect
         outbuf.writeLine((String)null);
         outbuf.writeLine((CharArrayBuffer)null);
 
-        ByteArrayOutputStream outstream = new ByteArrayOutputStream();
-        WritableByteChannel outChannel = newChannel(outstream);
+        final ByteArrayOutputStream outstream = new ByteArrayOutputStream();
+        final WritableByteChannel outChannel = newChannel(outstream);
         outbuf.flush(outChannel);
 
-        ReadableByteChannel channel = newChannel(outstream.toByteArray());
+        final ReadableByteChannel channel = newChannel(outstream.toByteArray());
 
-        SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 16, params);
+        final SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 16, null, this.allocator);
         inbuf.fill(channel);
 
-        for (int i = 0; i < teststrs.length; i++) {
-            Assert.assertEquals(teststrs[i], inbuf.readLine(true));
+        for (final String teststr : teststrs) {
+            Assert.assertEquals(teststr, inbuf.readLine(true));
         }
         Assert.assertNull(inbuf.readLine(true));
         Assert.assertNull(inbuf.readLine(true));
@@ -209,19 +227,17 @@ public class TestSessionInOutBuffers {
 
     @Test
     public void testComplexReadWriteLine() throws Exception {
-        HttpParams params = new BasicHttpParams();
-
-        SessionOutputBuffer outbuf = new SessionOutputBufferImpl(1024, 16, params);
+        final SessionOutputBuffer outbuf = new SessionOutputBufferImpl(1024, 16, null, this.allocator);
         outbuf.write(ByteBuffer.wrap(new byte[] {'a', '\n'}));
         outbuf.write(ByteBuffer.wrap(new byte[] {'\r', '\n'}));
         outbuf.write(ByteBuffer.wrap(new byte[] {'\r', '\r', '\n'}));
         outbuf.write(ByteBuffer.wrap(new byte[] {'\n'}));
 
-        StringBuilder buffer = new StringBuilder();
+        final StringBuilder buffer = new StringBuilder();
         for (int i = 0; i < 14; i++) {
             buffer.append("a");
         }
-        String s1 = buffer.toString();
+        final String s1 = buffer.toString();
         buffer.append("\r\n");
         outbuf.write(ByteBuffer.wrap(buffer.toString().getBytes("US-ASCII")));
 
@@ -229,7 +245,7 @@ public class TestSessionInOutBuffers {
         for (int i = 0; i < 15; i++) {
             buffer.append("a");
         }
-        String s2 = buffer.toString();
+        final String s2 = buffer.toString();
         buffer.append("\r\n");
         outbuf.write(ByteBuffer.wrap(buffer.toString().getBytes("US-ASCII")));
 
@@ -237,19 +253,19 @@ public class TestSessionInOutBuffers {
         for (int i = 0; i < 16; i++) {
             buffer.append("a");
         }
-        String s3 = buffer.toString();
+        final String s3 = buffer.toString();
         buffer.append("\r\n");
         outbuf.write(ByteBuffer.wrap(buffer.toString().getBytes("US-ASCII")));
 
         outbuf.write(ByteBuffer.wrap(new byte[] {'a'}));
 
-        ByteArrayOutputStream outstream = new ByteArrayOutputStream();
-        WritableByteChannel outChannel = newChannel(outstream);
+        final ByteArrayOutputStream outstream = new ByteArrayOutputStream();
+        final WritableByteChannel outChannel = newChannel(outstream);
         outbuf.flush(outChannel);
 
-        ReadableByteChannel channel = newChannel(outstream.toByteArray());
+        final ReadableByteChannel channel = newChannel(outstream.toByteArray());
 
-        SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 16, params);
+        final SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 16, null, this.allocator);
         inbuf.fill(channel);
 
         Assert.assertEquals("a", inbuf.readLine(true));
@@ -267,17 +283,16 @@ public class TestSessionInOutBuffers {
     @Test
     public void testReadOneByte() throws Exception {
         // make the buffer larger than that of transmitter
-        byte[] out = new byte[40];
+        final byte[] out = new byte[40];
         for (int i = 0; i < out.length; i++) {
             out[i] = (byte)('0' + i);
         }
-        ReadableByteChannel channel = newChannel(out);
-        HttpParams params = new BasicHttpParams();
-        SessionInputBuffer inbuf = new SessionInputBufferImpl(16, 16, params);
+        final ReadableByteChannel channel = newChannel(out);
+        final SessionInputBuffer inbuf = new SessionInputBufferImpl(16, 16, null, this.allocator);
         while (inbuf.fill(channel) > 0) {
         }
 
-        byte[] in = new byte[40];
+        final byte[] in = new byte[40];
         for (int i = 0; i < in.length; i++) {
             in[i] = (byte)inbuf.read();
         }
@@ -288,13 +303,12 @@ public class TestSessionInOutBuffers {
 
     @Test
     public void testReadByteBuffer() throws Exception {
-        byte[] pattern = "0123456789ABCDEF".getBytes("US-ASCII");
-        ReadableByteChannel channel = newChannel(pattern);
-        HttpParams params = new BasicHttpParams();
-        SessionInputBuffer inbuf = new SessionInputBufferImpl(4096, 1024, params);
+        final byte[] pattern = "0123456789ABCDEF".getBytes("US-ASCII");
+        final ReadableByteChannel channel = newChannel(pattern);
+        final SessionInputBuffer inbuf = new SessionInputBufferImpl(4096, 1024, null, this.allocator);
         while (inbuf.fill(channel) > 0) {
         }
-        ByteBuffer dst = ByteBuffer.allocate(10);
+        final ByteBuffer dst = ByteBuffer.allocate(10);
         Assert.assertEquals(10, inbuf.read(dst));
         dst.flip();
         Assert.assertEquals(dst, ByteBuffer.wrap(pattern, 0, 10));
@@ -306,13 +320,12 @@ public class TestSessionInOutBuffers {
 
     @Test
     public void testReadByteBufferWithMaxLen() throws Exception {
-        byte[] pattern = "0123456789ABCDEF".getBytes("US-ASCII");
-        ReadableByteChannel channel = newChannel(pattern);
-        HttpParams params = new BasicHttpParams();
-        SessionInputBuffer inbuf = new SessionInputBufferImpl(4096, 1024, params);
+        final byte[] pattern = "0123456789ABCDEF".getBytes("US-ASCII");
+        final ReadableByteChannel channel = newChannel(pattern);
+        final SessionInputBuffer inbuf = new SessionInputBufferImpl(4096, 1024, null, this.allocator);
         while (inbuf.fill(channel) > 0) {
         }
-        ByteBuffer dst = ByteBuffer.allocate(16);
+        final ByteBuffer dst = ByteBuffer.allocate(16);
         Assert.assertEquals(10, inbuf.read(dst, 10));
         dst.flip();
         Assert.assertEquals(dst, ByteBuffer.wrap(pattern, 0, 10));
@@ -327,15 +340,14 @@ public class TestSessionInOutBuffers {
 
     @Test
     public void testReadToChannel() throws Exception {
-        byte[] pattern = "0123456789ABCDEF".getBytes("US-ASCII");
-        ReadableByteChannel channel = newChannel(pattern);
-        HttpParams params = new BasicHttpParams();
-        SessionInputBuffer inbuf = new SessionInputBufferImpl(4096, 1024, params);
+        final byte[] pattern = "0123456789ABCDEF".getBytes("US-ASCII");
+        final ReadableByteChannel channel = newChannel(pattern);
+        final SessionInputBuffer inbuf = new SessionInputBufferImpl(4096, 1024, null, this.allocator);
         while (inbuf.fill(channel) > 0) {
         }
 
-        ByteArrayOutputStream outstream = new ByteArrayOutputStream();
-        WritableByteChannel dst = newChannel(outstream);
+        final ByteArrayOutputStream outstream = new ByteArrayOutputStream();
+        final WritableByteChannel dst = newChannel(outstream);
 
         Assert.assertEquals(16, inbuf.read(dst));
         Assert.assertEquals(ByteBuffer.wrap(pattern), ByteBuffer.wrap(outstream.toByteArray()));
@@ -343,15 +355,14 @@ public class TestSessionInOutBuffers {
 
     @Test
     public void testReadToChannelWithMaxLen() throws Exception {
-        byte[] pattern = "0123456789ABCDEF".getBytes("US-ASCII");
-        ReadableByteChannel channel = newChannel(pattern);
-        HttpParams params = new BasicHttpParams();
-        SessionInputBuffer inbuf = new SessionInputBufferImpl(4096, 1024, params);
+        final byte[] pattern = "0123456789ABCDEF".getBytes("US-ASCII");
+        final ReadableByteChannel channel = newChannel(pattern);
+        final SessionInputBuffer inbuf = new SessionInputBufferImpl(4096, 1024, null, this.allocator);
         while (inbuf.fill(channel) > 0) {
         }
 
-        ByteArrayOutputStream outstream = new ByteArrayOutputStream();
-        WritableByteChannel dst = newChannel(outstream);
+        final ByteArrayOutputStream outstream = new ByteArrayOutputStream();
+        final WritableByteChannel dst = newChannel(outstream);
 
         Assert.assertEquals(10, inbuf.read(dst, 10));
         Assert.assertEquals(3, inbuf.read(dst, 3));
@@ -361,15 +372,14 @@ public class TestSessionInOutBuffers {
 
     @Test
     public void testWriteByteBuffer() throws Exception {
-        byte[] pattern = "0123456789ABCDEF0123456789ABCDEF".getBytes("US-ASCII");
+        final byte[] pattern = "0123456789ABCDEF0123456789ABCDEF".getBytes("US-ASCII");
 
-        HttpParams params = new BasicHttpParams();
-        SessionOutputBuffer outbuf = new SessionOutputBufferImpl(4096, 1024, params);
-        ReadableByteChannel src = newChannel(pattern);
+        final SessionOutputBuffer outbuf = new SessionOutputBufferImpl(4096, 1024, null, this.allocator);
+        final ReadableByteChannel src = newChannel(pattern);
         outbuf.write(src);
 
-        ByteArrayOutputStream outstream = new ByteArrayOutputStream();
-        WritableByteChannel channel = newChannel(outstream);
+        final ByteArrayOutputStream outstream = new ByteArrayOutputStream();
+        final WritableByteChannel channel = newChannel(outstream);
         while (outbuf.flush(channel) > 0) {
         }
         Assert.assertEquals(ByteBuffer.wrap(pattern), ByteBuffer.wrap(outstream.toByteArray()));
@@ -377,16 +387,15 @@ public class TestSessionInOutBuffers {
 
     @Test
     public void testWriteFromChannel() throws Exception {
-        byte[] pattern = "0123456789ABCDEF0123456789ABCDEF".getBytes("US-ASCII");
+        final byte[] pattern = "0123456789ABCDEF0123456789ABCDEF".getBytes("US-ASCII");
 
-        HttpParams params = new BasicHttpParams();
-        SessionOutputBuffer outbuf = new SessionOutputBufferImpl(4096, 1024, params);
+        final SessionOutputBuffer outbuf = new SessionOutputBufferImpl(4096, 1024, null, this.allocator);
         outbuf.write(ByteBuffer.wrap(pattern, 0, 16));
         outbuf.write(ByteBuffer.wrap(pattern, 16, 10));
         outbuf.write(ByteBuffer.wrap(pattern, 26, 6));
 
-        ByteArrayOutputStream outstream = new ByteArrayOutputStream();
-        WritableByteChannel channel = newChannel(outstream);
+        final ByteArrayOutputStream outstream = new ByteArrayOutputStream();
+        final WritableByteChannel channel = newChannel(outstream);
         while (outbuf.flush(channel) > 0) {
         }
         Assert.assertEquals(ByteBuffer.wrap(pattern), ByteBuffer.wrap(outstream.toByteArray()));
@@ -401,11 +410,11 @@ public class TestSessionInOutBuffers {
         0x432, 0x435, 0x442
     };
 
-    private static String constructString(int [] unicodeChars) {
-        StringBuilder buffer = new StringBuilder();
+    private static String constructString(final int [] unicodeChars) {
+        final StringBuilder buffer = new StringBuilder();
         if (unicodeChars != null) {
-            for (int i = 0; i < unicodeChars.length; i++) {
-                buffer.append((char)unicodeChars[i]);
+            for (final int unicodeChar : unicodeChars) {
+                buffer.append((char)unicodeChar);
             }
         }
         return buffer.toString();
@@ -413,14 +422,12 @@ public class TestSessionInOutBuffers {
 
     @Test
     public void testMultibyteCodedReadWriteLine() throws Exception {
-        String s1 = constructString(SWISS_GERMAN_HELLO);
-        String s2 = constructString(RUSSIAN_HELLO);
-        String s3 = "Like hello and stuff";
+        final String s1 = constructString(SWISS_GERMAN_HELLO);
+        final String s2 = constructString(RUSSIAN_HELLO);
+        final String s3 = "Like hello and stuff";
 
-        HttpParams params = new BasicHttpParams();
-        HttpProtocolParams.setHttpElementCharset(params, "UTF-8");
-
-        SessionOutputBuffer outbuf = new SessionOutputBufferImpl(1024, 16, params);
+        final SessionOutputBuffer outbuf = new SessionOutputBufferImpl(1024, 16,
+                Consts.UTF_8.newEncoder(), this.allocator);
 
         for (int i = 0; i < 10; i++) {
             outbuf.writeLine(s1);
@@ -428,14 +435,15 @@ public class TestSessionInOutBuffers {
             outbuf.writeLine(s3);
         }
 
-        ByteArrayOutputStream outstream = new ByteArrayOutputStream();
-        WritableByteChannel outChannel = newChannel(outstream);
+        final ByteArrayOutputStream outstream = new ByteArrayOutputStream();
+        final WritableByteChannel outChannel = newChannel(outstream);
         outbuf.flush(outChannel);
 
-        byte[] tmp = outstream.toByteArray();
+        final byte[] tmp = outstream.toByteArray();
 
-        ReadableByteChannel channel = newChannel(tmp);
-        SessionInputBuffer inbuf = new SessionInputBufferImpl(16, 16, params);
+        final ReadableByteChannel channel = newChannel(tmp);
+        final SessionInputBuffer inbuf = new SessionInputBufferImpl(16, 16,
+                Consts.UTF_8.newDecoder(), this.allocator);
 
         while (inbuf.fill(channel) > 0) {
         }
@@ -448,110 +456,99 @@ public class TestSessionInOutBuffers {
     }
 
     @Test
-    public void testMalformedCharacters() throws Exception {
-        HttpParams params = new BasicHttpParams();
-        String s1 = constructString(SWISS_GERMAN_HELLO);
-        SessionOutputBuffer outbuf = new SessionOutputBufferImpl(1024, 16, params);
-        try {
-            outbuf.writeLine(s1);
-            Assert.fail("Expected CharacterCodingException");
-        } catch (CharacterCodingException expected) {
-        }
-
-        byte[] tmp = s1.getBytes("ISO-8859-1");
-        ReadableByteChannel channel = newChannel(tmp);
-        SessionInputBuffer inbuf = new SessionInputBufferImpl(16, 16, params);
-        while (inbuf.fill(channel) > 0) {
-        }
-
-        try {
-            String s = inbuf.readLine(true);
-            Assert.fail("Expected CharacterCodingException, got '" + s + "'");
-        } catch (CharacterCodingException expected) {
-        }
-    }
-
-    @Test
     public void testInputMatchesBufferLength() throws Exception {
-        HttpParams params = new BasicHttpParams();
-        String s1 = "abcde";
-        SessionOutputBuffer outbuf = new SessionOutputBufferImpl(1024, 5, params);
+        final String s1 = "abcde";
+        final SessionOutputBuffer outbuf = new SessionOutputBufferImpl(1024, 5, null, this.allocator);
         outbuf.writeLine(s1);
     }
 
-    @Test
-    public void testMalformedInputAction() throws Exception {
-        HttpParams params = new BasicHttpParams();
-        String s1 = constructString(SWISS_GERMAN_HELLO);
+    @Test(expected=CharacterCodingException.class)
+    public void testMalformedInputActionReport() throws Exception {
+        final String s = constructString(SWISS_GERMAN_HELLO);
+        final byte[] tmp = s.getBytes("ISO-8859-1");
 
-        byte[] tmp = s1.getBytes("ISO-8859-1");
-        ReadableByteChannel channel = newChannel(tmp);
-        SessionInputBuffer inbuf = new SessionInputBufferImpl(16, 16, params);
+        final CharsetDecoder decoder = Consts.UTF_8.newDecoder();
+        decoder.onMalformedInput(CodingErrorAction.REPORT);
+        decoder.onUnmappableCharacter(CodingErrorAction.IGNORE);
+        final SessionInputBuffer inbuf = new SessionInputBufferImpl(16, 16, decoder, this.allocator);
+        final ReadableByteChannel channel = newChannel(tmp);
         while (inbuf.fill(channel) > 0) {
         }
+        inbuf.readLine(true);
+    }
 
-        // Action with report
-        HttpProtocolParams.setMalformedInputAction(params, CodingErrorAction.REPORT);
-        try {
-            String s = inbuf.readLine(true);
-            Assert.fail("Expected CharacterCodingException, got '" + s + "'");
-        } catch (CharacterCodingException expected) {
+    @Test
+    public void testMalformedInputActionIgnore() throws Exception {
+        final String s = constructString(SWISS_GERMAN_HELLO);
+        final byte[] tmp = s.getBytes("ISO-8859-1");
+
+        final CharsetDecoder decoder = Consts.UTF_8.newDecoder();
+        decoder.onMalformedInput(CodingErrorAction.IGNORE);
+        decoder.onUnmappableCharacter(CodingErrorAction.IGNORE);
+        final SessionInputBuffer inbuf = new SessionInputBufferImpl(16, 16, decoder, this.allocator);
+        final ReadableByteChannel channel = newChannel(tmp);
+        while (inbuf.fill(channel) > 0) {
         }
+        final String result = inbuf.readLine(true);
+        Assert.assertEquals("Grezi_zm", result);
+    }
 
-        // Action with ignore
-        HttpProtocolParams.setMalformedInputAction(params, CodingErrorAction.IGNORE);
-        inbuf = new SessionInputBufferImpl(16, 16, params);
-        String s2 = null;
-        try {
-            s2 = inbuf.readLine(true);
-        } catch (CharacterCodingException e) {
-            Assert.fail("Unexpected CharacterCodingException " +
-                    (s2 == null ? "" : ", got '" + s2 + "'"));
+    @Test
+    public void testMalformedInputActionReplace() throws Exception {
+        final String s = constructString(SWISS_GERMAN_HELLO);
+        final byte[] tmp = s.getBytes("ISO-8859-1");
+
+        final CharsetDecoder decoder = Consts.UTF_8.newDecoder();
+        decoder.onMalformedInput(CodingErrorAction.REPLACE);
+        decoder.onUnmappableCharacter(CodingErrorAction.IGNORE);
+        final SessionInputBuffer inbuf = new SessionInputBufferImpl(16, 16, decoder, this.allocator);
+        final ReadableByteChannel channel = newChannel(tmp);
+        while (inbuf.fill(channel) > 0) {
         }
+        final String result = inbuf.readLine(true);
+        Assert.assertEquals("Gr\ufffdezi_z\ufffdm\ufffd", result);
+    }
 
-        // Action with replace
-        HttpProtocolParams.setMalformedInputAction(params, CodingErrorAction.REPLACE);
-        inbuf = new SessionInputBufferImpl(16, 16, params);
-        String s3 = null;
-        try {
-            s3 = inbuf.readLine(true);
-        } catch (CharacterCodingException e) {
-            Assert.fail("Unexpected CharacterCodingException " +
-                    (s3 == null ? "" : ", got '" + s3 + "'"));
-        }
+    @Test(expected=CharacterCodingException.class)
+    public void testUnmappableInputActionReport() throws Exception {
+        final String s = "This text contains a circumflex \u0302!!!";
+        final CharsetEncoder encoder = Consts.ISO_8859_1.newEncoder();
+        encoder.onMalformedInput(CodingErrorAction.IGNORE);
+        encoder.onUnmappableCharacter(CodingErrorAction.REPORT);
+        final SessionOutputBuffer outbuf = new SessionOutputBufferImpl(1024, 16, encoder, this.allocator);
+        outbuf.writeLine(s);
     }
 
     @Test
-    public void testUnmappableInputAction() throws Exception {
-        HttpParams params = new BasicHttpParams();
-        String s1 = constructString(SWISS_GERMAN_HELLO);
-
-        // Action with report
-        HttpProtocolParams.setUnmappableInputAction(params, CodingErrorAction.REPORT);
-        SessionOutputBuffer outbuf = new SessionOutputBufferImpl(1024, 16, params);
-        try {
-            outbuf.writeLine(s1);
-            Assert.fail("Expected CharacterCodingException");
-        } catch (CharacterCodingException expected) {
-        }
-
-        // Action with ignore
-        HttpProtocolParams.setUnmappableInputAction(params, CodingErrorAction.IGNORE);
-        outbuf = new SessionOutputBufferImpl(1024, 16, params);
-        try {
-            outbuf.writeLine(s1);
-        } catch (CharacterCodingException e) {
-            Assert.fail("Unexpected CharacterCodingException");
-        }
+    public void testUnmappableInputActionIgnore() throws Exception {
+        final String s = "This text contains a circumflex \u0302!!!";
+        final CharsetEncoder encoder = Consts.ISO_8859_1.newEncoder();
+        encoder.onMalformedInput(CodingErrorAction.IGNORE);
+        encoder.onUnmappableCharacter(CodingErrorAction.IGNORE);
+        final SessionOutputBuffer outbuf = new SessionOutputBufferImpl(1024, 16, encoder, this.allocator);
+        final ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        final WritableByteChannel channel = newChannel(baos);
+        outbuf.writeLine(s);
+        outbuf.flush(channel);
+
+        final String result = new String(baos.toByteArray(), "US-ASCII");
+        Assert.assertEquals("This text contains a circumflex !!!\r\n", result);
+    }
 
-        // Action with replace
-        HttpProtocolParams.setUnmappableInputAction(params, CodingErrorAction.REPLACE);
-        outbuf = new SessionOutputBufferImpl(1024, 16, params);
-        try {
-            outbuf.writeLine(s1);
-        } catch (CharacterCodingException e) {
-            Assert.fail("Unexpected CharacterCodingException");
-        }
+    @Test
+    public void testUnmappableInputActionReplace() throws Exception {
+        final String s = "This text contains a circumflex \u0302 !!!";
+        final CharsetEncoder encoder = Consts.ISO_8859_1.newEncoder();
+        encoder.onMalformedInput(CodingErrorAction.IGNORE);
+        encoder.onUnmappableCharacter(CodingErrorAction.REPLACE);
+        final SessionOutputBuffer outbuf = new SessionOutputBufferImpl(1024, 16, encoder, this.allocator);
+        final ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        final WritableByteChannel channel = newChannel(baos);
+        outbuf.writeLine(s);
+        outbuf.flush(channel);
+
+        final String result = new String(baos.toByteArray(), "US-ASCII");
+        Assert.assertEquals("This text contains a circumflex ? !!!\r\n", result);
     }
 
 }
diff --git a/httpcore-nio/src/test/java/org/apache/http/nio/integration/Job.java b/httpcore-nio/src/test/java/org/apache/http/nio/integration/Job.java
deleted file mode 100644
index 5be21d5..0000000
--- a/httpcore-nio/src/test/java/org/apache/http/nio/integration/Job.java
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * ====================================================================
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- *
- */
-
-package org.apache.http.nio.integration;
-
-import java.util.Random;
-
- at Deprecated
-public class Job {
-
-    private static final Random RND = new Random();
-    private static final String TEST_CHARS = "0123456789ABCDEF";
-
-    private final int count;
-    private final String pattern;
-
-    private volatile boolean completed;
-    private volatile int statusCode;
-    private volatile String result;
-    private volatile String failureMessage;
-    private volatile Exception ex;
-
-    public Job(int maxCount) {
-        super();
-        this.count = RND.nextInt(maxCount - 1) + 1;
-        StringBuilder buffer = new StringBuilder();
-        for (int i = 0; i < 5; i++) {
-            char rndchar = TEST_CHARS.charAt(RND.nextInt(TEST_CHARS.length() - 1));
-            buffer.append(rndchar);
-        }
-        this.pattern = buffer.toString();
-    }
-
-    public Job() {
-        this(1000);
-    }
-
-    public Job(final String pattern, int count) {
-        super();
-        this.count = count;
-        this.pattern = pattern;
-    }
-
-    public int getCount() {
-        return this.count;
-    }
-
-    public String getPattern() {
-        return this.pattern;
-    }
-
-    public String getExpected() {
-        StringBuilder buffer = new StringBuilder();
-        for (int i = 0; i < this.count; i++) {
-            buffer.append(this.pattern);
-        }
-        return buffer.toString();
-    }
-
-    public int getStatusCode() {
-        return this.statusCode;
-    }
-
-    public String getResult() {
-        return this.result;
-    }
-
-    public boolean isSuccessful() {
-        return this.result != null;
-    }
-
-    public String getFailureMessage() {
-        return this.failureMessage;
-    }
-
-    public Exception getException() {
-        return this.ex;
-    }
-
-    public boolean isCompleted() {
-        return this.completed;
-    }
-
-    public synchronized void setResult(int statusCode, final String result) {
-        if (this.completed) {
-            return;
-        }
-        this.completed = true;
-        this.statusCode = statusCode;
-        this.result = result;
-        notifyAll();
-    }
-
-    public synchronized void fail(final String message, final Exception ex) {
-        if (this.completed) {
-            return;
-        }
-        this.completed = true;
-        this.result = null;
-        this.failureMessage = message;
-        this.ex = ex;
-        notifyAll();
-    }
-
-    public void fail(final String message) {
-        fail(message, null);
-    }
-
-    public synchronized void waitFor() throws InterruptedException {
-        while (!this.completed) {
-            wait();
-        }
-    }
-
-}
diff --git a/httpcore-nio/src/test/java/org/apache/http/nio/integration/RequestExecutionHandler.java b/httpcore-nio/src/test/java/org/apache/http/nio/integration/RequestExecutionHandler.java
deleted file mode 100644
index 0b5eb96..0000000
--- a/httpcore-nio/src/test/java/org/apache/http/nio/integration/RequestExecutionHandler.java
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * ====================================================================
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- *
- */
-
-package org.apache.http.nio.integration;
-
-import java.io.IOException;
-import java.util.Queue;
-
-import org.apache.http.HttpEntity;
-import org.apache.http.HttpRequest;
-import org.apache.http.HttpResponse;
-import org.apache.http.nio.entity.BufferingNHttpEntity;
-import org.apache.http.nio.entity.ConsumingNHttpEntity;
-import org.apache.http.nio.protocol.HttpRequestExecutionHandler;
-import org.apache.http.nio.protocol.NHttpRequestExecutionHandler;
-import org.apache.http.nio.util.HeapByteBufferAllocator;
-import org.apache.http.protocol.HttpContext;
-import org.apache.http.util.EntityUtils;
-
- at Deprecated
-abstract class RequestExecutionHandler
-    implements NHttpRequestExecutionHandler, HttpRequestExecutionHandler {
-
-    public void initalizeContext(final HttpContext context, final Object attachment) {
-        context.setAttribute("queue", attachment);
-    }
-
-    protected abstract HttpRequest generateRequest(Job testjob);
-
-    public HttpRequest submitRequest(final HttpContext context) {
-
-        @SuppressWarnings("unchecked")
-        Queue<Job> queue = (Queue<Job>) context.getAttribute("queue");
-        if (queue == null) {
-            throw new IllegalStateException("Queue is null");
-        }
-
-        Job testjob = queue.poll();
-        context.setAttribute("job", testjob);
-
-        if (testjob != null) {
-            return generateRequest(testjob);
-        } else {
-            return null;
-        }
-    }
-
-    public ConsumingNHttpEntity responseEntity(
-            final HttpResponse response,
-            final HttpContext context) throws IOException {
-        return new BufferingNHttpEntity(response.getEntity(),
-                new HeapByteBufferAllocator());
-    }
-
-    public void handleResponse(final HttpResponse response, final HttpContext context) {
-        Job testjob = (Job) context.removeAttribute("job");
-        if (testjob == null) {
-            throw new IllegalStateException("TestJob is null");
-        }
-
-        int statusCode = response.getStatusLine().getStatusCode();
-        String content = null;
-
-        HttpEntity entity = response.getEntity();
-        if (entity != null) {
-            try {
-                content = EntityUtils.toString(entity);
-            } catch (IOException ex) {
-                content = "I/O exception: " + ex.getMessage();
-            }
-        }
-        testjob.setResult(statusCode, content);
-    }
-
-    public void finalizeContext(final HttpContext context) {
-        Job testjob = (Job) context.removeAttribute("job");
-        if (testjob != null) {
-            testjob.fail("Request failed");
-        }
-    }
-
-}
diff --git a/httpcore-nio/src/test/java/org/apache/http/nio/integration/RequestHandler.java b/httpcore-nio/src/test/java/org/apache/http/nio/integration/RequestHandler.java
deleted file mode 100644
index 74ae4d4..0000000
--- a/httpcore-nio/src/test/java/org/apache/http/nio/integration/RequestHandler.java
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * ====================================================================
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- *
- */
-
-package org.apache.http.nio.integration;
-
-import java.io.IOException;
-
-import org.apache.http.HttpEntity;
-import org.apache.http.HttpEntityEnclosingRequest;
-import org.apache.http.HttpException;
-import org.apache.http.HttpRequest;
-import org.apache.http.HttpResponse;
-import org.apache.http.HttpStatus;
-import org.apache.http.entity.ContentType;
-import org.apache.http.nio.entity.BufferingNHttpEntity;
-import org.apache.http.nio.entity.ConsumingNHttpEntity;
-import org.apache.http.nio.entity.NStringEntity;
-import org.apache.http.nio.protocol.SimpleNHttpRequestHandler;
-import org.apache.http.nio.util.HeapByteBufferAllocator;
-import org.apache.http.protocol.HttpContext;
-import org.apache.http.protocol.HttpRequestHandler;
-import org.apache.http.util.EntityUtils;
-
- at Deprecated
-final class RequestHandler extends SimpleNHttpRequestHandler implements HttpRequestHandler {
-
-    private final boolean chunking;
-
-    RequestHandler() {
-        this(false);
-    }
-
-    RequestHandler(boolean chunking) {
-        super();
-        this.chunking = chunking;
-    }
-
-    public ConsumingNHttpEntity entityRequest(
-            final HttpEntityEnclosingRequest request,
-            final HttpContext context) {
-        return new BufferingNHttpEntity(request.getEntity(), new HeapByteBufferAllocator());
-    }
-
-    @Override
-    public void handle(
-            final HttpRequest request,
-            final HttpResponse response,
-            final HttpContext context) throws HttpException, IOException {
-
-        String content = null;
-        if (request instanceof HttpEntityEnclosingRequest) {
-            HttpEntity entity = ((HttpEntityEnclosingRequest) request).getEntity();
-            if (entity != null) {
-                content = EntityUtils.toString(entity);
-            } else {
-                response.setStatusCode(HttpStatus.SC_BAD_REQUEST);
-                content = "Request entity not avaialble";
-            }
-        } else {
-            String s = request.getRequestLine().getUri();
-            int idx = s.indexOf('x');
-            if (idx == -1) {
-                throw new HttpException("Unexpected request-URI format");
-            }
-            String pattern = s.substring(0, idx);
-            int count = Integer.parseInt(s.substring(idx + 1, s.length()));
-
-            StringBuilder buffer = new StringBuilder();
-            for (int i = 0; i < count; i++) {
-                buffer.append(pattern);
-            }
-            content = buffer.toString();
-        }
-        NStringEntity entity = new NStringEntity(content, ContentType.DEFAULT_TEXT);
-        entity.setChunked(this.chunking);
-        response.setEntity(entity);
-    }
-
-}
diff --git a/httpcore-nio/src/test/java/org/apache/http/nio/integration/RndTestPatternGenerator.java b/httpcore-nio/src/test/java/org/apache/http/nio/integration/RndTestPatternGenerator.java
index f837815..5e6dc19 100644
--- a/httpcore-nio/src/test/java/org/apache/http/nio/integration/RndTestPatternGenerator.java
+++ b/httpcore-nio/src/test/java/org/apache/http/nio/integration/RndTestPatternGenerator.java
@@ -35,15 +35,15 @@ final class RndTestPatternGenerator {
     private static final String TEST_CHARS = "0123456789ABCDEF";
 
     public static String generateText() {
-        StringBuilder buffer = new StringBuilder();
+        final StringBuilder buffer = new StringBuilder();
         for (int i = 0; i < 5; i++) {
-            char rndchar = TEST_CHARS.charAt(RND.nextInt(TEST_CHARS.length() - 1));
+            final char rndchar = TEST_CHARS.charAt(RND.nextInt(TEST_CHARS.length() - 1));
             buffer.append(rndchar);
         }
         return buffer.toString();
     }
 
-    public static int generateCount(int max) {
+    public static int generateCount(final int max) {
         return RND.nextInt(max - 1) + 1;
     }
 
diff --git a/httpcore-nio/src/test/java/org/apache/http/nio/integration/SimpleRequestHandler.java b/httpcore-nio/src/test/java/org/apache/http/nio/integration/SimpleRequestHandler.java
index c35d1a3..3032b47 100644
--- a/httpcore-nio/src/test/java/org/apache/http/nio/integration/SimpleRequestHandler.java
+++ b/httpcore-nio/src/test/java/org/apache/http/nio/integration/SimpleRequestHandler.java
@@ -49,7 +49,7 @@ final class SimpleRequestHandler implements HttpRequestHandler {
         this(false);
     }
 
-    SimpleRequestHandler(boolean chunking) {
+    SimpleRequestHandler(final boolean chunking) {
         super();
         this.chunking = chunking;
     }
@@ -61,7 +61,7 @@ final class SimpleRequestHandler implements HttpRequestHandler {
 
         String content = null;
         if (request instanceof HttpEntityEnclosingRequest) {
-            HttpEntity entity = ((HttpEntityEnclosingRequest) request).getEntity();
+            final HttpEntity entity = ((HttpEntityEnclosingRequest) request).getEntity();
             if (entity != null) {
                 content = EntityUtils.toString(entity);
             } else {
@@ -69,21 +69,21 @@ final class SimpleRequestHandler implements HttpRequestHandler {
                 content = "Request entity not avaialble";
             }
         } else {
-            String s = request.getRequestLine().getUri();
-            int idx = s.indexOf('x');
+            final String s = request.getRequestLine().getUri();
+            final int idx = s.indexOf('x');
             if (idx == -1) {
                 throw new HttpException("Unexpected request-URI format");
             }
-            String pattern = s.substring(0, idx);
-            int count = Integer.parseInt(s.substring(idx + 1, s.length()));
+            final String pattern = s.substring(0, idx);
+            final int count = Integer.parseInt(s.substring(idx + 1, s.length()));
 
-            StringBuilder buffer = new StringBuilder();
+            final StringBuilder buffer = new StringBuilder();
             for (int i = 0; i < count; i++) {
                 buffer.append(pattern);
             }
             content = buffer.toString();
         }
-        NStringEntity entity = new NStringEntity(content, ContentType.DEFAULT_TEXT);
+        final NStringEntity entity = new NStringEntity(content, ContentType.DEFAULT_TEXT);
         entity.setChunked(this.chunking);
         response.setEntity(entity);
     }
diff --git a/httpcore-nio/src/test/java/org/apache/http/nio/integration/TestAsyncNHttpHandlers.java b/httpcore-nio/src/test/java/org/apache/http/nio/integration/TestAsyncNHttpHandlers.java
deleted file mode 100644
index 938b7ca..0000000
--- a/httpcore-nio/src/test/java/org/apache/http/nio/integration/TestAsyncNHttpHandlers.java
+++ /dev/null
@@ -1,1141 +0,0 @@
-/*
- * ====================================================================
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- *
- */
-
-package org.apache.http.nio.integration;
-
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.net.InetSocketAddress;
-import java.util.LinkedList;
-import java.util.Queue;
-import java.util.concurrent.ConcurrentLinkedQueue;
-
-import org.apache.http.HttpCoreNIOTestBase;
-import org.apache.http.HttpEntityEnclosingRequest;
-import org.apache.http.HttpException;
-import org.apache.http.HttpRequest;
-import org.apache.http.HttpRequestInterceptor;
-import org.apache.http.HttpResponse;
-import org.apache.http.HttpResponseInterceptor;
-import org.apache.http.HttpStatus;
-import org.apache.http.HttpVersion;
-import org.apache.http.LoggingClientConnectionFactory;
-import org.apache.http.LoggingServerConnectionFactory;
-import org.apache.http.impl.DefaultConnectionReuseStrategy;
-import org.apache.http.impl.DefaultHttpResponseFactory;
-import org.apache.http.impl.nio.DefaultNHttpClientConnection;
-import org.apache.http.impl.nio.DefaultNHttpServerConnection;
-import org.apache.http.message.BasicHttpEntityEnclosingRequest;
-import org.apache.http.message.BasicHttpRequest;
-import org.apache.http.nio.NHttpConnectionFactory;
-import org.apache.http.nio.entity.ConsumingNHttpEntity;
-import org.apache.http.nio.entity.NByteArrayEntity;
-import org.apache.http.nio.entity.NStringEntity;
-import org.apache.http.nio.protocol.AsyncNHttpClientHandler;
-import org.apache.http.nio.protocol.AsyncNHttpServiceHandler;
-import org.apache.http.nio.protocol.NHttpRequestExecutionHandler;
-import org.apache.http.nio.protocol.NHttpRequestHandler;
-import org.apache.http.nio.protocol.NHttpResponseTrigger;
-import org.apache.http.nio.protocol.SimpleNHttpRequestHandler;
-import org.apache.http.nio.reactor.IOReactorStatus;
-import org.apache.http.nio.reactor.ListenerEndpoint;
-import org.apache.http.nio.reactor.SessionRequest;
-import org.apache.http.params.CoreProtocolPNames;
-import org.apache.http.params.HttpParams;
-import org.apache.http.protocol.HttpContext;
-import org.apache.http.protocol.HttpExpectationVerifier;
-import org.apache.http.protocol.HttpProcessor;
-import org.apache.http.protocol.ImmutableHttpProcessor;
-import org.apache.http.protocol.RequestConnControl;
-import org.apache.http.protocol.RequestContent;
-import org.apache.http.protocol.RequestExpectContinue;
-import org.apache.http.protocol.RequestTargetHost;
-import org.apache.http.protocol.RequestUserAgent;
-import org.apache.http.protocol.ResponseConnControl;
-import org.apache.http.protocol.ResponseContent;
-import org.apache.http.protocol.ResponseDate;
-import org.apache.http.protocol.ResponseServer;
-import org.apache.http.testserver.SimpleEventListener;
-import org.apache.http.testserver.SimpleNHttpRequestHandlerResolver;
-import org.apache.http.util.EncodingUtils;
-import org.junit.After;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-
-/**
- * HttpCore NIO integration tests for async handlers.
- */
- at Deprecated
-public class TestAsyncNHttpHandlers extends HttpCoreNIOTestBase {
-
-    @Before
-    public void setUp() throws Exception {
-        initServer();
-        initClient();
-    }
-
-    @After
-    public void tearDown() throws Exception {
-        shutDownClient();
-        shutDownServer();
-    }
-
-    @Override
-    protected NHttpConnectionFactory<DefaultNHttpServerConnection> createServerConnectionFactory(
-            final HttpParams params) throws Exception {
-        return new LoggingServerConnectionFactory(params);
-    }
-
-    @Override
-    protected NHttpConnectionFactory<DefaultNHttpClientConnection> createClientConnectionFactory(
-            final HttpParams params) throws Exception {
-        return new LoggingClientConnectionFactory(params);
-    }
-
-    private void executeStandardTest(
-            final NHttpRequestHandler requestHandler,
-            final NHttpRequestExecutionHandler requestExecutionHandler) throws Exception {
-        int connNo = 3;
-        int reqNo = 20;
-        Job[] jobs = new Job[connNo * reqNo];
-        for (int i = 0; i < jobs.length; i++) {
-            jobs[i] = new Job();
-        }
-        Queue<Job> queue = new ConcurrentLinkedQueue<Job>();
-        for (int i = 0; i < jobs.length; i++) {
-            queue.add(jobs[i]);
-        }
-
-        AsyncNHttpServiceHandler serviceHandler = new AsyncNHttpServiceHandler(
-                this.serverHttpProc,
-                new DefaultHttpResponseFactory(),
-                new DefaultConnectionReuseStrategy(),
-                this.serverParams);
-
-        serviceHandler.setHandlerResolver(
-                new SimpleNHttpRequestHandlerResolver(requestHandler));
-        serviceHandler.setEventListener(
-                new SimpleEventListener());
-
-        AsyncNHttpClientHandler clientHandler = new AsyncNHttpClientHandler(
-                this.clientHttpProc,
-                requestExecutionHandler,
-                new DefaultConnectionReuseStrategy(),
-                this.clientParams);
-
-        clientHandler.setEventListener(
-                new SimpleEventListener());
-
-        this.server.start(serviceHandler);
-        this.client.start(clientHandler);
-
-        ListenerEndpoint endpoint = this.server.getListenerEndpoint();
-        endpoint.waitFor();
-        InetSocketAddress serverAddress = (InetSocketAddress) endpoint.getAddress();
-
-        Assert.assertEquals("Test server status", IOReactorStatus.ACTIVE, this.server.getStatus());
-
-        Queue<SessionRequest> connRequests = new LinkedList<SessionRequest>();
-        for (int i = 0; i < connNo; i++) {
-            SessionRequest sessionRequest = this.client.openConnection(
-                    new InetSocketAddress("localhost", serverAddress.getPort()),
-                    queue);
-            connRequests.add(sessionRequest);
-        }
-
-        while (!connRequests.isEmpty()) {
-            SessionRequest sessionRequest = connRequests.remove();
-            sessionRequest.waitFor();
-            if (sessionRequest.getException() != null) {
-                throw sessionRequest.getException();
-            }
-            Assert.assertNotNull(sessionRequest.getSession());
-        }
-
-        Assert.assertEquals("Test client status", IOReactorStatus.ACTIVE, this.client.getStatus());
-
-        for (int i = 0; i < jobs.length; i++) {
-            Job testjob = jobs[i];
-            testjob.waitFor();
-            if (testjob.isSuccessful()) {
-                Assert.assertEquals(HttpStatus.SC_OK, testjob.getStatusCode());
-                Assert.assertEquals(testjob.getExpected(), testjob.getResult());
-            } else {
-                Assert.fail(testjob.getFailureMessage());
-            }
-        }
-    }
-
-    /**
-     * This test case executes a series of simple (non-pipelined) GET requests
-     * over multiple connections. This uses non-blocking output entities.
-     */
-    @Test
-    public void testHttpGets() throws Exception {
-        NHttpRequestExecutionHandler requestExecutionHandler = new RequestExecutionHandler() {
-
-            @Override
-            protected HttpRequest generateRequest(Job testjob) {
-                String s = testjob.getPattern() + "x" + testjob.getCount();
-                return new BasicHttpRequest("GET", s);
-            }
-
-        };
-        executeStandardTest(new RequestHandler(), requestExecutionHandler);
-    }
-
-    /**
-     * This test case executes a series of simple (non-pipelined) POST requests
-     * with content length delimited content over multiple connections.
-     * It uses purely asynchronous handlers.
-     */
-    @Test
-    public void testHttpPostsWithContentLength() throws Exception {
-        NHttpRequestExecutionHandler requestExecutionHandler = new RequestExecutionHandler() {
-
-            @Override
-            protected HttpRequest generateRequest(Job testjob) {
-                String s = testjob.getPattern() + "x" + testjob.getCount();
-                HttpEntityEnclosingRequest r = new BasicHttpEntityEnclosingRequest("POST", s);
-                NStringEntity entity = null;
-                try {
-                    entity = new NStringEntity(testjob.getExpected(), "US-ASCII");
-                    entity.setChunked(false);
-                } catch (UnsupportedEncodingException ignore) {
-                }
-                r.setEntity(entity);
-                return r;
-            }
-
-        };
-        executeStandardTest(new RequestHandler(), requestExecutionHandler);
-    }
-
-    /**
-     * This test case executes a series of simple (non-pipelined) POST requests
-     * with chunk coded content content over multiple connections.  This tests
-     * with nonblocking handlers & nonblocking entities.
-     */
-    @Test
-    public void testHttpPostsChunked() throws Exception {
-        NHttpRequestExecutionHandler requestExecutionHandler = new RequestExecutionHandler() {
-
-            @Override
-            protected HttpRequest generateRequest(Job testjob) {
-                String s = testjob.getPattern() + "x" + testjob.getCount();
-                HttpEntityEnclosingRequest r = new BasicHttpEntityEnclosingRequest("POST", s);
-                NStringEntity entity = null;
-                try {
-                    entity = new NStringEntity(testjob.getExpected(), "US-ASCII");
-                    entity.setChunked(true);
-                } catch (UnsupportedEncodingException ignore) {
-                }
-                r.setEntity(entity);
-                return r;
-            }
-
-        };
-        executeStandardTest(new RequestHandler(), requestExecutionHandler);
-    }
-
-    /**
-     * This test case executes a series of simple (non-pipelined) HTTP/1.0
-     * POST requests over multiple persistent connections. This tests with nonblocking
-     * handlers & entities.
-     */
-    @Test
-    public void testHttpPostsHTTP10() throws Exception {
-        NHttpRequestExecutionHandler requestExecutionHandler = new RequestExecutionHandler() {
-
-            @Override
-            protected HttpRequest generateRequest(Job testjob) {
-                String s = testjob.getPattern() + "x" + testjob.getCount();
-                HttpEntityEnclosingRequest r = new BasicHttpEntityEnclosingRequest("POST", s,
-                        HttpVersion.HTTP_1_0);
-                NStringEntity entity = null;
-                try {
-                    entity = new NStringEntity(testjob.getExpected(), "US-ASCII");
-                } catch (UnsupportedEncodingException ignore) {
-                }
-                r.setEntity(entity);
-                return r;
-            }
-
-        };
-        executeStandardTest(new RequestHandler(), requestExecutionHandler);
-    }
-
-    /**
-     * This test case executes a series of simple (non-pipelined) POST requests
-     * over multiple connections using the 'expect: continue' handshake.  This test
-     * uses nonblocking handlers & entities.
-     */
-    @Test
-    public void testHttpPostsWithExpectContinue() throws Exception {
-        NHttpRequestExecutionHandler requestExecutionHandler = new RequestExecutionHandler() {
-
-            @Override
-            protected HttpRequest generateRequest(Job testjob) {
-                String s = testjob.getPattern() + "x" + testjob.getCount();
-                HttpEntityEnclosingRequest r = new BasicHttpEntityEnclosingRequest("POST", s);
-                NStringEntity entity = null;
-                try {
-                    entity = new NStringEntity(testjob.getExpected(), "US-ASCII");
-                } catch (UnsupportedEncodingException ignore) {
-                }
-                r.setEntity(entity);
-                r.getParams().setBooleanParameter(CoreProtocolPNames.USE_EXPECT_CONTINUE, true);
-                return r;
-            }
-
-        };
-        executeStandardTest(new RequestHandler(), requestExecutionHandler);
-    }
-
-    /**
-     * This test case executes a series of simple (non-pipelined) POST requests
-     * one of which does not meet the target server expectations.
-     * This test uses nonblocking entities.
-     */
-    @Test
-    public void testHttpPostsWithExpectationVerification() throws Exception {
-        Job[] jobs = new Job[3];
-        jobs[0] = new Job("AAAAA", 10);
-        jobs[1] = new Job("AAAAA", 10);
-        jobs[2] = new Job("BBBBB", 20);
-        Queue<Job> queue = new ConcurrentLinkedQueue<Job>();
-        for (int i = 0; i < jobs.length; i++) {
-            queue.add(jobs[i]);
-        }
-
-        HttpExpectationVerifier expectationVerifier = new HttpExpectationVerifier() {
-
-            public void verify(
-                    final HttpRequest request,
-                    final HttpResponse response,
-                    final HttpContext context) throws HttpException {
-                String s = request.getRequestLine().getUri();
-                if (!s.equals("AAAAAx10")) {
-                    response.setStatusCode(HttpStatus.SC_EXPECTATION_FAILED);
-                    NByteArrayEntity outgoing = new NByteArrayEntity(
-                            EncodingUtils.getAsciiBytes("Expectation failed"));
-                    response.setEntity(outgoing);
-                }
-            }
-
-        };
-
-        NHttpRequestExecutionHandler requestExecutionHandler = new RequestExecutionHandler() {
-
-            @Override
-            protected HttpRequest generateRequest(Job testjob) {
-                String s = testjob.getPattern() + "x" + testjob.getCount();
-                HttpEntityEnclosingRequest r = new BasicHttpEntityEnclosingRequest("POST", s);
-                NStringEntity entity = null;
-                try {
-                    entity = new NStringEntity(testjob.getExpected(), "US-ASCII");
-                } catch (UnsupportedEncodingException ignore) {
-                }
-                r.setEntity(entity);
-                r.getParams().setBooleanParameter(CoreProtocolPNames.USE_EXPECT_CONTINUE, true);
-                return r;
-            }
-
-        };
-
-        HttpProcessor serverHttpProc = new ImmutableHttpProcessor(new HttpResponseInterceptor[] {
-                new ResponseDate(),
-                new ResponseServer(),
-                new ResponseContent(),
-                new ResponseConnControl()
-        });
-
-        AsyncNHttpServiceHandler serviceHandler = new AsyncNHttpServiceHandler(
-                serverHttpProc,
-                new DefaultHttpResponseFactory(),
-                new DefaultConnectionReuseStrategy(),
-                this.serverParams);
-
-        serviceHandler.setHandlerResolver(
-                new SimpleNHttpRequestHandlerResolver(new RequestHandler()));
-        serviceHandler.setExpectationVerifier(
-                expectationVerifier);
-        serviceHandler.setEventListener(
-                new SimpleEventListener());
-
-        HttpProcessor clientHttpProc = new ImmutableHttpProcessor(new HttpRequestInterceptor[] {
-                new RequestContent(),
-                new RequestTargetHost(),
-                new RequestConnControl(),
-                new RequestUserAgent(),
-                new RequestExpectContinue()});
-
-        AsyncNHttpClientHandler clientHandler = new AsyncNHttpClientHandler(
-                clientHttpProc,
-                requestExecutionHandler,
-                new DefaultConnectionReuseStrategy(),
-                this.clientParams);
-
-        clientHandler.setEventListener(new SimpleEventListener());
-
-        this.server.start(serviceHandler);
-        this.client.start(clientHandler);
-
-        ListenerEndpoint endpoint = this.server.getListenerEndpoint();
-        endpoint.waitFor();
-        InetSocketAddress serverAddress = (InetSocketAddress) endpoint.getAddress();
-
-        Assert.assertEquals("Test server status", IOReactorStatus.ACTIVE, this.server.getStatus());
-
-        SessionRequest sessionRequest = this.client.openConnection(
-                new InetSocketAddress("localhost", serverAddress.getPort()),
-                queue);
-
-        sessionRequest.waitFor();
-        if (sessionRequest.getException() != null) {
-            throw sessionRequest.getException();
-        }
-        Assert.assertNotNull(sessionRequest.getSession());
-
-        Assert.assertEquals("Test client status", IOReactorStatus.ACTIVE, this.client.getStatus());
-
-        for (int i = 0; i < 2; i++) {
-            Job testjob = jobs[i];
-            testjob.waitFor();
-            if (testjob.isSuccessful()) {
-                Assert.assertEquals(testjob.getExpected(), testjob.getResult());
-            } else {
-                Assert.fail(testjob.getFailureMessage());
-            }
-        }
-        Job failedExpectation = jobs[2];
-        failedExpectation.waitFor();
-        Assert.assertEquals(HttpStatus.SC_EXPECTATION_FAILED, failedExpectation.getStatusCode());
-    }
-
-    /**
-     * This test case executes a series of simple (non-pipelined) HEAD requests
-     * over multiple connections. This test uses nonblocking entities.
-     */
-    @Test
-    public void testHttpHeads() throws Exception {
-        int connNo = 3;
-        int reqNo = 20;
-        Job[] jobs = new Job[connNo * reqNo];
-        for (int i = 0; i < jobs.length; i++) {
-            jobs[i] = new Job();
-        }
-        Queue<Job> queue = new ConcurrentLinkedQueue<Job>();
-        for (int i = 0; i < jobs.length; i++) {
-            queue.add(jobs[i]);
-        }
-
-        NHttpRequestExecutionHandler requestExecutionHandler = new RequestExecutionHandler() {
-
-            @Override
-            protected HttpRequest generateRequest(Job testjob) {
-                String s = testjob.getPattern() + "x" + testjob.getCount();
-                return new BasicHttpRequest("HEAD", s);
-            }
-
-        };
-
-        HttpProcessor serverHttpProc = new ImmutableHttpProcessor(new HttpResponseInterceptor[] {
-                new ResponseDate(),
-                new ResponseServer(),
-                new ResponseContent(),
-                new ResponseConnControl()
-        });
-
-        AsyncNHttpServiceHandler serviceHandler = new AsyncNHttpServiceHandler(
-                serverHttpProc,
-                new DefaultHttpResponseFactory(),
-                new DefaultConnectionReuseStrategy(),
-                this.serverParams);
-
-        serviceHandler.setHandlerResolver(
-                new SimpleNHttpRequestHandlerResolver(new RequestHandler()));
-        serviceHandler.setEventListener(
-                new SimpleEventListener());
-
-        HttpProcessor clientHttpProc = new ImmutableHttpProcessor(new HttpRequestInterceptor[] {
-                new RequestContent(),
-                new RequestTargetHost(),
-                new RequestConnControl(),
-                new RequestUserAgent(),
-                new RequestExpectContinue()});
-
-        AsyncNHttpClientHandler clientHandler = new AsyncNHttpClientHandler(
-                clientHttpProc,
-                requestExecutionHandler,
-                new DefaultConnectionReuseStrategy(),
-                this.clientParams);
-
-        clientHandler.setEventListener(new SimpleEventListener());
-
-        this.server.start(serviceHandler);
-        this.client.start(clientHandler);
-
-        ListenerEndpoint endpoint = this.server.getListenerEndpoint();
-        endpoint.waitFor();
-        InetSocketAddress serverAddress = (InetSocketAddress) endpoint.getAddress();
-
-        Assert.assertEquals("Test server status", IOReactorStatus.ACTIVE, this.server.getStatus());
-
-        Queue<SessionRequest> connRequests = new LinkedList<SessionRequest>();
-        for (int i = 0; i < connNo; i++) {
-            SessionRequest sessionRequest = this.client.openConnection(
-                    new InetSocketAddress("localhost", serverAddress.getPort()),
-                    queue);
-            connRequests.add(sessionRequest);
-        }
-
-        while (!connRequests.isEmpty()) {
-            SessionRequest sessionRequest = connRequests.remove();
-            sessionRequest.waitFor();
-            if (sessionRequest.getException() != null) {
-                throw sessionRequest.getException();
-            }
-            Assert.assertNotNull(sessionRequest.getSession());
-        }
-
-        Assert.assertEquals("Test client status", IOReactorStatus.ACTIVE, this.client.getStatus());
-
-        for (int i = 0; i < jobs.length; i++) {
-            Job testjob = jobs[i];
-            testjob.waitFor();
-            if (testjob.getFailureMessage() != null) {
-                Assert.fail(testjob.getFailureMessage());
-            }
-            Assert.assertEquals(HttpStatus.SC_OK, testjob.getStatusCode());
-            Assert.assertNull(testjob.getResult());
-        }
-    }
-
-    /**
-     * This test executes a series of delayed GETs, ensuring the
-     * {@link NHttpResponseTrigger} works correctly.
-     */
-    @Test
-    public void testDelayedHttpGets() throws Exception {
-
-        NHttpRequestHandler requestHandler = new NHttpRequestHandler() {
-
-            public ConsumingNHttpEntity entityRequest(
-                    final HttpEntityEnclosingRequest request,
-                    final HttpContext context) {
-                return null;
-            }
-
-            public void handle(
-                    final HttpRequest request,
-                    final HttpResponse response,
-                    final NHttpResponseTrigger trigger,
-                    final HttpContext context) throws HttpException, IOException {
-                String s = request.getRequestLine().getUri();
-                int idx = s.indexOf('x');
-                if (idx == -1) {
-                    throw new HttpException("Unexpected request-URI format");
-                }
-                String pattern = s.substring(0, idx);
-                int count = Integer.parseInt(s.substring(idx + 1, s.length()));
-
-                StringBuilder buffer = new StringBuilder();
-                for (int i = 0; i < count; i++) {
-                    buffer.append(pattern);
-                }
-                final String content = buffer.toString();
-
-                new Thread() {
-                    @Override
-                    public void run() {
-                        // Wait a bit, to make sure this is delayed.
-                        try { Thread.sleep(10); } catch(InterruptedException ie) {}
-                        // Set the entity after delaying...
-                        try {
-                            NStringEntity entity = new NStringEntity(content, "US-ASCII");
-                            response.setEntity(entity);
-                        }  catch (UnsupportedEncodingException ex) {
-                        }
-                        trigger.submitResponse(response);
-                    }
-                }.start();
-            }
-
-        };
-
-        NHttpRequestExecutionHandler requestExecutionHandler = new RequestExecutionHandler() {
-
-            @Override
-            protected HttpRequest generateRequest(Job testjob) {
-                String s = testjob.getPattern() + "x" + testjob.getCount();
-                return new BasicHttpRequest("GET", s);
-            }
-
-        };
-        executeStandardTest(requestHandler, requestExecutionHandler);
-    }
-
-    /**
-     * This test ensures that HttpExceptions work correctly when immediate.
-     */
-    @Test
-    public void testHttpException() throws Exception {
-
-        NHttpRequestHandler requestHandler = new SimpleNHttpRequestHandler() {
-
-            public ConsumingNHttpEntity entityRequest(
-                    final HttpEntityEnclosingRequest request,
-                    final HttpContext context) {
-                return null;
-            }
-
-            @Override
-            public void handle(
-                    final HttpRequest request,
-                    final HttpResponse response,
-                    final HttpContext context) throws HttpException, IOException {
-                throw new HttpException(request.getRequestLine().getUri());
-            }
-
-        };
-
-        NHttpRequestExecutionHandler requestExecutionHandler = new RequestExecutionHandler() {
-
-            @Override
-            protected HttpRequest generateRequest(Job testjob) {
-                String s = testjob.getPattern() + "x" + testjob.getCount();
-                return new BasicHttpRequest("GET", s);
-            }
-
-        };
-
-        int connNo = 3;
-        int reqNo = 20;
-        Job[] jobs = new Job[connNo * reqNo];
-        for (int i = 0; i < jobs.length; i++) {
-            jobs[i] = new Job();
-        }
-        Queue<Job> queue = new ConcurrentLinkedQueue<Job>();
-        for (int i = 0; i < jobs.length; i++) {
-            queue.add(jobs[i]);
-        }
-
-        HttpProcessor serverHttpProc = new ImmutableHttpProcessor(new HttpResponseInterceptor[] {
-                new ResponseDate(),
-                new ResponseServer(),
-                new ResponseContent(),
-                new ResponseConnControl()
-        });
-
-        AsyncNHttpServiceHandler serviceHandler = new AsyncNHttpServiceHandler(
-                serverHttpProc,
-                new DefaultHttpResponseFactory(),
-                new DefaultConnectionReuseStrategy(),
-                this.serverParams);
-
-        serviceHandler.setHandlerResolver(
-                new SimpleNHttpRequestHandlerResolver(requestHandler));
-        serviceHandler.setEventListener(
-                new SimpleEventListener());
-
-        HttpProcessor clientHttpProc = new ImmutableHttpProcessor(new HttpRequestInterceptor[] {
-                new RequestContent(),
-                new RequestTargetHost(),
-                new RequestConnControl(),
-                new RequestUserAgent(),
-                new RequestExpectContinue()});
-
-        AsyncNHttpClientHandler clientHandler = new AsyncNHttpClientHandler(
-                clientHttpProc,
-                requestExecutionHandler,
-                new DefaultConnectionReuseStrategy(),
-                this.clientParams);
-
-        clientHandler.setEventListener(new SimpleEventListener());
-
-        this.server.start(serviceHandler);
-        this.client.start(clientHandler);
-
-        ListenerEndpoint endpoint = this.server.getListenerEndpoint();
-        endpoint.waitFor();
-        InetSocketAddress serverAddress = (InetSocketAddress) endpoint.getAddress();
-
-        Assert.assertEquals("Test server status", IOReactorStatus.ACTIVE, this.server.getStatus());
-
-        Queue<SessionRequest> connRequests = new LinkedList<SessionRequest>();
-        for (int i = 0; i < connNo; i++) {
-            SessionRequest sessionRequest = this.client.openConnection(
-                    new InetSocketAddress("localhost", serverAddress.getPort()),
-                    queue);
-            connRequests.add(sessionRequest);
-        }
-
-        while (!connRequests.isEmpty()) {
-            SessionRequest sessionRequest = connRequests.remove();
-            sessionRequest.waitFor();
-            if (sessionRequest.getException() != null) {
-                throw sessionRequest.getException();
-            }
-            Assert.assertNotNull(sessionRequest.getSession());
-        }
-
-        Assert.assertEquals("Test client status", IOReactorStatus.ACTIVE, this.client.getStatus());
-
-        for (int i = 0; i < jobs.length; i++) {
-            Job testjob = jobs[i];
-            testjob.waitFor();
-            if (testjob.isSuccessful()) {
-                Assert.assertEquals(HttpStatus.SC_INTERNAL_SERVER_ERROR, testjob.getStatusCode());
-                Assert.assertEquals(testjob.getPattern() + "x" + testjob.getCount(), testjob.getResult());
-            } else {
-                Assert.fail(testjob.getFailureMessage());
-            }
-        }
-    }
-
-    /**
-     * This test ensures that HttpExceptions work correctly when they are delayed by a trigger.
-     */
-    @Test
-    public void testDelayedHttpException() throws Exception {
-
-        NHttpRequestHandler requestHandler = new NHttpRequestHandler() {
-
-            public ConsumingNHttpEntity entityRequest(
-                    final HttpEntityEnclosingRequest request,
-                    final HttpContext context) {
-                return null;
-            }
-            public void handle(final HttpRequest request, HttpResponse response,
-                    final NHttpResponseTrigger trigger, HttpContext context)
-                    throws HttpException, IOException {
-                new Thread() {
-                    @Override
-                    public void run() {
-                        try { Thread.sleep(10); } catch(InterruptedException ie) {}
-                        trigger.handleException(
-                                new HttpException(request.getRequestLine().getUri()));
-                    }
-                }.start();
-            }
-
-        };
-
-        NHttpRequestExecutionHandler requestExecutionHandler = new RequestExecutionHandler() {
-
-            @Override
-            protected HttpRequest generateRequest(Job testjob) {
-                String s = testjob.getPattern() + "x" + testjob.getCount();
-                return new BasicHttpRequest("GET", s);
-            }
-
-        };
-
-        int connNo = 3;
-        int reqNo = 20;
-        Job[] jobs = new Job[connNo * reqNo];
-        for (int i = 0; i < jobs.length; i++) {
-            jobs[i] = new Job();
-        }
-        Queue<Job> queue = new ConcurrentLinkedQueue<Job>();
-        for (int i = 0; i < jobs.length; i++) {
-            queue.add(jobs[i]);
-        }
-
-        HttpProcessor serverHttpProc = new ImmutableHttpProcessor(new HttpResponseInterceptor[] {
-                new ResponseDate(),
-                new ResponseServer(),
-                new ResponseContent(),
-                new ResponseConnControl()
-        });
-
-        AsyncNHttpServiceHandler serviceHandler = new AsyncNHttpServiceHandler(
-                serverHttpProc,
-                new DefaultHttpResponseFactory(),
-                new DefaultConnectionReuseStrategy(),
-                this.serverParams);
-
-        serviceHandler.setHandlerResolver(
-                new SimpleNHttpRequestHandlerResolver(requestHandler));
-        serviceHandler.setEventListener(
-                new SimpleEventListener());
-
-        HttpProcessor clientHttpProc = new ImmutableHttpProcessor(new HttpRequestInterceptor[] {
-                new RequestContent(),
-                new RequestTargetHost(),
-                new RequestConnControl(),
-                new RequestUserAgent(),
-                new RequestExpectContinue()});
-
-        AsyncNHttpClientHandler clientHandler = new AsyncNHttpClientHandler(
-                clientHttpProc,
-                requestExecutionHandler,
-                new DefaultConnectionReuseStrategy(),
-                this.clientParams);
-
-        clientHandler.setEventListener(new SimpleEventListener());
-
-        this.server.start(serviceHandler);
-        this.client.start(clientHandler);
-
-        ListenerEndpoint endpoint = this.server.getListenerEndpoint();
-        endpoint.waitFor();
-        InetSocketAddress serverAddress = (InetSocketAddress) endpoint.getAddress();
-
-        Assert.assertEquals("Test server status", IOReactorStatus.ACTIVE, this.server.getStatus());
-
-        Queue<SessionRequest> connRequests = new LinkedList<SessionRequest>();
-        for (int i = 0; i < connNo; i++) {
-            SessionRequest sessionRequest = this.client.openConnection(
-                    new InetSocketAddress("localhost", serverAddress.getPort()),
-                    queue);
-            connRequests.add(sessionRequest);
-        }
-
-        while (!connRequests.isEmpty()) {
-            SessionRequest sessionRequest = connRequests.remove();
-            sessionRequest.waitFor();
-            if (sessionRequest.getException() != null) {
-                throw sessionRequest.getException();
-            }
-            Assert.assertNotNull(sessionRequest.getSession());
-        }
-
-        Assert.assertEquals("Test client status", IOReactorStatus.ACTIVE, this.client.getStatus());
-
-        for (int i = 0; i < jobs.length; i++) {
-            Job testjob = jobs[i];
-            testjob.waitFor();
-            if (testjob.isSuccessful()) {
-                Assert.assertEquals(HttpStatus.SC_INTERNAL_SERVER_ERROR, testjob.getStatusCode());
-                Assert.assertEquals(testjob.getPattern() + "x" + testjob.getCount(), testjob.getResult());
-            } else {
-                Assert.fail(testjob.getFailureMessage());
-            }
-        }
-    }
-
-    /**
-     * This test makes sure that if no service handler is installed, things still work.
-     */
-    @Test
-    public void testNoServiceHandler() throws Exception {
-        NHttpRequestExecutionHandler requestExecutionHandler = new RequestExecutionHandler() {
-
-            @Override
-            protected HttpRequest generateRequest(Job testjob) {
-                String s = testjob.getPattern() + "x" + testjob.getCount();
-                return new BasicHttpRequest("GET", s);
-            }
-
-        };
-
-        int connNo = 5;
-        Job[] jobs = new Job[connNo];
-        for (int i = 0; i < jobs.length; i++) {
-            jobs[i] = new Job();
-        }
-        Queue<Job> queue = new ConcurrentLinkedQueue<Job>();
-        for (int i = 0; i < jobs.length; i++) {
-            queue.add(jobs[i]);
-        }
-
-        HttpProcessor serverHttpProc = new ImmutableHttpProcessor(new HttpResponseInterceptor[] {
-                new ResponseDate(),
-                new ResponseServer(),
-                new ResponseContent(),
-                new ResponseConnControl()
-        });
-
-        AsyncNHttpServiceHandler serviceHandler = new AsyncNHttpServiceHandler(
-                serverHttpProc,
-                new DefaultHttpResponseFactory(),
-                new DefaultConnectionReuseStrategy(),
-                this.serverParams);
-
-        serviceHandler.setEventListener(
-                new SimpleEventListener());
-
-        HttpProcessor clientHttpProc = new ImmutableHttpProcessor(new HttpRequestInterceptor[] {
-                new RequestContent(),
-                new RequestTargetHost(),
-                new RequestConnControl(),
-                new RequestUserAgent(),
-                new RequestExpectContinue()});
-
-        AsyncNHttpClientHandler clientHandler = new AsyncNHttpClientHandler(
-                clientHttpProc,
-                requestExecutionHandler,
-                new DefaultConnectionReuseStrategy(),
-                this.clientParams);
-
-        clientHandler.setEventListener(new SimpleEventListener());
-
-        this.server.start(serviceHandler);
-        this.client.start(clientHandler);
-
-        ListenerEndpoint endpoint = this.server.getListenerEndpoint();
-        endpoint.waitFor();
-        InetSocketAddress serverAddress = (InetSocketAddress) endpoint.getAddress();
-
-        Assert.assertEquals("Test server status", IOReactorStatus.ACTIVE, this.server.getStatus());
-
-        Queue<SessionRequest> connRequests = new LinkedList<SessionRequest>();
-        for (int i = 0; i < connNo; i++) {
-            SessionRequest sessionRequest = this.client.openConnection(
-                    new InetSocketAddress("localhost", serverAddress.getPort()),
-                    queue);
-            connRequests.add(sessionRequest);
-        }
-
-        while (!connRequests.isEmpty()) {
-            SessionRequest sessionRequest = connRequests.remove();
-            sessionRequest.waitFor();
-            if (sessionRequest.getException() != null) {
-                throw sessionRequest.getException();
-            }
-            Assert.assertNotNull(sessionRequest.getSession());
-        }
-
-        Assert.assertEquals("Test client status", IOReactorStatus.ACTIVE, this.client.getStatus());
-
-        for (int i = 0; i < jobs.length; i++) {
-            Job testjob = jobs[i];
-
-            testjob.waitFor();
-            if (testjob.isSuccessful()) {
-                Assert.assertEquals(HttpStatus.SC_NOT_IMPLEMENTED, testjob.getStatusCode());
-                Assert.assertEquals("", testjob.getResult());
-            } else {
-                Assert.fail(testjob.getFailureMessage());
-            }
-        }
-    }
-
-    /**
-     * This test case executes a series of simple (non-pipelined) POST requests
-     * with no entities on the client side, to ensure they are sent properly,
-     * and the server can read them.
-     */
-    @Test
-    public void testHttpPostWithNoEntities() throws Exception {
-        NHttpRequestExecutionHandler requestExecutionHandler = new RequestExecutionHandler() {
-
-            @Override
-            protected HttpRequest generateRequest(Job testjob) {
-                String s = testjob.getPattern() + "x" + testjob.getCount();
-                HttpEntityEnclosingRequest r = new BasicHttpEntityEnclosingRequest("POST", s);
-                r.setEntity(null);
-                return r;
-            }
-
-        };
-
-        int connNo = 3;
-        int reqNo = 20;
-        Job[] jobs = new Job[connNo * reqNo];
-        for (int i = 0; i < jobs.length; i++) {
-            jobs[i] = new Job();
-        }
-        Queue<Job> queue = new ConcurrentLinkedQueue<Job>();
-        for (int i = 0; i < jobs.length; i++) {
-            queue.add(jobs[i]);
-        }
-
-        HttpProcessor serverHttpProc = new ImmutableHttpProcessor(new HttpResponseInterceptor[] {
-                new ResponseDate(),
-                new ResponseServer(),
-                new ResponseContent(),
-                new ResponseConnControl()
-        });
-
-        AsyncNHttpServiceHandler serviceHandler = new AsyncNHttpServiceHandler(
-                serverHttpProc,
-                new DefaultHttpResponseFactory(),
-                new DefaultConnectionReuseStrategy(),
-                this.serverParams);
-
-        serviceHandler.setHandlerResolver(
-                new SimpleNHttpRequestHandlerResolver(new RequestHandler()));
-        serviceHandler.setEventListener(
-                new SimpleEventListener());
-
-        HttpProcessor clientHttpProc = new ImmutableHttpProcessor(new HttpRequestInterceptor[] {
-                new RequestContent(),
-                new RequestTargetHost(),
-                new RequestConnControl(),
-                new RequestUserAgent(),
-                new RequestExpectContinue()});
-
-        AsyncNHttpClientHandler clientHandler = new AsyncNHttpClientHandler(
-                clientHttpProc,
-                requestExecutionHandler,
-                new DefaultConnectionReuseStrategy(),
-                this.clientParams);
-
-        clientHandler.setEventListener(new SimpleEventListener());
-
-        this.server.start(serviceHandler);
-        this.client.start(clientHandler);
-
-        ListenerEndpoint endpoint = this.server.getListenerEndpoint();
-        endpoint.waitFor();
-        InetSocketAddress serverAddress = (InetSocketAddress) endpoint.getAddress();
-
-        Assert.assertEquals("Test server status", IOReactorStatus.ACTIVE, this.server.getStatus());
-
-        Queue<SessionRequest> connRequests = new LinkedList<SessionRequest>();
-        for (int i = 0; i < connNo; i++) {
-            SessionRequest sessionRequest = this.client.openConnection(
-                    new InetSocketAddress("localhost", serverAddress.getPort()),
-                    queue);
-            connRequests.add(sessionRequest);
-        }
-
-        while (!connRequests.isEmpty()) {
-            SessionRequest sessionRequest = connRequests.remove();
-            sessionRequest.waitFor();
-            if (sessionRequest.getException() != null) {
-                throw sessionRequest.getException();
-            }
-            Assert.assertNotNull(sessionRequest.getSession());
-        }
-
-        Assert.assertEquals("Test client status", IOReactorStatus.ACTIVE, this.client.getStatus());
-
-        for (int i = 0; i < jobs.length; i++) {
-            Job testjob = jobs[i];
-            testjob.waitFor();
-            if (testjob.isSuccessful()) {
-                Assert.assertEquals(HttpStatus.SC_OK, testjob.getStatusCode());
-                Assert.assertEquals("", testjob.getResult());
-            } else {
-                Assert.fail(testjob.getFailureMessage());
-            }
-        }
-    }
-
-    @Test
-    public void testNoRequestHandler() throws Exception {
-        NHttpRequestExecutionHandler requestExecutionHandler = new RequestExecutionHandler() {
-
-            @Override
-            protected HttpRequest generateRequest(Job testjob) {
-                String s = testjob.getPattern() + "x" + testjob.getCount();
-                HttpEntityEnclosingRequest r = new BasicHttpEntityEnclosingRequest("POST", s);
-                NByteArrayEntity entity = new NByteArrayEntity(new byte[] {1,2,3,4,5} );
-                entity.setChunked(false);
-                r.setEntity(entity);
-                return r;
-            }
-
-        };
-
-        int connNo = 3;
-        Job[] jobs = new Job[connNo];
-        for (int i = 0; i < jobs.length; i++) {
-            jobs[i] = new Job();
-        }
-        Queue<Job> queue = new ConcurrentLinkedQueue<Job>();
-        for (int i = 0; i < jobs.length; i++) {
-            queue.add(jobs[i]);
-        }
-
-        HttpProcessor serverHttpProc = new ImmutableHttpProcessor(new HttpResponseInterceptor[] {
-                new ResponseDate(),
-                new ResponseServer(),
-                new ResponseContent(),
-                new ResponseConnControl()
-        });
-
-        AsyncNHttpServiceHandler serviceHandler = new AsyncNHttpServiceHandler(
-                serverHttpProc,
-                new DefaultHttpResponseFactory(),
-                new DefaultConnectionReuseStrategy(),
-                this.serverParams);
-
-        serviceHandler.setHandlerResolver(
-                new SimpleNHttpRequestHandlerResolver(null));
-        serviceHandler.setEventListener(
-                new SimpleEventListener());
-
-        HttpProcessor clientHttpProc = new ImmutableHttpProcessor(new HttpRequestInterceptor[] {
-                new RequestContent(),
-                new RequestTargetHost(),
-                new RequestConnControl(),
-                new RequestUserAgent(),
-                new RequestExpectContinue()});
-
-        AsyncNHttpClientHandler clientHandler = new AsyncNHttpClientHandler(
-                clientHttpProc,
-                requestExecutionHandler,
-                new DefaultConnectionReuseStrategy(),
-                this.clientParams);
-
-        clientHandler.setEventListener(new SimpleEventListener());
-
-        this.server.start(serviceHandler);
-        this.client.start(clientHandler);
-
-        ListenerEndpoint endpoint = this.server.getListenerEndpoint();
-        endpoint.waitFor();
-        InetSocketAddress serverAddress = (InetSocketAddress) endpoint.getAddress();
-
-        Assert.assertEquals("Test server status", IOReactorStatus.ACTIVE, this.server.getStatus());
-
-        Queue<SessionRequest> connRequests = new LinkedList<SessionRequest>();
-        for (int i = 0; i < connNo; i++) {
-            SessionRequest sessionRequest = this.client.openConnection(
-                    new InetSocketAddress("localhost", serverAddress.getPort()),
-                    queue);
-            connRequests.add(sessionRequest);
-        }
-
-        while (!connRequests.isEmpty()) {
-            SessionRequest sessionRequest = connRequests.remove();
-            sessionRequest.waitFor();
-            if (sessionRequest.getException() != null) {
-                throw sessionRequest.getException();
-            }
-            Assert.assertNotNull(sessionRequest.getSession());
-        }
-
-        Assert.assertEquals("Test client status", IOReactorStatus.ACTIVE, this.client.getStatus());
-
-        for (int i = 0; i < jobs.length; i++) {
-            Job testjob = jobs[i];
-            testjob.waitFor();
-            if (testjob.isSuccessful()) {
-                Assert.assertEquals(HttpStatus.SC_NOT_IMPLEMENTED, testjob.getStatusCode());
-            } else {
-                Assert.fail(testjob.getFailureMessage());
-            }
-        }
-    }
-}
diff --git a/httpcore-nio/src/test/java/org/apache/http/nio/integration/TestCustomSSL.java b/httpcore-nio/src/test/java/org/apache/http/nio/integration/TestCustomSSL.java
new file mode 100644
index 0000000..87c6997
--- /dev/null
+++ b/httpcore-nio/src/test/java/org/apache/http/nio/integration/TestCustomSSL.java
@@ -0,0 +1,148 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+
+package org.apache.http.nio.integration;
+
+import org.apache.http.HttpException;
+import org.apache.http.HttpHost;
+import org.apache.http.HttpRequest;
+import org.apache.http.HttpResponse;
+import org.apache.http.impl.nio.pool.BasicNIOConnFactory;
+import org.apache.http.message.BasicHttpRequest;
+import org.apache.http.nio.NHttpConnection;
+import org.apache.http.nio.protocol.BasicAsyncRequestHandler;
+import org.apache.http.nio.protocol.UriHttpAsyncRequestHandlerMapper;
+import org.apache.http.nio.reactor.IOReactorStatus;
+import org.apache.http.nio.reactor.IOSession;
+import org.apache.http.nio.reactor.ListenerEndpoint;
+import org.apache.http.nio.reactor.ssl.SSLSetupHandler;
+import org.apache.http.nio.testserver.HttpClientNio;
+import org.apache.http.nio.testserver.HttpServerNio;
+import org.apache.http.nio.testserver.LoggingSSLClientConnectionFactory;
+import org.apache.http.nio.testserver.LoggingSSLServerConnectionFactory;
+import org.apache.http.nio.testserver.SSLTestContexts;
+import org.apache.http.nio.testserver.SimpleIOReactorExceptionHandler;
+import org.apache.http.protocol.HttpContext;
+import org.apache.http.protocol.HttpCoreContext;
+import org.apache.http.protocol.HttpRequestHandler;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Test;
+
+import javax.net.ssl.SSLEngine;
+import javax.net.ssl.SSLException;
+import javax.net.ssl.SSLSession;
+import java.io.IOException;
+import java.math.BigInteger;
+import java.net.InetSocketAddress;
+import java.util.concurrent.Future;
+
+public class TestCustomSSL {
+
+    protected HttpServerNio server;
+    protected HttpClientNio client;
+
+    @After
+    public void shutDownClient() throws Exception {
+        if (this.client != null) {
+            this.client.shutdown();
+            this.client = null;
+        }
+    }
+
+    @After
+    public void shutDownServer() throws Exception {
+        if (this.server != null) {
+            this.server.shutdown();
+            this.server = null;
+        }
+    }
+
+    @Test
+    public void testCustomSSLContext() throws Exception {
+        final SSLSetupHandler sslSetupHandler = new SSLSetupHandler() {
+
+            public void initalize(
+                    final SSLEngine sslengine) throws SSLException {
+            }
+
+            public void verify(
+                    final IOSession iosession, final SSLSession sslsession) throws SSLException {
+                final BigInteger sslid = new BigInteger(sslsession.getId());
+                iosession.setAttribute("ssl-id", sslid);
+            }
+
+        };
+
+        final HttpRequestHandler requestHandler = new HttpRequestHandler() {
+
+            public void handle(
+                    final HttpRequest request,
+                    final HttpResponse response,
+                    final HttpContext context) throws HttpException, IOException {
+                final NHttpConnection conn = (NHttpConnection) context.getAttribute(
+                        HttpCoreContext.HTTP_CONNECTION);
+                final BigInteger sslid = (BigInteger) conn.getContext().getAttribute(
+                        "ssl-id");
+                Assert.assertNotNull(sslid);
+            }
+
+        };
+
+        this.server = new HttpServerNio(
+                new LoggingSSLServerConnectionFactory(
+                        SSLTestContexts.createServerSSLContext(), sslSetupHandler));
+        this.server.setExceptionHandler(new SimpleIOReactorExceptionHandler());
+        this.server.setTimeout(5000);
+        this.client = new HttpClientNio(
+                new BasicNIOConnFactory(
+                        new LoggingSSLClientConnectionFactory(
+                                SSLTestContexts.createClientSSLContext()), null));
+        this.client.setExceptionHandler(new SimpleIOReactorExceptionHandler());
+        this.client.setTimeout(5000);
+
+        final UriHttpAsyncRequestHandlerMapper registry = new UriHttpAsyncRequestHandlerMapper();
+        registry.register("*", new BasicAsyncRequestHandler(requestHandler));
+
+        this.server.start(HttpServerNio.DEFAULT_HTTP_PROC, registry, null);
+        this.client.start(HttpClientNio.DEFAULT_HTTP_PROC);
+
+        final ListenerEndpoint endpoint = this.server.getListenerEndpoint();
+        endpoint.waitFor();
+
+        Assert.assertEquals("Test server status", IOReactorStatus.ACTIVE, this.server.getStatus());
+        final InetSocketAddress address = (InetSocketAddress) endpoint.getAddress();
+
+        final HttpHost target = new HttpHost("localhost", address.getPort());
+        final BasicHttpRequest request = new BasicHttpRequest("GET", "/");
+        final Future<HttpResponse> future = this.client.execute(target, request);
+        final HttpResponse response = future.get();
+        Assert.assertNotNull(response);
+        Assert.assertEquals(200, response.getStatusLine().getStatusCode());
+    }
+
+}
diff --git a/httpcore-nio/src/test/java/org/apache/http/nio/integration/TestHttpAsyncHandlerCancellable.java b/httpcore-nio/src/test/java/org/apache/http/nio/integration/TestHttpAsyncHandlerCancellable.java
index e3ea157..d32b8d9 100644
--- a/httpcore-nio/src/test/java/org/apache/http/nio/integration/TestHttpAsyncHandlerCancellable.java
+++ b/httpcore-nio/src/test/java/org/apache/http/nio/integration/TestHttpAsyncHandlerCancellable.java
@@ -36,18 +36,13 @@ import java.net.Socket;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
 
-import org.apache.http.HttpCoreNIOTestBase;
 import org.apache.http.HttpException;
 import org.apache.http.HttpRequest;
 import org.apache.http.HttpResponse;
 import org.apache.http.HttpVersion;
-import org.apache.http.LoggingClientConnectionFactory;
-import org.apache.http.LoggingServerConnectionFactory;
 import org.apache.http.concurrent.Cancellable;
 import org.apache.http.entity.BasicHttpEntity;
 import org.apache.http.entity.ContentType;
-import org.apache.http.impl.DefaultConnectionReuseStrategy;
-import org.apache.http.impl.DefaultHttpResponseFactory;
 import org.apache.http.impl.nio.DefaultNHttpClientConnection;
 import org.apache.http.impl.nio.DefaultNHttpServerConnection;
 import org.apache.http.message.BasicHttpResponse;
@@ -58,12 +53,13 @@ import org.apache.http.nio.protocol.BasicAsyncRequestConsumer;
 import org.apache.http.nio.protocol.HttpAsyncExchange;
 import org.apache.http.nio.protocol.HttpAsyncRequestConsumer;
 import org.apache.http.nio.protocol.HttpAsyncRequestHandler;
-import org.apache.http.nio.protocol.HttpAsyncRequestHandlerRegistry;
 import org.apache.http.nio.protocol.HttpAsyncResponseProducer;
-import org.apache.http.nio.protocol.HttpAsyncService;
+import org.apache.http.nio.protocol.UriHttpAsyncRequestHandlerMapper;
 import org.apache.http.nio.reactor.IOReactorStatus;
 import org.apache.http.nio.reactor.ListenerEndpoint;
-import org.apache.http.params.HttpParams;
+import org.apache.http.nio.testserver.HttpCoreNIOTestBase;
+import org.apache.http.nio.testserver.LoggingClientConnectionFactory;
+import org.apache.http.nio.testserver.LoggingServerConnectionFactory;
 import org.apache.http.protocol.HttpContext;
 import org.junit.After;
 import org.junit.Assert;
@@ -83,51 +79,49 @@ public class TestHttpAsyncHandlerCancellable extends HttpCoreNIOTestBase {
     }
 
     @Override
-    protected NHttpConnectionFactory<DefaultNHttpServerConnection> createServerConnectionFactory(
-            final HttpParams params) throws Exception {
-        return new LoggingServerConnectionFactory(params);
+    protected NHttpConnectionFactory<DefaultNHttpServerConnection> createServerConnectionFactory() throws Exception {
+        return new LoggingServerConnectionFactory();
     }
 
     @Override
-    protected NHttpConnectionFactory<DefaultNHttpClientConnection> createClientConnectionFactory(
-            final HttpParams params) throws Exception {
-        return new LoggingClientConnectionFactory(params);
+    protected NHttpConnectionFactory<DefaultNHttpClientConnection> createClientConnectionFactory() throws Exception {
+        return new LoggingClientConnectionFactory();
     }
 
     @Test
     public void testResponsePrematureTermination() throws Exception {
-        
+
         final CountDownLatch latch = new CountDownLatch(1);
         final HttpAsyncResponseProducer responseProducer = new HttpAsyncResponseProducer() {
-            
+
             public HttpResponse generateResponse() {
-                HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
-                BasicHttpEntity entity = new BasicHttpEntity();
+                final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
+                final BasicHttpEntity entity = new BasicHttpEntity();
                 entity.setContentType(ContentType.DEFAULT_BINARY.toString());
                 entity.setChunked(true);
                 response.setEntity(entity);
                 return response;
             }
-            
+
             public void close() throws IOException {
                 latch.countDown();
             }
-            
+
             public void responseCompleted(final HttpContext context) {
             }
-            
+
             public void produceContent(
                     final ContentEncoder encoder, final IOControl ioctrl) throws IOException {
                 // suspend output
                 ioctrl.suspendOutput();
             }
-            
+
             public void failed(final Exception ex) {
             }
 
         };
-        
-        HttpAsyncRequestHandlerRegistry registry = new HttpAsyncRequestHandlerRegistry();
+
+        final UriHttpAsyncRequestHandlerMapper registry = new UriHttpAsyncRequestHandlerMapper();
         registry.register("*", new HttpAsyncRequestHandler<HttpRequest>() {
 
             public HttpAsyncRequestConsumer<HttpRequest> processRequest(
@@ -137,39 +131,32 @@ public class TestHttpAsyncHandlerCancellable extends HttpCoreNIOTestBase {
             }
 
             public void handle(
-                    final HttpRequest data, 
-                    final HttpAsyncExchange httpExchange, 
+                    final HttpRequest data,
+                    final HttpAsyncExchange httpExchange,
                     final HttpContext context)
                     throws HttpException, IOException {
                 httpExchange.submitResponse(responseProducer);
             }
-            
+
         });
-        HttpAsyncService serviceHandler = new HttpAsyncService(
-                this.serverHttpProc,
-                new DefaultConnectionReuseStrategy(),
-                new DefaultHttpResponseFactory(),
-                registry,
-                null,
-                this.serverParams);
-        this.server.start(serviceHandler);
-
-        ListenerEndpoint endpoint = this.server.getListenerEndpoint();
+        this.server.start(registry);
+
+        final ListenerEndpoint endpoint = this.server.getListenerEndpoint();
         endpoint.waitFor();
 
         Assert.assertEquals("Test server status", IOReactorStatus.ACTIVE, this.server.getStatus());
-        InetSocketAddress address = (InetSocketAddress) endpoint.getAddress();
-        Socket socket = new Socket("localhost", address.getPort());
+        final InetSocketAddress address = (InetSocketAddress) endpoint.getAddress();
+        final Socket socket = new Socket("localhost", address.getPort());
         try {
-            OutputStream outstream = socket.getOutputStream();
-            BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(outstream, "US-ASCII"));
+            final OutputStream outstream = socket.getOutputStream();
+            final BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(outstream, "US-ASCII"));
             writer.write("GET /long HTTP/1.1\r\n");
             writer.write("Host: localhost\r\n");
             writer.write("\r\n");
             writer.flush();
-            
+
             Thread.sleep(250);
-            
+
             writer.close();
         } finally {
             socket.close();
@@ -180,17 +167,17 @@ public class TestHttpAsyncHandlerCancellable extends HttpCoreNIOTestBase {
 
     @Test
     public void testRequestCancelled() throws Exception {
-        
+
         final CountDownLatch latch = new CountDownLatch(1);
         final Cancellable cancellable = new Cancellable() {
-            
+
             public boolean cancel() {
                 latch.countDown();
                 return true;
             }
         };
-        
-        HttpAsyncRequestHandlerRegistry registry = new HttpAsyncRequestHandlerRegistry();
+
+        final UriHttpAsyncRequestHandlerMapper registry = new UriHttpAsyncRequestHandlerMapper();
         registry.register("*", new HttpAsyncRequestHandler<HttpRequest>() {
 
             public HttpAsyncRequestConsumer<HttpRequest> processRequest(
@@ -200,40 +187,33 @@ public class TestHttpAsyncHandlerCancellable extends HttpCoreNIOTestBase {
             }
 
             public void handle(
-                    final HttpRequest data, 
-                    final HttpAsyncExchange httpExchange, 
+                    final HttpRequest data,
+                    final HttpAsyncExchange httpExchange,
                     final HttpContext context)
                     throws HttpException, IOException {
                 httpExchange.setCallback(cancellable);
                 // do not submit a response;
             }
-            
+
         });
-        HttpAsyncService serviceHandler = new HttpAsyncService(
-                this.serverHttpProc,
-                new DefaultConnectionReuseStrategy(),
-                new DefaultHttpResponseFactory(),
-                registry,
-                null,
-                this.serverParams);
-        this.server.start(serviceHandler);
-
-        ListenerEndpoint endpoint = this.server.getListenerEndpoint();
+        this.server.start(registry);
+
+        final ListenerEndpoint endpoint = this.server.getListenerEndpoint();
         endpoint.waitFor();
 
         Assert.assertEquals("Test server status", IOReactorStatus.ACTIVE, this.server.getStatus());
-        InetSocketAddress address = (InetSocketAddress) endpoint.getAddress();
-        Socket socket = new Socket("localhost", address.getPort());
+        final InetSocketAddress address = (InetSocketAddress) endpoint.getAddress();
+        final Socket socket = new Socket("localhost", address.getPort());
         try {
-            OutputStream outstream = socket.getOutputStream();
-            BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(outstream, "US-ASCII"));
+            final OutputStream outstream = socket.getOutputStream();
+            final BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(outstream, "US-ASCII"));
             writer.write("GET /long HTTP/1.1\r\n");
             writer.write("Host: localhost\r\n");
             writer.write("\r\n");
             writer.flush();
-            
+
             Thread.sleep(250);
-            
+
             writer.close();
         } finally {
             socket.close();
diff --git a/httpcore-nio/src/test/java/org/apache/http/nio/integration/TestHttpAsyncHandlers.java b/httpcore-nio/src/test/java/org/apache/http/nio/integration/TestHttpAsyncHandlers.java
index 4c52796..114cf31 100644
--- a/httpcore-nio/src/test/java/org/apache/http/nio/integration/TestHttpAsyncHandlers.java
+++ b/httpcore-nio/src/test/java/org/apache/http/nio/integration/TestHttpAsyncHandlers.java
@@ -33,7 +33,6 @@ import java.util.Queue;
 import java.util.concurrent.ConcurrentLinkedQueue;
 import java.util.concurrent.Future;
 
-import org.apache.http.HttpCoreNIOTestBase;
 import org.apache.http.HttpException;
 import org.apache.http.HttpHost;
 import org.apache.http.HttpRequest;
@@ -41,12 +40,8 @@ import org.apache.http.HttpRequestInterceptor;
 import org.apache.http.HttpResponse;
 import org.apache.http.HttpStatus;
 import org.apache.http.HttpVersion;
-import org.apache.http.LoggingClientConnectionFactory;
-import org.apache.http.LoggingServerConnectionFactory;
 import org.apache.http.ProtocolVersion;
 import org.apache.http.entity.ContentType;
-import org.apache.http.impl.DefaultConnectionReuseStrategy;
-import org.apache.http.impl.DefaultHttpResponseFactory;
 import org.apache.http.impl.nio.DefaultNHttpClientConnection;
 import org.apache.http.impl.nio.DefaultNHttpServerConnection;
 import org.apache.http.message.BasicHttpEntityEnclosingRequest;
@@ -56,24 +51,22 @@ import org.apache.http.nio.NHttpConnectionFactory;
 import org.apache.http.nio.entity.NStringEntity;
 import org.apache.http.nio.protocol.BasicAsyncRequestConsumer;
 import org.apache.http.nio.protocol.BasicAsyncRequestHandler;
-import org.apache.http.nio.protocol.BasicAsyncRequestProducer;
-import org.apache.http.nio.protocol.BasicAsyncResponseConsumer;
 import org.apache.http.nio.protocol.BasicAsyncResponseProducer;
 import org.apache.http.nio.protocol.HttpAsyncExchange;
 import org.apache.http.nio.protocol.HttpAsyncExpectationVerifier;
 import org.apache.http.nio.protocol.HttpAsyncRequestConsumer;
-import org.apache.http.nio.protocol.HttpAsyncRequestExecutor;
 import org.apache.http.nio.protocol.HttpAsyncRequestHandler;
-import org.apache.http.nio.protocol.HttpAsyncRequestHandlerRegistry;
-import org.apache.http.nio.protocol.HttpAsyncRequestHandlerResolver;
-import org.apache.http.nio.protocol.HttpAsyncRequester;
-import org.apache.http.nio.protocol.HttpAsyncService;
+import org.apache.http.nio.protocol.HttpAsyncRequestHandlerMapper;
+import org.apache.http.nio.protocol.UriHttpAsyncRequestHandlerMapper;
 import org.apache.http.nio.reactor.IOReactorStatus;
 import org.apache.http.nio.reactor.ListenerEndpoint;
-import org.apache.http.params.CoreProtocolPNames;
-import org.apache.http.params.HttpParams;
+import org.apache.http.nio.testserver.HttpCoreNIOTestBase;
+import org.apache.http.nio.testserver.LoggingClientConnectionFactory;
+import org.apache.http.nio.testserver.LoggingServerConnectionFactory;
+import org.apache.http.protocol.BasicHttpContext;
 import org.apache.http.protocol.HTTP;
 import org.apache.http.protocol.HttpContext;
+import org.apache.http.protocol.HttpProcessor;
 import org.apache.http.protocol.HttpRequestHandler;
 import org.apache.http.protocol.ImmutableHttpProcessor;
 import org.apache.http.protocol.RequestConnControl;
@@ -95,55 +88,51 @@ public class TestHttpAsyncHandlers extends HttpCoreNIOTestBase {
     public void setUp() throws Exception {
         initServer();
         initClient();
-        initConnPool();
     }
 
     @After
     public void tearDown() throws Exception {
-        shutDownConnPool();
         shutDownClient();
         shutDownServer();
     }
 
     @Override
-    protected NHttpConnectionFactory<DefaultNHttpServerConnection> createServerConnectionFactory(
-            final HttpParams params) throws Exception {
-        return new LoggingServerConnectionFactory(params);
+    protected NHttpConnectionFactory<DefaultNHttpServerConnection> createServerConnectionFactory() throws Exception {
+        return new LoggingServerConnectionFactory();
     }
 
     @Override
-    protected NHttpConnectionFactory<DefaultNHttpClientConnection> createClientConnectionFactory(
-            final HttpParams params) throws Exception {
-        return new LoggingClientConnectionFactory(params);
+    protected NHttpConnectionFactory<DefaultNHttpClientConnection> createClientConnectionFactory() throws Exception {
+        return new LoggingClientConnectionFactory();
     }
 
     private InetSocketAddress start(
-            final HttpAsyncRequestHandlerResolver requestHandlerResolver,
+            final HttpProcessor clientProtocolProcessor,
+            final HttpProcessor serverProtocolProcessor,
+            final HttpAsyncRequestHandlerMapper requestHandlerResolver,
             final HttpAsyncExpectationVerifier expectationVerifier) throws Exception {
-        HttpAsyncService serviceHandler = new HttpAsyncService(
-                this.serverHttpProc,
-                new DefaultConnectionReuseStrategy(),
-                new DefaultHttpResponseFactory(),
-                requestHandlerResolver,
-                expectationVerifier,
-                this.serverParams);
-        HttpAsyncRequestExecutor clientHandler = new HttpAsyncRequestExecutor();
-        this.server.start(serviceHandler);
-        this.client.start(clientHandler);
-
-        ListenerEndpoint endpoint = this.server.getListenerEndpoint();
+        this.server.start(serverProtocolProcessor, requestHandlerResolver, expectationVerifier);
+        this.client.start(clientProtocolProcessor);
+
+        final ListenerEndpoint endpoint = this.server.getListenerEndpoint();
         endpoint.waitFor();
 
         Assert.assertEquals("Test server status", IOReactorStatus.ACTIVE, this.server.getStatus());
         return (InetSocketAddress) endpoint.getAddress();
     }
 
-    private static String createRequestUri(final String pattern, int count) {
+    private InetSocketAddress start(
+            final HttpAsyncRequestHandlerMapper requestHandlerResolver,
+            final HttpAsyncExpectationVerifier expectationVerifier) throws Exception {
+        return start(null, null, requestHandlerResolver, expectationVerifier);
+    }
+
+    private static String createRequestUri(final String pattern, final int count) {
         return pattern + "x" + count;
     }
 
-    private static String createExpectedString(final String pattern, int count) {
-        StringBuilder buffer = new StringBuilder();
+    private static String createExpectedString(final String pattern, final int count) {
+        final StringBuilder buffer = new StringBuilder();
         for (int i = 0; i < count; i++) {
             buffer.append(pattern);
         }
@@ -152,32 +141,29 @@ public class TestHttpAsyncHandlers extends HttpCoreNIOTestBase {
 
     @Test
     public void testHttpGets() throws Exception {
-        HttpAsyncRequestHandlerRegistry registry = new HttpAsyncRequestHandlerRegistry();
+        final UriHttpAsyncRequestHandlerMapper registry = new UriHttpAsyncRequestHandlerMapper();
         registry.register("*", new BasicAsyncRequestHandler(new SimpleRequestHandler()));
-        InetSocketAddress address = start(registry, null);
+        final InetSocketAddress address = start(registry, null);
 
-        this.connpool.setDefaultMaxPerRoute(3);
-        this.connpool.setMaxTotal(3);
+        this.client.setMaxPerRoute(3);
+        this.client.setMaxTotal(3);
 
-        String pattern = RndTestPatternGenerator.generateText();
-        int count = RndTestPatternGenerator.generateCount(1000);
+        final String pattern = RndTestPatternGenerator.generateText();
+        final int count = RndTestPatternGenerator.generateCount(1000);
 
-        HttpHost target = new HttpHost("localhost", address.getPort());
-        String expectedPattern = createExpectedString(pattern, count);
+        final HttpHost target = new HttpHost("localhost", address.getPort());
+        final String expectedPattern = createExpectedString(pattern, count);
 
-        Queue<Future<HttpResponse>> queue = new ConcurrentLinkedQueue<Future<HttpResponse>>();
+        final Queue<Future<HttpResponse>> queue = new ConcurrentLinkedQueue<Future<HttpResponse>>();
         for (int i = 0; i < 30; i++) {
-            BasicHttpRequest request = new BasicHttpRequest("GET", createRequestUri(pattern, count));
-            Future<HttpResponse> future = this.executor.execute(
-                    new BasicAsyncRequestProducer(target, request),
-                    new BasicAsyncResponseConsumer(),
-                    this.connpool);
+            final BasicHttpRequest request = new BasicHttpRequest("GET", createRequestUri(pattern, count));
+            final Future<HttpResponse> future = this.client.execute(target, request);
             queue.add(future);
         }
 
         while (!queue.isEmpty()) {
-            Future<HttpResponse> future = queue.remove();
-            HttpResponse response = future.get();
+            final Future<HttpResponse> future = queue.remove();
+            final HttpResponse response = future.get();
             Assert.assertNotNull(response);
             Assert.assertEquals(expectedPattern, EntityUtils.toString(response.getEntity()));
         }
@@ -185,31 +171,28 @@ public class TestHttpAsyncHandlers extends HttpCoreNIOTestBase {
 
     @Test
     public void testHttpHeads() throws Exception {
-        HttpAsyncRequestHandlerRegistry registry = new HttpAsyncRequestHandlerRegistry();
+        final UriHttpAsyncRequestHandlerMapper registry = new UriHttpAsyncRequestHandlerMapper();
         registry.register("*", new BasicAsyncRequestHandler(new SimpleRequestHandler()));
-        InetSocketAddress address = start(registry, null);
+        final InetSocketAddress address = start(registry, null);
 
-        this.connpool.setDefaultMaxPerRoute(3);
-        this.connpool.setMaxTotal(3);
+        this.client.setMaxPerRoute(3);
+        this.client.setMaxTotal(3);
 
-        String pattern = RndTestPatternGenerator.generateText();
-        int count = RndTestPatternGenerator.generateCount(1000);
+        final String pattern = RndTestPatternGenerator.generateText();
+        final int count = RndTestPatternGenerator.generateCount(1000);
 
-        HttpHost target = new HttpHost("localhost", address.getPort());
+        final HttpHost target = new HttpHost("localhost", address.getPort());
 
-        Queue<Future<HttpResponse>> queue = new ConcurrentLinkedQueue<Future<HttpResponse>>();
+        final Queue<Future<HttpResponse>> queue = new ConcurrentLinkedQueue<Future<HttpResponse>>();
         for (int i = 0; i < 30; i++) {
-            BasicHttpRequest request = new BasicHttpRequest("HEAD", createRequestUri(pattern, count));
-            Future<HttpResponse> future = this.executor.execute(
-                    new BasicAsyncRequestProducer(target, request),
-                    new BasicAsyncResponseConsumer(),
-                    this.connpool);
+            final BasicHttpRequest request = new BasicHttpRequest("HEAD", createRequestUri(pattern, count));
+            final Future<HttpResponse> future = this.client.execute(target, request);
             queue.add(future);
         }
 
         while (!queue.isEmpty()) {
-            Future<HttpResponse> future = queue.remove();
-            HttpResponse response = future.get();
+            final Future<HttpResponse> future = queue.remove();
+            final HttpResponse response = future.get();
             Assert.assertNotNull(response);
             Assert.assertEquals(HttpStatus.SC_OK, response.getStatusLine().getStatusCode());
         }
@@ -217,35 +200,32 @@ public class TestHttpAsyncHandlers extends HttpCoreNIOTestBase {
 
     @Test
     public void testHttpPostsWithContentLength() throws Exception {
-        HttpAsyncRequestHandlerRegistry registry = new HttpAsyncRequestHandlerRegistry();
+        final UriHttpAsyncRequestHandlerMapper registry = new UriHttpAsyncRequestHandlerMapper();
         registry.register("*", new BasicAsyncRequestHandler(new SimpleRequestHandler()));
-        InetSocketAddress address = start(registry, null);
+        final InetSocketAddress address = start(registry, null);
 
-        this.connpool.setDefaultMaxPerRoute(3);
-        this.connpool.setMaxTotal(3);
+        this.client.setMaxPerRoute(3);
+        this.client.setMaxTotal(3);
 
-        String pattern = RndTestPatternGenerator.generateText();
-        int count = RndTestPatternGenerator.generateCount(1000);
+        final String pattern = RndTestPatternGenerator.generateText();
+        final int count = RndTestPatternGenerator.generateCount(1000);
 
-        HttpHost target = new HttpHost("localhost", address.getPort());
-        String expectedPattern = createExpectedString(pattern, count);
+        final HttpHost target = new HttpHost("localhost", address.getPort());
+        final String expectedPattern = createExpectedString(pattern, count);
 
-        Queue<Future<HttpResponse>> queue = new ConcurrentLinkedQueue<Future<HttpResponse>>();
+        final Queue<Future<HttpResponse>> queue = new ConcurrentLinkedQueue<Future<HttpResponse>>();
         for (int i = 0; i < 30; i++) {
-            BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest(
+            final BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest(
                     "POST", createRequestUri(pattern, count));
-            NStringEntity entity = new NStringEntity(expectedPattern, ContentType.DEFAULT_TEXT);
+            final NStringEntity entity = new NStringEntity(expectedPattern, ContentType.DEFAULT_TEXT);
             request.setEntity(entity);
-            Future<HttpResponse> future = this.executor.execute(
-                    new BasicAsyncRequestProducer(target, request),
-                    new BasicAsyncResponseConsumer(),
-                    this.connpool);
+            final Future<HttpResponse> future = this.client.execute(target, request);
             queue.add(future);
         }
 
         while (!queue.isEmpty()) {
-            Future<HttpResponse> future = queue.remove();
-            HttpResponse response = future.get();
+            final Future<HttpResponse> future = queue.remove();
+            final HttpResponse response = future.get();
             Assert.assertNotNull(response);
             Assert.assertEquals(expectedPattern, EntityUtils.toString(response.getEntity()));
         }
@@ -253,36 +233,33 @@ public class TestHttpAsyncHandlers extends HttpCoreNIOTestBase {
 
     @Test
     public void testHttpPostsChunked() throws Exception {
-        HttpAsyncRequestHandlerRegistry registry = new HttpAsyncRequestHandlerRegistry();
+        final UriHttpAsyncRequestHandlerMapper registry = new UriHttpAsyncRequestHandlerMapper();
         registry.register("*", new BasicAsyncRequestHandler(new SimpleRequestHandler()));
-        InetSocketAddress address = start(registry, null);
+        final InetSocketAddress address = start(registry, null);
 
-        this.connpool.setDefaultMaxPerRoute(3);
-        this.connpool.setMaxTotal(3);
+        this.client.setMaxPerRoute(3);
+        this.client.setMaxTotal(3);
 
-        String pattern = RndTestPatternGenerator.generateText();
-        int count = RndTestPatternGenerator.generateCount(1000);
+        final String pattern = RndTestPatternGenerator.generateText();
+        final int count = RndTestPatternGenerator.generateCount(1000);
 
-        HttpHost target = new HttpHost("localhost", address.getPort());
-        String expectedPattern = createExpectedString(pattern, count);
+        final HttpHost target = new HttpHost("localhost", address.getPort());
+        final String expectedPattern = createExpectedString(pattern, count);
 
-        Queue<Future<HttpResponse>> queue = new ConcurrentLinkedQueue<Future<HttpResponse>>();
+        final Queue<Future<HttpResponse>> queue = new ConcurrentLinkedQueue<Future<HttpResponse>>();
         for (int i = 0; i < 30; i++) {
-            BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest(
+            final BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest(
                     "POST", createRequestUri(pattern, count));
-            NStringEntity entity = new NStringEntity(expectedPattern, ContentType.DEFAULT_TEXT);
+            final NStringEntity entity = new NStringEntity(expectedPattern, ContentType.DEFAULT_TEXT);
             entity.setChunked(true);
             request.setEntity(entity);
-            Future<HttpResponse> future = this.executor.execute(
-                    new BasicAsyncRequestProducer(target, request),
-                    new BasicAsyncResponseConsumer(),
-                    this.connpool);
+            final Future<HttpResponse> future = this.client.execute(target, request);
             queue.add(future);
         }
 
         while (!queue.isEmpty()) {
-            Future<HttpResponse> future = queue.remove();
-            HttpResponse response = future.get();
+            final Future<HttpResponse> future = queue.remove();
+            final HttpResponse response = future.get();
             Assert.assertNotNull(response);
             Assert.assertEquals(expectedPattern, EntityUtils.toString(response.getEntity()));
         }
@@ -290,35 +267,32 @@ public class TestHttpAsyncHandlers extends HttpCoreNIOTestBase {
 
     @Test
     public void testHttpPostsHTTP10() throws Exception {
-        HttpAsyncRequestHandlerRegistry registry = new HttpAsyncRequestHandlerRegistry();
+        final UriHttpAsyncRequestHandlerMapper registry = new UriHttpAsyncRequestHandlerMapper();
         registry.register("*", new BasicAsyncRequestHandler(new SimpleRequestHandler()));
-        InetSocketAddress address = start(registry, null);
+        final InetSocketAddress address = start(registry, null);
 
-        this.connpool.setDefaultMaxPerRoute(3);
-        this.connpool.setMaxTotal(3);
+        this.client.setMaxPerRoute(3);
+        this.client.setMaxTotal(3);
 
-        String pattern = RndTestPatternGenerator.generateText();
-        int count = RndTestPatternGenerator.generateCount(1000);
+        final String pattern = RndTestPatternGenerator.generateText();
+        final int count = RndTestPatternGenerator.generateCount(1000);
 
-        HttpHost target = new HttpHost("localhost", address.getPort());
-        String expectedPattern = createExpectedString(pattern, count);
+        final HttpHost target = new HttpHost("localhost", address.getPort());
+        final String expectedPattern = createExpectedString(pattern, count);
 
-        Queue<Future<HttpResponse>> queue = new ConcurrentLinkedQueue<Future<HttpResponse>>();
+        final Queue<Future<HttpResponse>> queue = new ConcurrentLinkedQueue<Future<HttpResponse>>();
         for (int i = 0; i < 30; i++) {
-            BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest(
+            final BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest(
                     "POST", createRequestUri(pattern, count), HttpVersion.HTTP_1_0);
-            NStringEntity entity = new NStringEntity(expectedPattern, ContentType.DEFAULT_TEXT);
+            final NStringEntity entity = new NStringEntity(expectedPattern, ContentType.DEFAULT_TEXT);
             request.setEntity(entity);
-            Future<HttpResponse> future = this.executor.execute(
-                    new BasicAsyncRequestProducer(target, request),
-                    new BasicAsyncResponseConsumer(),
-                    this.connpool);
+            final Future<HttpResponse> future = this.client.execute(target, request);
             queue.add(future);
         }
 
         while (!queue.isEmpty()) {
-            Future<HttpResponse> future = queue.remove();
-            HttpResponse response = future.get();
+            final Future<HttpResponse> future = queue.remove();
+            final HttpResponse response = future.get();
             Assert.assertNotNull(response);
             Assert.assertEquals(expectedPattern, EntityUtils.toString(response.getEntity()));
         }
@@ -326,33 +300,30 @@ public class TestHttpAsyncHandlers extends HttpCoreNIOTestBase {
 
     @Test
     public void testHttpPostsNoEntity() throws Exception {
-        HttpAsyncRequestHandlerRegistry registry = new HttpAsyncRequestHandlerRegistry();
+        final UriHttpAsyncRequestHandlerMapper registry = new UriHttpAsyncRequestHandlerMapper();
         registry.register("*", new BasicAsyncRequestHandler(new SimpleRequestHandler()));
-        InetSocketAddress address = start(registry, null);
+        final InetSocketAddress address = start(registry, null);
 
-        this.connpool.setDefaultMaxPerRoute(3);
-        this.connpool.setMaxTotal(3);
+        this.client.setMaxPerRoute(3);
+        this.client.setMaxTotal(3);
 
-        String pattern = RndTestPatternGenerator.generateText();
-        int count = RndTestPatternGenerator.generateCount(1000);
+        final String pattern = RndTestPatternGenerator.generateText();
+        final int count = RndTestPatternGenerator.generateCount(1000);
 
-        HttpHost target = new HttpHost("localhost", address.getPort());
+        final HttpHost target = new HttpHost("localhost", address.getPort());
 
-        Queue<Future<HttpResponse>> queue = new ConcurrentLinkedQueue<Future<HttpResponse>>();
+        final Queue<Future<HttpResponse>> queue = new ConcurrentLinkedQueue<Future<HttpResponse>>();
         for (int i = 0; i < 30; i++) {
-            BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest(
+            final BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest(
                     "POST", createRequestUri(pattern, count));
             request.setEntity(null);
-            Future<HttpResponse> future = this.executor.execute(
-                    new BasicAsyncRequestProducer(target, request),
-                    new BasicAsyncResponseConsumer(),
-                    this.connpool);
+            final Future<HttpResponse> future = this.client.execute(target, request);
             queue.add(future);
         }
 
         while (!queue.isEmpty()) {
-            Future<HttpResponse> future = queue.remove();
-            HttpResponse response = future.get();
+            final Future<HttpResponse> future = queue.remove();
+            final HttpResponse response = future.get();
             Assert.assertNotNull(response);
             Assert.assertEquals(HttpStatus.SC_OK, response.getStatusLine().getStatusCode());
         }
@@ -360,54 +331,46 @@ public class TestHttpAsyncHandlers extends HttpCoreNIOTestBase {
 
     @Test
     public void testHttpPostNoContentLength() throws Exception {
-        HttpAsyncRequestHandlerRegistry registry = new HttpAsyncRequestHandlerRegistry();
+        final UriHttpAsyncRequestHandlerMapper registry = new UriHttpAsyncRequestHandlerMapper();
         registry.register("*", new BasicAsyncRequestHandler(new SimpleRequestHandler()));
-        
-        this.clientHttpProc = new ImmutableHttpProcessor(new HttpRequestInterceptor[] {
+
+        final HttpProcessor clientHttpProc = new ImmutableHttpProcessor(new HttpRequestInterceptor[] {
                 new RequestTargetHost(),
                 new RequestConnControl(),
                 new RequestUserAgent(),
-                new RequestExpectContinue()});
-        
-        this.executor = new HttpAsyncRequester(
-                this.clientHttpProc,
-                new DefaultConnectionReuseStrategy(),
-                this.clientParams);
-        
-        InetSocketAddress address = start(registry, null);
+                new RequestExpectContinue(true)});
+
+        final InetSocketAddress address = start(clientHttpProc, null, registry, null);
 
-        this.connpool.setDefaultMaxPerRoute(3);
-        this.connpool.setMaxTotal(3);
+        this.client.setMaxPerRoute(3);
+        this.client.setMaxTotal(3);
 
-        String pattern = RndTestPatternGenerator.generateText();
-        int count = RndTestPatternGenerator.generateCount(1000);
+        final String pattern = RndTestPatternGenerator.generateText();
+        final int count = RndTestPatternGenerator.generateCount(1000);
 
-        HttpHost target = new HttpHost("localhost", address.getPort());
+        final HttpHost target = new HttpHost("localhost", address.getPort());
 
-        BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest(
+        final BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest(
                 "POST", createRequestUri(pattern, count));
         request.setEntity(null);
 
-        Future<HttpResponse> future = this.executor.execute(
-                new BasicAsyncRequestProducer(target, request),
-                new BasicAsyncResponseConsumer(),
-                this.connpool);
+        final Future<HttpResponse> future = this.client.execute(target, request);
 
-        HttpResponse response = future.get();
+        final HttpResponse response = future.get();
         Assert.assertNotNull(response);
         Assert.assertEquals(HttpStatus.SC_OK, response.getStatusLine().getStatusCode());
     }
 
     @Test
     public void testHttpPostIdentity() throws Exception {
-        HttpAsyncRequestHandlerRegistry registry = new HttpAsyncRequestHandlerRegistry();
+        final UriHttpAsyncRequestHandlerMapper registry = new UriHttpAsyncRequestHandlerMapper();
         registry.register("*", new BasicAsyncRequestHandler(new SimpleRequestHandler()));
-        
-        this.clientHttpProc = new ImmutableHttpProcessor(new HttpRequestInterceptor[] {
+
+        final HttpProcessor clientHttpProc = new ImmutableHttpProcessor(new HttpRequestInterceptor[] {
                 new HttpRequestInterceptor() {
-                    
+
                     public void process(
-                            final HttpRequest request, 
+                            final HttpRequest request,
                             final HttpContext context) throws HttpException, IOException {
                         request.addHeader(HTTP.TRANSFER_ENCODING, "identity");
                     }
@@ -416,69 +379,59 @@ public class TestHttpAsyncHandlers extends HttpCoreNIOTestBase {
                 new RequestTargetHost(),
                 new RequestConnControl(),
                 new RequestUserAgent(),
-                new RequestExpectContinue()});
-        
-        this.executor = new HttpAsyncRequester(
-                this.clientHttpProc,
-                new DefaultConnectionReuseStrategy(),
-                this.clientParams);
-        
-        InetSocketAddress address = start(registry, null);
+                new RequestExpectContinue(true)});
 
-        this.connpool.setDefaultMaxPerRoute(3);
-        this.connpool.setMaxTotal(3);
+        final InetSocketAddress address = start(clientHttpProc, null, registry, null);
 
-        String pattern = RndTestPatternGenerator.generateText();
-        int count = RndTestPatternGenerator.generateCount(1000);
+        this.client.setMaxPerRoute(3);
+        this.client.setMaxTotal(3);
 
-        HttpHost target = new HttpHost("localhost", address.getPort());
+        final String pattern = RndTestPatternGenerator.generateText();
+        final int count = RndTestPatternGenerator.generateCount(1000);
 
-        BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest(
+        final HttpHost target = new HttpHost("localhost", address.getPort());
+
+        final BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest(
                 "POST", createRequestUri(pattern, count));
         request.setEntity(null);
 
-        Future<HttpResponse> future = this.executor.execute(
-                new BasicAsyncRequestProducer(target, request),
-                new BasicAsyncResponseConsumer(),
-                this.connpool);
+        final Future<HttpResponse> future = this.client.execute(target, request);
 
-        HttpResponse response = future.get();
+        final HttpResponse response = future.get();
         Assert.assertNotNull(response);
         Assert.assertEquals(HttpStatus.SC_BAD_REQUEST, response.getStatusLine().getStatusCode());
     }
 
     @Test
     public void testHttpPostsWithExpectContinue() throws Exception {
-        HttpAsyncRequestHandlerRegistry registry = new HttpAsyncRequestHandlerRegistry();
+        final UriHttpAsyncRequestHandlerMapper registry = new UriHttpAsyncRequestHandlerMapper();
         registry.register("*", new BasicAsyncRequestHandler(new SimpleRequestHandler()));
-        InetSocketAddress address = start(registry, null);
+        final InetSocketAddress address = start(registry, null);
 
-        this.connpool.setDefaultMaxPerRoute(3);
-        this.connpool.setMaxTotal(3);
+        this.client.setMaxPerRoute(3);
+        this.client.setMaxTotal(3);
 
-        String pattern = RndTestPatternGenerator.generateText();
-        int count = RndTestPatternGenerator.generateCount(1000);
+        final String pattern = RndTestPatternGenerator.generateText();
+        final int count = RndTestPatternGenerator.generateCount(1000);
 
-        HttpHost target = new HttpHost("localhost", address.getPort());
-        String expectedPattern = createExpectedString(pattern, count);
+        final HttpHost target = new HttpHost("localhost", address.getPort());
+        final String expectedPattern = createExpectedString(pattern, count);
 
-        Queue<Future<HttpResponse>> queue = new ConcurrentLinkedQueue<Future<HttpResponse>>();
+        final Queue<Future<HttpResponse>> queue = new ConcurrentLinkedQueue<Future<HttpResponse>>();
         for (int i = 0; i < 30; i++) {
-            BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest(
+            final BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest(
                     "POST", createRequestUri(pattern, count));
-            request.getParams().setBooleanParameter(CoreProtocolPNames.USE_EXPECT_CONTINUE, true);
-            NStringEntity entity = new NStringEntity(expectedPattern, ContentType.DEFAULT_TEXT);
+            final NStringEntity entity = new NStringEntity(expectedPattern, ContentType.DEFAULT_TEXT);
             request.setEntity(entity);
-            Future<HttpResponse> future = this.executor.execute(
-                    new BasicAsyncRequestProducer(target, request),
-                    new BasicAsyncResponseConsumer(),
-                    this.connpool);
+
+            final HttpContext context = new BasicHttpContext();
+            final Future<HttpResponse> future = this.client.execute(target, request, context);
             queue.add(future);
         }
 
         while (!queue.isEmpty()) {
-            Future<HttpResponse> future = queue.remove();
-            HttpResponse response = future.get();
+            final Future<HttpResponse> future = queue.remove();
+            final HttpResponse response = future.get();
             Assert.assertNotNull(response);
             Assert.assertEquals(expectedPattern, EntityUtils.toString(response.getEntity()));
         }
@@ -486,19 +439,19 @@ public class TestHttpAsyncHandlers extends HttpCoreNIOTestBase {
 
     @Test
     public void testHttpPostsWithExpectationVerification() throws Exception {
-        HttpAsyncExpectationVerifier expectationVerifier = new HttpAsyncExpectationVerifier() {
+        final HttpAsyncExpectationVerifier expectationVerifier = new HttpAsyncExpectationVerifier() {
 
             public void verify(
                     final HttpAsyncExchange httpexchange,
                     final HttpContext context) throws HttpException {
-                HttpRequest request = httpexchange.getRequest();
+                final HttpRequest request = httpexchange.getRequest();
                 ProtocolVersion ver = request.getRequestLine().getProtocolVersion();
-                String s = request.getRequestLine().getUri();
+                final String s = request.getRequestLine().getUri();
                 if (!s.equals("AAAAAx10")) {
                     if (!ver.lessEquals(HttpVersion.HTTP_1_1)) {
                         ver = HttpVersion.HTTP_1_1;
                     }
-                    BasicHttpResponse response = new BasicHttpResponse(ver,
+                    final BasicHttpResponse response = new BasicHttpResponse(ver,
                             HttpStatus.SC_EXPECTATION_FAILED, "Expectation failed");
                     response.setEntity(new NStringEntity("Expectation failed", ContentType.TEXT_PLAIN));
                     httpexchange.submitResponse(new BasicAsyncResponseProducer(response));
@@ -509,46 +462,41 @@ public class TestHttpAsyncHandlers extends HttpCoreNIOTestBase {
 
         };
 
-        HttpAsyncRequestHandlerRegistry registry = new HttpAsyncRequestHandlerRegistry();
+        final UriHttpAsyncRequestHandlerMapper registry = new UriHttpAsyncRequestHandlerMapper();
         registry.register("*", new BasicAsyncRequestHandler(new SimpleRequestHandler()));
-        InetSocketAddress address = start(registry, expectationVerifier);
+        final InetSocketAddress address = start(registry, expectationVerifier);
 
-        BasicHttpEntityEnclosingRequest request1 = new BasicHttpEntityEnclosingRequest(
+        final BasicHttpEntityEnclosingRequest request1 = new BasicHttpEntityEnclosingRequest(
                 "POST", createRequestUri("AAAAA", 10));
-        request1.getParams().setBooleanParameter(CoreProtocolPNames.USE_EXPECT_CONTINUE, true);
         request1.setEntity(new NStringEntity(createExpectedString("AAAAA", 10)));
-        BasicHttpEntityEnclosingRequest request2 = new BasicHttpEntityEnclosingRequest(
+        final BasicHttpEntityEnclosingRequest request2 = new BasicHttpEntityEnclosingRequest(
                 "POST", createRequestUri("AAAAA", 10));
-        request2.getParams().setBooleanParameter(CoreProtocolPNames.USE_EXPECT_CONTINUE, true);
         request2.setEntity(new NStringEntity(createExpectedString("AAAAA", 10)));
-        BasicHttpEntityEnclosingRequest request3 = new BasicHttpEntityEnclosingRequest(
+        final BasicHttpEntityEnclosingRequest request3 = new BasicHttpEntityEnclosingRequest(
                 "POST", createRequestUri("BBBBB", 10));
-        request3.getParams().setBooleanParameter(CoreProtocolPNames.USE_EXPECT_CONTINUE, true);
         request3.setEntity(new NStringEntity(createExpectedString("BBBBB", 10)));
 
-        HttpRequest[] requests = new HttpRequest[] { request1, request2, request3 };
+        final HttpRequest[] requests = new HttpRequest[] { request1, request2, request3 };
 
-        HttpHost target = new HttpHost("localhost", address.getPort());
+        final HttpHost target = new HttpHost("localhost", address.getPort());
 
-        Queue<Future<HttpResponse>> queue = new ConcurrentLinkedQueue<Future<HttpResponse>>();
-        for (int i = 0; i < requests.length; i++) {
-            Future<HttpResponse> future = this.executor.execute(
-                    new BasicAsyncRequestProducer(target, requests[i]),
-                    new BasicAsyncResponseConsumer(),
-                    this.connpool);
+        final Queue<Future<HttpResponse>> queue = new ConcurrentLinkedQueue<Future<HttpResponse>>();
+        for (final HttpRequest request : requests) {
+            final HttpContext context = new BasicHttpContext();
+            final Future<HttpResponse> future = this.client.execute(target, request, context);
             queue.add(future);
         }
 
-        Future<HttpResponse> future1 = queue.remove();
-        HttpResponse response1 = future1.get();
+        final Future<HttpResponse> future1 = queue.remove();
+        final HttpResponse response1 = future1.get();
         Assert.assertEquals(HttpStatus.SC_OK, response1.getStatusLine().getStatusCode());
 
-        Future<HttpResponse> future2 = queue.remove();
-        HttpResponse response2 = future2.get();
+        final Future<HttpResponse> future2 = queue.remove();
+        final HttpResponse response2 = future2.get();
         Assert.assertEquals(HttpStatus.SC_OK, response2.getStatusLine().getStatusCode());
 
-        Future<HttpResponse> future3 = queue.remove();
-        HttpResponse response3 = future3.get();
+        final Future<HttpResponse> future3 = queue.remove();
+        final HttpResponse response3 = future3.get();
         Assert.assertEquals(HttpStatus.SC_EXPECTATION_FAILED, response3.getStatusLine().getStatusCode());
     }
 
@@ -583,11 +531,11 @@ public class TestHttpAsyncHandlers extends HttpCoreNIOTestBase {
                     @Override
                     public void run() {
                         // Wait a bit, to make sure this is delayed.
-                        try { Thread.sleep(100); } catch(InterruptedException ie) {}
+                        try { Thread.sleep(100); } catch(final InterruptedException ie) {}
                         // Set the entity after delaying...
                         try {
                             requestHandler.handle(request, response, context);
-                        } catch (Exception ex) {
+                        } catch (final Exception ex) {
                             response.setStatusCode(HttpStatus.SC_INTERNAL_SERVER_ERROR);
                         }
                         httpexchange.submitResponse(new BasicAsyncResponseProducer(response));
@@ -597,31 +545,28 @@ public class TestHttpAsyncHandlers extends HttpCoreNIOTestBase {
 
         }
 
-        HttpAsyncRequestHandlerRegistry registry = new HttpAsyncRequestHandlerRegistry();
+        final UriHttpAsyncRequestHandlerMapper registry = new UriHttpAsyncRequestHandlerMapper();
         registry.register("*", new DelayedRequestHandler());
-        InetSocketAddress address = start(registry, null);
+        final InetSocketAddress address = start(registry, null);
 
-        this.connpool.setDefaultMaxPerRoute(3);
-        this.connpool.setMaxTotal(3);
+        this.client.setMaxPerRoute(3);
+        this.client.setMaxTotal(3);
 
-        String pattern = RndTestPatternGenerator.generateText();
-        int count = RndTestPatternGenerator.generateCount(1000);
+        final String pattern = RndTestPatternGenerator.generateText();
+        final int count = RndTestPatternGenerator.generateCount(1000);
 
-        HttpHost target = new HttpHost("localhost", address.getPort());
+        final HttpHost target = new HttpHost("localhost", address.getPort());
 
-        Queue<Future<HttpResponse>> queue = new ConcurrentLinkedQueue<Future<HttpResponse>>();
+        final Queue<Future<HttpResponse>> queue = new ConcurrentLinkedQueue<Future<HttpResponse>>();
         for (int i = 0; i < 30; i++) {
-            BasicHttpRequest request = new BasicHttpRequest("HEAD", createRequestUri(pattern, count));
-            Future<HttpResponse> future = this.executor.execute(
-                    new BasicAsyncRequestProducer(target, request),
-                    new BasicAsyncResponseConsumer(),
-                    this.connpool);
+            final BasicHttpRequest request = new BasicHttpRequest("HEAD", createRequestUri(pattern, count));
+            final Future<HttpResponse> future = this.client.execute(target, request);
             queue.add(future);
         }
 
         while (!queue.isEmpty()) {
-            Future<HttpResponse> future = queue.remove();
-            HttpResponse response = future.get();
+            final Future<HttpResponse> future = queue.remove();
+            final HttpResponse response = future.get();
             Assert.assertNotNull(response);
             Assert.assertEquals(HttpStatus.SC_OK, response.getStatusLine().getStatusCode());
         }
@@ -629,7 +574,7 @@ public class TestHttpAsyncHandlers extends HttpCoreNIOTestBase {
 
     @Test
     public void testHttpPostsWithExpectationVerificationDelayedResponse() throws Exception {
-        HttpAsyncExpectationVerifier expectationVerifier = new HttpAsyncExpectationVerifier() {
+        final HttpAsyncExpectationVerifier expectationVerifier = new HttpAsyncExpectationVerifier() {
 
             public void verify(
                     final HttpAsyncExchange httpexchange,
@@ -638,16 +583,16 @@ public class TestHttpAsyncHandlers extends HttpCoreNIOTestBase {
                     @Override
                     public void run() {
                         // Wait a bit, to make sure this is delayed.
-                        try { Thread.sleep(100); } catch(InterruptedException ie) {}
+                        try { Thread.sleep(100); } catch(final InterruptedException ie) {}
                         // Set the entity after delaying...
-                        HttpRequest request = httpexchange.getRequest();
+                        final HttpRequest request = httpexchange.getRequest();
                         ProtocolVersion ver = request.getRequestLine().getProtocolVersion();
-                        String s = request.getRequestLine().getUri();
+                        final String s = request.getRequestLine().getUri();
                         if (!s.equals("AAAAAx10")) {
                             if (!ver.lessEquals(HttpVersion.HTTP_1_1)) {
                                 ver = HttpVersion.HTTP_1_1;
                             }
-                            BasicHttpResponse response = new BasicHttpResponse(ver,
+                            final BasicHttpResponse response = new BasicHttpResponse(ver,
                                     HttpStatus.SC_EXPECTATION_FAILED, "Expectation failed");
                             response.setEntity(new NStringEntity("Expectation failed", ContentType.TEXT_PLAIN));
                             httpexchange.submitResponse(new BasicAsyncResponseProducer(response));
@@ -660,46 +605,41 @@ public class TestHttpAsyncHandlers extends HttpCoreNIOTestBase {
 
         };
 
-        HttpAsyncRequestHandlerRegistry registry = new HttpAsyncRequestHandlerRegistry();
+        final UriHttpAsyncRequestHandlerMapper registry = new UriHttpAsyncRequestHandlerMapper();
         registry.register("*", new BasicAsyncRequestHandler(new SimpleRequestHandler()));
-        InetSocketAddress address = start(registry, expectationVerifier);
+        final InetSocketAddress address = start(registry, expectationVerifier);
 
-        BasicHttpEntityEnclosingRequest request1 = new BasicHttpEntityEnclosingRequest(
+        final BasicHttpEntityEnclosingRequest request1 = new BasicHttpEntityEnclosingRequest(
                 "POST", createRequestUri("AAAAA", 10));
-        request1.getParams().setBooleanParameter(CoreProtocolPNames.USE_EXPECT_CONTINUE, true);
         request1.setEntity(new NStringEntity(createExpectedString("AAAAA", 10)));
-        BasicHttpEntityEnclosingRequest request2 = new BasicHttpEntityEnclosingRequest(
+        final BasicHttpEntityEnclosingRequest request2 = new BasicHttpEntityEnclosingRequest(
                 "POST", createRequestUri("AAAAA", 10));
-        request2.getParams().setBooleanParameter(CoreProtocolPNames.USE_EXPECT_CONTINUE, true);
         request2.setEntity(new NStringEntity(createExpectedString("AAAAA", 10)));
-        BasicHttpEntityEnclosingRequest request3 = new BasicHttpEntityEnclosingRequest(
+        final BasicHttpEntityEnclosingRequest request3 = new BasicHttpEntityEnclosingRequest(
                 "POST", createRequestUri("BBBBB", 10));
-        request3.getParams().setBooleanParameter(CoreProtocolPNames.USE_EXPECT_CONTINUE, true);
         request3.setEntity(new NStringEntity(createExpectedString("BBBBB", 10)));
 
-        HttpRequest[] requests = new HttpRequest[] { request1, request2, request3 };
+        final HttpRequest[] requests = new HttpRequest[] { request1, request2, request3 };
 
-        HttpHost target = new HttpHost("localhost", address.getPort());
+        final HttpHost target = new HttpHost("localhost", address.getPort());
 
-        Queue<Future<HttpResponse>> queue = new ConcurrentLinkedQueue<Future<HttpResponse>>();
-        for (int i = 0; i < requests.length; i++) {
-            Future<HttpResponse> future = this.executor.execute(
-                    new BasicAsyncRequestProducer(target, requests[i]),
-                    new BasicAsyncResponseConsumer(),
-                    this.connpool);
+        final Queue<Future<HttpResponse>> queue = new ConcurrentLinkedQueue<Future<HttpResponse>>();
+        for (final HttpRequest request : requests) {
+            final HttpContext context = new BasicHttpContext();
+            final Future<HttpResponse> future = this.client.execute(target, request, context);
             queue.add(future);
         }
 
-        Future<HttpResponse> future1 = queue.remove();
-        HttpResponse response1 = future1.get();
+        final Future<HttpResponse> future1 = queue.remove();
+        final HttpResponse response1 = future1.get();
         Assert.assertEquals(HttpStatus.SC_OK, response1.getStatusLine().getStatusCode());
 
-        Future<HttpResponse> future2 = queue.remove();
-        HttpResponse response2 = future2.get();
+        final Future<HttpResponse> future2 = queue.remove();
+        final HttpResponse response2 = future2.get();
         Assert.assertEquals(HttpStatus.SC_OK, response2.getStatusLine().getStatusCode());
 
-        Future<HttpResponse> future3 = queue.remove();
-        HttpResponse response3 = future3.get();
+        final Future<HttpResponse> future3 = queue.remove();
+        final HttpResponse response3 = future3.get();
         Assert.assertEquals(HttpStatus.SC_EXPECTATION_FAILED, response3.getStatusLine().getStatusCode());
     }
 
@@ -727,31 +667,28 @@ public class TestHttpAsyncHandlers extends HttpCoreNIOTestBase {
 
         }
 
-        HttpAsyncRequestHandlerRegistry registry = new HttpAsyncRequestHandlerRegistry();
+        final UriHttpAsyncRequestHandlerMapper registry = new UriHttpAsyncRequestHandlerMapper();
         registry.register("*", new FailingRequestHandler());
-        InetSocketAddress address = start(registry, null);
+        final InetSocketAddress address = start(registry, null);
 
-        this.connpool.setDefaultMaxPerRoute(3);
-        this.connpool.setMaxTotal(3);
+        this.client.setMaxPerRoute(3);
+        this.client.setMaxTotal(3);
 
-        String pattern = RndTestPatternGenerator.generateText();
-        int count = RndTestPatternGenerator.generateCount(1000);
+        final String pattern = RndTestPatternGenerator.generateText();
+        final int count = RndTestPatternGenerator.generateCount(1000);
 
-        HttpHost target = new HttpHost("localhost", address.getPort());
+        final HttpHost target = new HttpHost("localhost", address.getPort());
 
-        Queue<Future<HttpResponse>> queue = new ConcurrentLinkedQueue<Future<HttpResponse>>();
+        final Queue<Future<HttpResponse>> queue = new ConcurrentLinkedQueue<Future<HttpResponse>>();
         for (int i = 0; i < 1; i++) {
-            BasicHttpRequest request = new BasicHttpRequest("GET", createRequestUri(pattern, count));
-            Future<HttpResponse> future = this.executor.execute(
-                    new BasicAsyncRequestProducer(target, request),
-                    new BasicAsyncResponseConsumer(),
-                    this.connpool);
+            final BasicHttpRequest request = new BasicHttpRequest("GET", createRequestUri(pattern, count));
+            final Future<HttpResponse> future = this.client.execute(target, request);
             queue.add(future);
         }
 
         while (!queue.isEmpty()) {
-            Future<HttpResponse> future = queue.remove();
-            HttpResponse response = future.get();
+            final Future<HttpResponse> future = queue.remove();
+            final HttpResponse response = future.get();
             Assert.assertNotNull(response);
             Assert.assertEquals(HttpStatus.SC_INTERNAL_SERVER_ERROR, response.getStatusLine().getStatusCode());
         }
@@ -759,30 +696,27 @@ public class TestHttpAsyncHandlers extends HttpCoreNIOTestBase {
 
     @Test
     public void testNoServiceHandler() throws Exception {
-        HttpAsyncRequestHandlerRegistry registry = new HttpAsyncRequestHandlerRegistry();
-        InetSocketAddress address = start(registry, null);
+        final UriHttpAsyncRequestHandlerMapper registry = new UriHttpAsyncRequestHandlerMapper();
+        final InetSocketAddress address = start(registry, null);
 
-        this.connpool.setDefaultMaxPerRoute(3);
-        this.connpool.setMaxTotal(3);
+        this.client.setMaxPerRoute(3);
+        this.client.setMaxTotal(3);
 
-        String pattern = RndTestPatternGenerator.generateText();
-        int count = RndTestPatternGenerator.generateCount(1000);
+        final String pattern = RndTestPatternGenerator.generateText();
+        final int count = RndTestPatternGenerator.generateCount(1000);
 
-        HttpHost target = new HttpHost("localhost", address.getPort());
+        final HttpHost target = new HttpHost("localhost", address.getPort());
 
-        Queue<Future<HttpResponse>> queue = new ConcurrentLinkedQueue<Future<HttpResponse>>();
+        final Queue<Future<HttpResponse>> queue = new ConcurrentLinkedQueue<Future<HttpResponse>>();
         for (int i = 0; i < 30; i++) {
-            BasicHttpRequest request = new BasicHttpRequest("GET", createRequestUri(pattern, count));
-            Future<HttpResponse> future = this.executor.execute(
-                    new BasicAsyncRequestProducer(target, request),
-                    new BasicAsyncResponseConsumer(),
-                    this.connpool);
+            final BasicHttpRequest request = new BasicHttpRequest("GET", createRequestUri(pattern, count));
+            final Future<HttpResponse> future = this.client.execute(target, request);
             queue.add(future);
         }
 
         while (!queue.isEmpty()) {
-            Future<HttpResponse> future = queue.remove();
-            HttpResponse response = future.get();
+            final Future<HttpResponse> future = queue.remove();
+            final HttpResponse response = future.get();
             Assert.assertNotNull(response);
             Assert.assertEquals(HttpStatus.SC_NOT_IMPLEMENTED, response.getStatusLine().getStatusCode());
         }
@@ -790,37 +724,34 @@ public class TestHttpAsyncHandlers extends HttpCoreNIOTestBase {
 
     @Test
     public void testResponseNoContent() throws Exception {
-        HttpAsyncRequestHandlerRegistry registry = new HttpAsyncRequestHandlerRegistry();
+        final UriHttpAsyncRequestHandlerMapper registry = new UriHttpAsyncRequestHandlerMapper();
         registry.register("*", new BasicAsyncRequestHandler(new HttpRequestHandler() {
-            
+
             public void handle(
-                    final HttpRequest request, 
-                    final HttpResponse response, 
+                    final HttpRequest request,
+                    final HttpResponse response,
                     final HttpContext context) throws HttpException, IOException {
                 response.setStatusCode(HttpStatus.SC_NO_CONTENT);
             }
-        
+
         }));
-        InetSocketAddress address = start(registry, null);
+        final InetSocketAddress address = start(registry, null);
 
-        this.connpool.setDefaultMaxPerRoute(3);
-        this.connpool.setMaxTotal(3);
+        this.client.setMaxPerRoute(3);
+        this.client.setMaxTotal(3);
 
-        HttpHost target = new HttpHost("localhost", address.getPort());
+        final HttpHost target = new HttpHost("localhost", address.getPort());
 
-        Queue<Future<HttpResponse>> queue = new ConcurrentLinkedQueue<Future<HttpResponse>>();
+        final Queue<Future<HttpResponse>> queue = new ConcurrentLinkedQueue<Future<HttpResponse>>();
         for (int i = 0; i < 30; i++) {
-            BasicHttpRequest request = new BasicHttpRequest("GET", "/");
-            Future<HttpResponse> future = this.executor.execute(
-                    new BasicAsyncRequestProducer(target, request),
-                    new BasicAsyncResponseConsumer(),
-                    this.connpool);
+            final BasicHttpRequest request = new BasicHttpRequest("GET", "/");
+            final Future<HttpResponse> future = this.client.execute(target, request);
             queue.add(future);
         }
 
         while (!queue.isEmpty()) {
-            Future<HttpResponse> future = queue.remove();
-            HttpResponse response = future.get();
+            final Future<HttpResponse> future = queue.remove();
+            final HttpResponse response = future.get();
             Assert.assertNotNull(response);
             Assert.assertNull(response.getEntity());
         }
diff --git a/httpcore-nio/src/test/java/org/apache/http/nio/integration/TestHttpAsyncPrematureTermination.java b/httpcore-nio/src/test/java/org/apache/http/nio/integration/TestHttpAsyncPrematureTermination.java
index 2865bde..2caf7f1 100644
--- a/httpcore-nio/src/test/java/org/apache/http/nio/integration/TestHttpAsyncPrematureTermination.java
+++ b/httpcore-nio/src/test/java/org/apache/http/nio/integration/TestHttpAsyncPrematureTermination.java
@@ -26,23 +26,22 @@
  */
 package org.apache.http.nio.integration;
 
+import java.io.ByteArrayInputStream;
 import java.io.IOException;
+import java.io.InputStream;
 import java.net.InetSocketAddress;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
 
+import org.apache.http.Consts;
 import org.apache.http.HttpConnection;
-import org.apache.http.HttpCoreNIOTestBase;
 import org.apache.http.HttpException;
 import org.apache.http.HttpHost;
 import org.apache.http.HttpRequest;
 import org.apache.http.HttpResponse;
-import org.apache.http.LoggingClientConnectionFactory;
-import org.apache.http.LoggingServerConnectionFactory;
 import org.apache.http.concurrent.FutureCallback;
 import org.apache.http.entity.ContentType;
-import org.apache.http.impl.DefaultConnectionReuseStrategy;
-import org.apache.http.impl.DefaultHttpResponseFactory;
+import org.apache.http.entity.InputStreamEntity;
 import org.apache.http.impl.nio.DefaultNHttpClientConnection;
 import org.apache.http.impl.nio.DefaultNHttpServerConnection;
 import org.apache.http.message.BasicHttpRequest;
@@ -51,23 +50,21 @@ import org.apache.http.nio.IOControl;
 import org.apache.http.nio.NHttpConnectionFactory;
 import org.apache.http.nio.entity.NStringEntity;
 import org.apache.http.nio.protocol.BasicAsyncRequestConsumer;
-import org.apache.http.nio.protocol.BasicAsyncRequestProducer;
-import org.apache.http.nio.protocol.BasicAsyncResponseConsumer;
 import org.apache.http.nio.protocol.BasicAsyncResponseProducer;
 import org.apache.http.nio.protocol.HttpAsyncExchange;
 import org.apache.http.nio.protocol.HttpAsyncExpectationVerifier;
 import org.apache.http.nio.protocol.HttpAsyncRequestConsumer;
-import org.apache.http.nio.protocol.HttpAsyncRequestExecutor;
 import org.apache.http.nio.protocol.HttpAsyncRequestHandler;
-import org.apache.http.nio.protocol.HttpAsyncRequestHandlerRegistry;
-import org.apache.http.nio.protocol.HttpAsyncRequestHandlerResolver;
-import org.apache.http.nio.protocol.HttpAsyncService;
+import org.apache.http.nio.protocol.HttpAsyncRequestHandlerMapper;
+import org.apache.http.nio.protocol.UriHttpAsyncRequestHandlerMapper;
 import org.apache.http.nio.reactor.IOReactorStatus;
 import org.apache.http.nio.reactor.ListenerEndpoint;
-import org.apache.http.params.HttpParams;
+import org.apache.http.nio.testserver.HttpCoreNIOTestBase;
+import org.apache.http.nio.testserver.LoggingClientConnectionFactory;
+import org.apache.http.nio.testserver.LoggingServerConnectionFactory;
 import org.apache.http.protocol.BasicHttpContext;
-import org.apache.http.protocol.ExecutionContext;
 import org.apache.http.protocol.HttpContext;
+import org.apache.http.protocol.HttpCoreContext;
 import org.junit.After;
 import org.junit.Assert;
 import org.junit.Before;
@@ -79,7 +76,6 @@ public class TestHttpAsyncPrematureTermination extends HttpCoreNIOTestBase {
     public void setUp() throws Exception {
         initServer();
         initClient();
-        initConnPool();
     }
 
     @After
@@ -89,32 +85,22 @@ public class TestHttpAsyncPrematureTermination extends HttpCoreNIOTestBase {
     }
 
     @Override
-    protected NHttpConnectionFactory<DefaultNHttpServerConnection> createServerConnectionFactory(
-            final HttpParams params) throws Exception {
-        return new LoggingServerConnectionFactory(params);
+    protected NHttpConnectionFactory<DefaultNHttpServerConnection> createServerConnectionFactory() throws Exception {
+        return new LoggingServerConnectionFactory();
     }
 
     @Override
-    protected NHttpConnectionFactory<DefaultNHttpClientConnection> createClientConnectionFactory(
-            final HttpParams params) throws Exception {
-        return new LoggingClientConnectionFactory(params);
+    protected NHttpConnectionFactory<DefaultNHttpClientConnection> createClientConnectionFactory() throws Exception {
+        return new LoggingClientConnectionFactory();
     }
 
     private InetSocketAddress start(
-            final HttpAsyncRequestHandlerResolver requestHandlerResolver,
+            final HttpAsyncRequestHandlerMapper requestHandlerResolver,
             final HttpAsyncExpectationVerifier expectationVerifier) throws Exception {
-        HttpAsyncService serviceHandler = new HttpAsyncService(
-                this.serverHttpProc,
-                new DefaultConnectionReuseStrategy(),
-                new DefaultHttpResponseFactory(),
-                requestHandlerResolver,
-                expectationVerifier,
-                this.serverParams);
-        HttpAsyncRequestExecutor clientHandler = new HttpAsyncRequestExecutor();
-        this.server.start(serviceHandler);
-        this.client.start(clientHandler);
-
-        ListenerEndpoint endpoint = this.server.getListenerEndpoint();
+        this.server.start(requestHandlerResolver, expectationVerifier);
+        this.client.start();
+
+        final ListenerEndpoint endpoint = this.server.getListenerEndpoint();
         endpoint.waitFor();
 
         Assert.assertEquals("Test server status", IOReactorStatus.ACTIVE, this.server.getStatus());
@@ -123,14 +109,14 @@ public class TestHttpAsyncPrematureTermination extends HttpCoreNIOTestBase {
 
     @Test
     public void testConnectionTerminatedProcessingRequest() throws Exception {
-        HttpAsyncRequestHandlerRegistry registry = new HttpAsyncRequestHandlerRegistry();
+        final UriHttpAsyncRequestHandlerMapper registry = new UriHttpAsyncRequestHandlerMapper();
         registry.register("*", new HttpAsyncRequestHandler<HttpRequest>() {
 
             public HttpAsyncRequestConsumer<HttpRequest> processRequest(
                     final HttpRequest request,
                     final HttpContext context) throws HttpException, IOException {
-                HttpConnection conn = (HttpConnection) context.getAttribute(
-                        ExecutionContext.HTTP_CONNECTION);
+                final HttpConnection conn = (HttpConnection) context.getAttribute(
+                        HttpCoreContext.HTTP_CONNECTION);
                 conn.shutdown();
                 return new BasicAsyncRequestConsumer();
             }
@@ -139,18 +125,18 @@ public class TestHttpAsyncPrematureTermination extends HttpCoreNIOTestBase {
                     final HttpRequest request,
                     final HttpAsyncExchange httpExchange,
                     final HttpContext context) throws HttpException, IOException {
-                HttpResponse response = httpExchange.getResponse();
+                final HttpResponse response = httpExchange.getResponse();
                 response.setEntity(new NStringEntity("all is well", ContentType.TEXT_PLAIN));
                 httpExchange.submitResponse();
             }
 
         });
-        InetSocketAddress address = start(registry, null);
-        HttpHost target = new HttpHost("localhost", address.getPort());
+        final InetSocketAddress address = start(registry, null);
+        final HttpHost target = new HttpHost("localhost", address.getPort());
 
         final CountDownLatch latch = new CountDownLatch(1);
 
-        FutureCallback<HttpResponse> callback = new FutureCallback<HttpResponse>() {
+        final FutureCallback<HttpResponse> callback = new FutureCallback<HttpResponse>() {
 
             public void cancelled() {
                 latch.countDown();
@@ -166,19 +152,25 @@ public class TestHttpAsyncPrematureTermination extends HttpCoreNIOTestBase {
 
         };
 
-        HttpRequest request = new BasicHttpRequest("GET", "/");
-        HttpContext context = new BasicHttpContext();
-        this.executor.execute(
-                new BasicAsyncRequestProducer(target, request),
-                new BasicAsyncResponseConsumer(),
-                this.connpool, context, callback);
+        final HttpRequest request = new BasicHttpRequest("GET", "/");
+        final HttpContext context = new BasicHttpContext();
+        this.client.execute(target, request, context, callback);
 
         Assert.assertTrue(latch.await(5, TimeUnit.SECONDS));
     }
 
     @Test
     public void testConnectionTerminatedHandlingRequest() throws Exception {
-        HttpAsyncRequestHandlerRegistry registry = new HttpAsyncRequestHandlerRegistry();
+        final UriHttpAsyncRequestHandlerMapper registry = new UriHttpAsyncRequestHandlerMapper();
+        final CountDownLatch responseStreamClosed = new CountDownLatch(1);
+        final InputStream testInputStream = new ByteArrayInputStream(
+                "all is well".getBytes(Consts.ASCII.name())) {
+            @Override
+            public void close() throws IOException {
+                responseStreamClosed.countDown();
+                super.close();
+            }
+        };
         registry.register("*", new HttpAsyncRequestHandler<HttpRequest>() {
 
             public HttpAsyncRequestConsumer<HttpRequest> processRequest(
@@ -191,21 +183,21 @@ public class TestHttpAsyncPrematureTermination extends HttpCoreNIOTestBase {
                     final HttpRequest request,
                     final HttpAsyncExchange httpExchange,
                     final HttpContext context) throws HttpException, IOException {
-                HttpConnection conn = (HttpConnection) context.getAttribute(
-                        ExecutionContext.HTTP_CONNECTION);
+                final HttpConnection conn = (HttpConnection) context.getAttribute(
+                        HttpCoreContext.HTTP_CONNECTION);
                 conn.shutdown();
-                HttpResponse response = httpExchange.getResponse();
-                response.setEntity(new NStringEntity("all is well", ContentType.TEXT_PLAIN));
+                final HttpResponse response = httpExchange.getResponse();
+                response.setEntity(new InputStreamEntity(testInputStream, -1));
                 httpExchange.submitResponse();
             }
 
         });
-        InetSocketAddress address = start(registry, null);
-        HttpHost target = new HttpHost("localhost", address.getPort());
+        final InetSocketAddress address = start(registry, null);
+        final HttpHost target = new HttpHost("localhost", address.getPort());
 
         final CountDownLatch latch = new CountDownLatch(1);
 
-        FutureCallback<HttpResponse> callback = new FutureCallback<HttpResponse>() {
+        final FutureCallback<HttpResponse> callback = new FutureCallback<HttpResponse>() {
 
             public void cancelled() {
                 latch.countDown();
@@ -221,19 +213,17 @@ public class TestHttpAsyncPrematureTermination extends HttpCoreNIOTestBase {
 
         };
 
-        HttpRequest request = new BasicHttpRequest("GET", "/");
-        HttpContext context = new BasicHttpContext();
-        this.executor.execute(
-                new BasicAsyncRequestProducer(target, request),
-                new BasicAsyncResponseConsumer(),
-                this.connpool, context, callback);
+        final HttpRequest request = new BasicHttpRequest("GET", "/");
+        final HttpContext context = new BasicHttpContext();
+        this.client.execute(target, request, context, callback);
 
         Assert.assertTrue(latch.await(5, TimeUnit.SECONDS));
+        Assert.assertTrue(responseStreamClosed.await(5, TimeUnit.SECONDS));
     }
 
     @Test
     public void testConnectionTerminatedSendingResponse() throws Exception {
-        HttpAsyncRequestHandlerRegistry registry = new HttpAsyncRequestHandlerRegistry();
+        final UriHttpAsyncRequestHandlerMapper registry = new UriHttpAsyncRequestHandlerMapper();
         registry.register("*", new HttpAsyncRequestHandler<HttpRequest>() {
 
             public HttpAsyncRequestConsumer<HttpRequest> processRequest(
@@ -246,7 +236,7 @@ public class TestHttpAsyncPrematureTermination extends HttpCoreNIOTestBase {
                     final HttpRequest request,
                     final HttpAsyncExchange httpExchange,
                     final HttpContext context) throws HttpException, IOException {
-                HttpResponse response = httpExchange.getResponse();
+                final HttpResponse response = httpExchange.getResponse();
                 response.setEntity(new NStringEntity("all is well", ContentType.TEXT_PLAIN));
                 httpExchange.submitResponse(new BasicAsyncResponseProducer(response) {
 
@@ -261,12 +251,12 @@ public class TestHttpAsyncPrematureTermination extends HttpCoreNIOTestBase {
             }
 
         });
-        InetSocketAddress address = start(registry, null);
-        HttpHost target = new HttpHost("localhost", address.getPort());
+        final InetSocketAddress address = start(registry, null);
+        final HttpHost target = new HttpHost("localhost", address.getPort());
 
         final CountDownLatch latch = new CountDownLatch(1);
 
-        FutureCallback<HttpResponse> callback = new FutureCallback<HttpResponse>() {
+        final FutureCallback<HttpResponse> callback = new FutureCallback<HttpResponse>() {
 
             public void cancelled() {
                 latch.countDown();
@@ -282,12 +272,9 @@ public class TestHttpAsyncPrematureTermination extends HttpCoreNIOTestBase {
 
         };
 
-        HttpRequest request = new BasicHttpRequest("GET", "/");
-        HttpContext context = new BasicHttpContext();
-        this.executor.execute(
-                new BasicAsyncRequestProducer(target, request),
-                new BasicAsyncResponseConsumer(),
-                this.connpool, context, callback);
+        final HttpRequest request = new BasicHttpRequest("GET", "/");
+        final HttpContext context = new BasicHttpContext();
+        this.client.execute(target, request, context, callback);
 
         Assert.assertTrue(latch.await(5, TimeUnit.SECONDS));
     }
diff --git a/httpcore-nio/src/test/java/org/apache/http/nio/integration/TestHttpsAsyncHandlers.java b/httpcore-nio/src/test/java/org/apache/http/nio/integration/TestHttpsAsyncHandlers.java
index 02acb56..be0c6fa 100644
--- a/httpcore-nio/src/test/java/org/apache/http/nio/integration/TestHttpsAsyncHandlers.java
+++ b/httpcore-nio/src/test/java/org/apache/http/nio/integration/TestHttpsAsyncHandlers.java
@@ -27,13 +27,12 @@
 
 package org.apache.http.nio.integration;
 
-import org.apache.http.LoggingSSLClientConnectionFactory;
-import org.apache.http.LoggingSSLServerConnectionFactory;
-import org.apache.http.SSLTestContexts;
 import org.apache.http.impl.nio.DefaultNHttpClientConnection;
 import org.apache.http.impl.nio.DefaultNHttpServerConnection;
 import org.apache.http.nio.NHttpConnectionFactory;
-import org.apache.http.params.HttpParams;
+import org.apache.http.nio.testserver.LoggingSSLClientConnectionFactory;
+import org.apache.http.nio.testserver.LoggingSSLServerConnectionFactory;
+import org.apache.http.nio.testserver.SSLTestContexts;
 
 /**
  * HttpCore NIO integration tests for async handlers using SSL.
@@ -41,15 +40,13 @@ import org.apache.http.params.HttpParams;
 public class TestHttpsAsyncHandlers extends TestHttpAsyncHandlers {
 
     @Override
-    protected NHttpConnectionFactory<DefaultNHttpServerConnection> createServerConnectionFactory(
-            final HttpParams params) throws Exception {
-        return new LoggingSSLServerConnectionFactory(SSLTestContexts.createServerSSLContext(), params);
+    protected NHttpConnectionFactory<DefaultNHttpServerConnection> createServerConnectionFactory() throws Exception {
+        return new LoggingSSLServerConnectionFactory(SSLTestContexts.createServerSSLContext());
     }
 
     @Override
-    protected NHttpConnectionFactory<DefaultNHttpClientConnection> createClientConnectionFactory(
-            final HttpParams params) throws Exception {
-        return new LoggingSSLClientConnectionFactory(SSLTestContexts.createClientSSLContext(), params);
+    protected NHttpConnectionFactory<DefaultNHttpClientConnection> createClientConnectionFactory() throws Exception {
+        return new LoggingSSLClientConnectionFactory(SSLTestContexts.createClientSSLContext());
     }
 
 }
diff --git a/httpcore-nio/src/test/java/org/apache/http/nio/integration/TestHttpsAsyncTimeout.java b/httpcore-nio/src/test/java/org/apache/http/nio/integration/TestHttpsAsyncTimeout.java
index e8daf1d..d9bc33c 100644
--- a/httpcore-nio/src/test/java/org/apache/http/nio/integration/TestHttpsAsyncTimeout.java
+++ b/httpcore-nio/src/test/java/org/apache/http/nio/integration/TestHttpsAsyncTimeout.java
@@ -27,23 +27,31 @@
 
 package org.apache.http.nio.integration;
 
-import org.apache.http.HttpCoreNIOTestBase;
+import java.net.InetSocketAddress;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
 import org.apache.http.HttpHost;
 import org.apache.http.HttpRequest;
 import org.apache.http.HttpResponse;
-import org.apache.http.LoggingClientConnectionFactory;
-import org.apache.http.LoggingSSLClientConnectionFactory;
-import org.apache.http.SSLTestContexts;
 import org.apache.http.concurrent.FutureCallback;
 import org.apache.http.impl.nio.DefaultNHttpClientConnection;
 import org.apache.http.impl.nio.DefaultNHttpServerConnection;
+import org.apache.http.impl.nio.pool.BasicNIOConnFactory;
 import org.apache.http.message.BasicHttpRequest;
+import org.apache.http.nio.NHttpClientConnection;
 import org.apache.http.nio.NHttpConnectionFactory;
+import org.apache.http.nio.pool.NIOConnFactory;
 import org.apache.http.nio.protocol.BasicAsyncRequestProducer;
 import org.apache.http.nio.protocol.BasicAsyncResponseConsumer;
 import org.apache.http.nio.protocol.HttpAsyncRequestExecutor;
-import org.apache.http.params.CoreConnectionPNames;
-import org.apache.http.params.HttpParams;
+import org.apache.http.nio.testserver.HttpCoreNIOTestBase;
+import org.apache.http.nio.testserver.LoggingClientConnectionFactory;
+import org.apache.http.nio.testserver.LoggingSSLClientConnectionFactory;
+import org.apache.http.nio.testserver.LoggingServerConnectionFactory;
+import org.apache.http.nio.testserver.SSLTestContexts;
 import org.apache.http.protocol.BasicHttpContext;
 import org.apache.http.protocol.HttpContext;
 import org.junit.After;
@@ -51,12 +59,6 @@ import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
 
-import java.net.InetSocketAddress;
-import java.net.ServerSocket;
-import java.net.Socket;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
 public class TestHttpsAsyncTimeout extends HttpCoreNIOTestBase {
 
     private ServerSocket serverSocket;
@@ -64,7 +66,6 @@ public class TestHttpsAsyncTimeout extends HttpCoreNIOTestBase {
     @Before
     public void setUp() throws Exception {
         initClient();
-        initConnPool();
     }
 
     @After
@@ -74,27 +75,27 @@ public class TestHttpsAsyncTimeout extends HttpCoreNIOTestBase {
     }
 
     @Override
-    protected NHttpConnectionFactory<DefaultNHttpServerConnection> createServerConnectionFactory(
-            final HttpParams params) throws Exception {
-        return null;
+    protected NHttpConnectionFactory<DefaultNHttpServerConnection> createServerConnectionFactory()
+        throws Exception {
+        return new LoggingServerConnectionFactory();
     }
 
     @Override
-    protected NHttpConnectionFactory<DefaultNHttpClientConnection> createClientConnectionFactory(
-            final HttpParams params) throws Exception {
-        return new LoggingClientConnectionFactory(params);
+    protected NHttpConnectionFactory<DefaultNHttpClientConnection> createClientConnectionFactory()
+        throws Exception {
+        return new LoggingClientConnectionFactory();
     }
 
     @Override
-    protected NHttpConnectionFactory<DefaultNHttpClientConnection> createClientSSLConnectionFactory(
-            final HttpParams params) throws Exception {
-
-        return new LoggingSSLClientConnectionFactory(SSLTestContexts.createClientSSLContext(), params);
+    protected NIOConnFactory<HttpHost, NHttpClientConnection> createPoolConnectionFactory()
+        throws Exception {
+        return new BasicNIOConnFactory(createClientConnectionFactory(),
+            new LoggingSSLClientConnectionFactory(SSLTestContexts.createClientSSLContext()));
     }
 
     private InetSocketAddress start() throws Exception {
 
-        HttpAsyncRequestExecutor clientHandler = new HttpAsyncRequestExecutor();
+        final HttpAsyncRequestExecutor clientHandler = new HttpAsyncRequestExecutor();
         this.client.start(clientHandler);
         serverSocket = new ServerSocket(0);
         return new InetSocketAddress(serverSocket.getInetAddress(), serverSocket.getLocalPort());
@@ -107,12 +108,12 @@ public class TestHttpsAsyncTimeout extends HttpCoreNIOTestBase {
         // connect, be unable to progress through the handshake, and then
         // time out when SO_TIMEOUT has elapsed.
 
-        InetSocketAddress address = start();
-        HttpHost target = new HttpHost("localhost", address.getPort(), "https");
+        final InetSocketAddress address = start();
+        final HttpHost target = new HttpHost("localhost", address.getPort(), "https");
 
         final CountDownLatch latch = new CountDownLatch(1);
 
-        FutureCallback<HttpResponse> callback = new FutureCallback<HttpResponse>() {
+        final FutureCallback<HttpResponse> callback = new FutureCallback<HttpResponse>() {
 
             public void cancelled() {
                 latch.countDown();
@@ -128,14 +129,14 @@ public class TestHttpsAsyncTimeout extends HttpCoreNIOTestBase {
 
         };
 
-        HttpRequest request = new BasicHttpRequest("GET", "/");
-        HttpContext context = new BasicHttpContext();
-        this.clientParams.setParameter(CoreConnectionPNames.SO_TIMEOUT, 2000);
-        this.executor.execute(
+        final HttpRequest request = new BasicHttpRequest("GET", "/");
+        final HttpContext context = new BasicHttpContext();
+        this.client.setTimeout(1000);
+        this.client.execute(
                 new BasicAsyncRequestProducer(target, request),
                 new BasicAsyncResponseConsumer(),
-                this.connpool, context, callback);
-        Socket accepted = serverSocket.accept();
+                context, callback);
+        final Socket accepted = serverSocket.accept();
         try {
             Assert.assertTrue(latch.await(10, TimeUnit.SECONDS));
         } finally {
diff --git a/httpcore-nio/src/test/java/org/apache/http/nio/integration/TestPipelining.java b/httpcore-nio/src/test/java/org/apache/http/nio/integration/TestPipelining.java
index 502aed0..3e654e4 100644
--- a/httpcore-nio/src/test/java/org/apache/http/nio/integration/TestPipelining.java
+++ b/httpcore-nio/src/test/java/org/apache/http/nio/integration/TestPipelining.java
@@ -39,16 +39,12 @@ import java.net.Socket;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
 
-import org.apache.http.HttpCoreNIOTestBase;
 import org.apache.http.HttpException;
 import org.apache.http.HttpRequest;
 import org.apache.http.HttpResponse;
 import org.apache.http.HttpResponseInterceptor;
-import org.apache.http.LoggingClientConnectionFactory;
-import org.apache.http.LoggingServerConnectionFactory;
 import org.apache.http.concurrent.Cancellable;
 import org.apache.http.entity.ContentType;
-import org.apache.http.impl.DefaultConnectionReuseStrategy;
 import org.apache.http.impl.nio.DefaultNHttpClientConnection;
 import org.apache.http.impl.nio.DefaultNHttpServerConnection;
 import org.apache.http.nio.NHttpConnectionFactory;
@@ -58,12 +54,15 @@ import org.apache.http.nio.protocol.BasicAsyncRequestHandler;
 import org.apache.http.nio.protocol.HttpAsyncExchange;
 import org.apache.http.nio.protocol.HttpAsyncRequestConsumer;
 import org.apache.http.nio.protocol.HttpAsyncRequestHandler;
-import org.apache.http.nio.protocol.HttpAsyncRequestHandlerRegistry;
 import org.apache.http.nio.protocol.HttpAsyncService;
+import org.apache.http.nio.protocol.UriHttpAsyncRequestHandlerMapper;
 import org.apache.http.nio.reactor.IOReactorStatus;
 import org.apache.http.nio.reactor.ListenerEndpoint;
-import org.apache.http.params.HttpParams;
+import org.apache.http.nio.testserver.HttpCoreNIOTestBase;
+import org.apache.http.nio.testserver.LoggingClientConnectionFactory;
+import org.apache.http.nio.testserver.LoggingServerConnectionFactory;
 import org.apache.http.protocol.HttpContext;
+import org.apache.http.protocol.HttpProcessor;
 import org.apache.http.protocol.HttpRequestHandler;
 import org.apache.http.protocol.ImmutableHttpProcessor;
 import org.apache.http.protocol.ResponseConnControl;
@@ -79,11 +78,13 @@ import org.junit.Test;
  */
 public class TestPipelining extends HttpCoreNIOTestBase {
 
+    protected HttpProcessor serverHttpProc;
+
     @Before
     public void setUp() throws Exception {
         initServer();
         this.serverHttpProc = new ImmutableHttpProcessor(new HttpResponseInterceptor[] {
-                new ResponseServer(),
+                new ResponseServer("TEST-SERVER/1.1"),
                 new ResponseContent(),
                 new ResponseConnControl()
         });
@@ -95,49 +96,43 @@ public class TestPipelining extends HttpCoreNIOTestBase {
     }
 
     @Override
-    protected NHttpConnectionFactory<DefaultNHttpServerConnection> createServerConnectionFactory(
-            final HttpParams params) throws Exception {
-        return new LoggingServerConnectionFactory(params);
+    protected NHttpConnectionFactory<DefaultNHttpServerConnection> createServerConnectionFactory() throws Exception {
+        return new LoggingServerConnectionFactory();
     }
 
     @Override
-    protected NHttpConnectionFactory<DefaultNHttpClientConnection> createClientConnectionFactory(
-            final HttpParams params) throws Exception {
-        return new LoggingClientConnectionFactory(params);
+    protected NHttpConnectionFactory<DefaultNHttpClientConnection> createClientConnectionFactory() throws Exception {
+        return new LoggingClientConnectionFactory();
     }
 
     @Test
     public void testBasicPipelining() throws Exception {
-        HttpAsyncRequestHandlerRegistry registry = new HttpAsyncRequestHandlerRegistry();
+        final UriHttpAsyncRequestHandlerMapper registry = new UriHttpAsyncRequestHandlerMapper();
         registry.register("*", new BasicAsyncRequestHandler(new HttpRequestHandler() {
 
             public void handle(
                     final HttpRequest request,
                     final HttpResponse response,
                     final HttpContext context) throws HttpException, IOException {
-                String content = "thank you very much";
-                NStringEntity entity = new NStringEntity(content, ContentType.DEFAULT_TEXT);
+                final String content = "thank you very much";
+                final NStringEntity entity = new NStringEntity(content, ContentType.DEFAULT_TEXT);
                 response.setEntity(entity);
             }
 
         }));
-        HttpAsyncService serviceHandler = new HttpAsyncService(
-                this.serverHttpProc,
-                new DefaultConnectionReuseStrategy(),
-                registry,
-                this.serverParams);
+        final HttpAsyncService serviceHandler = new HttpAsyncService(this.serverHttpProc, registry);
         this.server.start(serviceHandler);
 
-        ListenerEndpoint endpoint = this.server.getListenerEndpoint();
+        final ListenerEndpoint endpoint = this.server.getListenerEndpoint();
         endpoint.waitFor();
 
         Assert.assertEquals("Test server status", IOReactorStatus.ACTIVE, this.server.getStatus());
 
-        InetSocketAddress address = (InetSocketAddress) endpoint.getAddress();
-        Socket socket = new Socket("localhost", address.getPort());
+        final InetSocketAddress address = (InetSocketAddress) endpoint.getAddress();
+        final Socket socket = new Socket("localhost", address.getPort());
         try {
-            OutputStream outstream = socket.getOutputStream();
-            BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(outstream, "US-ASCII"));
+            final OutputStream outstream = socket.getOutputStream();
+            final BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(outstream, "US-ASCII"));
             writer.write("GET / HTTP/1.1\r\n");
             writer.write("Host: localhost\r\n");
             writer.write("\r\n");
@@ -146,10 +141,10 @@ public class TestPipelining extends HttpCoreNIOTestBase {
             writer.write("Connection: close\r\n");
             writer.write("\r\n");
             writer.flush();
-            InputStream instream = socket.getInputStream();
-            BufferedReader reader = new BufferedReader(new InputStreamReader(instream, "US-ASCII"));
-            StringBuilder buf = new StringBuilder();
-            char[] tmp = new char[1024];
+            final InputStream instream = socket.getInputStream();
+            final BufferedReader reader = new BufferedReader(new InputStreamReader(instream, "US-ASCII"));
+            final StringBuilder buf = new StringBuilder();
+            final char[] tmp = new char[1024];
             int l;
             while ((l = reader.read(tmp)) != -1) {
                 buf.append(tmp, 0, l);
@@ -170,7 +165,7 @@ public class TestPipelining extends HttpCoreNIOTestBase {
 //                    "Connection: close\r\n" +
 //                    "\r\n" +
 //                    "thank you very much";
-            String expected =
+            final String expected =
                     "HTTP/1.1 400 Bad Request\r\n" +
                     "Connection: Close\r\n" +
                     "Server: TEST-SERVER/1.1\r\n" +
@@ -191,14 +186,14 @@ public class TestPipelining extends HttpCoreNIOTestBase {
 
         final CountDownLatch latch = new CountDownLatch(1);
         final Cancellable cancellable = new Cancellable() {
-            
+
             public boolean cancel() {
                 latch.countDown();
                 return true;
             }
         };
 
-        HttpAsyncRequestHandlerRegistry registry = new HttpAsyncRequestHandlerRegistry();
+        final UriHttpAsyncRequestHandlerMapper registry = new UriHttpAsyncRequestHandlerMapper();
         registry.register("/long", new HttpAsyncRequestHandler<HttpRequest>() {
 
             public HttpAsyncRequestConsumer<HttpRequest> processRequest(final HttpRequest request,
@@ -221,29 +216,25 @@ public class TestPipelining extends HttpCoreNIOTestBase {
                     final HttpRequest request,
                     final HttpResponse response,
                     final HttpContext context) throws HttpException, IOException {
-                String content = "thank you very much";
-                NStringEntity entity = new NStringEntity(content, ContentType.DEFAULT_TEXT);
+                final String content = "thank you very much";
+                final NStringEntity entity = new NStringEntity(content, ContentType.DEFAULT_TEXT);
                 response.setEntity(entity);
             }
 
         }));
-        HttpAsyncService serviceHandler = new HttpAsyncService(
-                this.serverHttpProc,
-                new DefaultConnectionReuseStrategy(),
-                registry,
-                this.serverParams);
+        final HttpAsyncService serviceHandler = new HttpAsyncService(this.serverHttpProc, registry);
         this.server.start(serviceHandler);
 
-        ListenerEndpoint endpoint = this.server.getListenerEndpoint();
+        final ListenerEndpoint endpoint = this.server.getListenerEndpoint();
         endpoint.waitFor();
 
         Assert.assertEquals("Test server status", IOReactorStatus.ACTIVE, this.server.getStatus());
 
-        InetSocketAddress address = (InetSocketAddress) endpoint.getAddress();
-        Socket socket = new Socket("localhost", address.getPort());
+        final InetSocketAddress address = (InetSocketAddress) endpoint.getAddress();
+        final Socket socket = new Socket("localhost", address.getPort());
         try {
-            OutputStream outstream = socket.getOutputStream();
-            BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(outstream, "US-ASCII"));
+            final OutputStream outstream = socket.getOutputStream();
+            final BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(outstream, "US-ASCII"));
             writer.write("GET /long HTTP/1.1\r\n");
             writer.write("Host: localhost\r\n");
             writer.write("\r\n");
@@ -252,10 +243,10 @@ public class TestPipelining extends HttpCoreNIOTestBase {
             writer.write("Connection: close\r\n");
             writer.write("\r\n");
             writer.flush();
-            InputStream instream = socket.getInputStream();
-            BufferedReader reader = new BufferedReader(new InputStreamReader(instream, "US-ASCII"));
-            StringBuilder buf = new StringBuilder();
-            char[] tmp = new char[1024];
+            final InputStream instream = socket.getInputStream();
+            final BufferedReader reader = new BufferedReader(new InputStreamReader(instream, "US-ASCII"));
+            final StringBuilder buf = new StringBuilder();
+            final char[] tmp = new char[1024];
             int l;
             while ((l = reader.read(tmp)) != -1) {
                 buf.append(tmp, 0, l);
@@ -263,7 +254,7 @@ public class TestPipelining extends HttpCoreNIOTestBase {
             reader.close();
             writer.close();
 
-            String expected =
+            final String expected =
                     "HTTP/1.1 400 Bad Request\r\n" +
                     "Connection: Close\r\n" +
                     "Server: TEST-SERVER/1.1\r\n" +
diff --git a/httpcore-nio/src/test/java/org/apache/http/nio/integration/TestThrottlingNHttpHandlers.java b/httpcore-nio/src/test/java/org/apache/http/nio/integration/TestThrottlingNHttpHandlers.java
deleted file mode 100644
index 57dcf92..0000000
--- a/httpcore-nio/src/test/java/org/apache/http/nio/integration/TestThrottlingNHttpHandlers.java
+++ /dev/null
@@ -1,853 +0,0 @@
-/*
- * ====================================================================
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- *
- */
-
-package org.apache.http.nio.integration;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.UnsupportedEncodingException;
-import java.net.InetSocketAddress;
-import java.nio.charset.Charset;
-import java.util.LinkedList;
-import java.util.Queue;
-import java.util.concurrent.ConcurrentLinkedQueue;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-
-import org.apache.http.HttpCoreNIOTestBase;
-import org.apache.http.HttpEntity;
-import org.apache.http.HttpEntityEnclosingRequest;
-import org.apache.http.HttpException;
-import org.apache.http.HttpRequest;
-import org.apache.http.HttpRequestInterceptor;
-import org.apache.http.HttpResponse;
-import org.apache.http.HttpResponseInterceptor;
-import org.apache.http.HttpStatus;
-import org.apache.http.HttpVersion;
-import org.apache.http.LoggingClientConnectionFactory;
-import org.apache.http.LoggingServerConnectionFactory;
-import org.apache.http.entity.ContentType;
-import org.apache.http.entity.StringEntity;
-import org.apache.http.impl.DefaultConnectionReuseStrategy;
-import org.apache.http.impl.DefaultHttpResponseFactory;
-import org.apache.http.impl.nio.DefaultNHttpClientConnection;
-import org.apache.http.impl.nio.DefaultNHttpServerConnection;
-import org.apache.http.message.BasicHttpEntityEnclosingRequest;
-import org.apache.http.message.BasicHttpRequest;
-import org.apache.http.nio.NHttpConnectionFactory;
-import org.apache.http.nio.entity.NByteArrayEntity;
-import org.apache.http.nio.entity.NStringEntity;
-import org.apache.http.nio.protocol.HttpRequestExecutionHandler;
-import org.apache.http.nio.protocol.ThrottlingHttpClientHandler;
-import org.apache.http.nio.protocol.ThrottlingHttpServiceHandler;
-import org.apache.http.nio.reactor.IOReactorStatus;
-import org.apache.http.nio.reactor.ListenerEndpoint;
-import org.apache.http.nio.reactor.SessionRequest;
-import org.apache.http.params.CoreProtocolPNames;
-import org.apache.http.params.HttpParams;
-import org.apache.http.protocol.HTTP;
-import org.apache.http.protocol.HttpContext;
-import org.apache.http.protocol.HttpExpectationVerifier;
-import org.apache.http.protocol.HttpProcessor;
-import org.apache.http.protocol.HttpRequestHandler;
-import org.apache.http.protocol.ImmutableHttpProcessor;
-import org.apache.http.protocol.RequestConnControl;
-import org.apache.http.protocol.RequestContent;
-import org.apache.http.protocol.RequestExpectContinue;
-import org.apache.http.protocol.RequestTargetHost;
-import org.apache.http.protocol.RequestUserAgent;
-import org.apache.http.protocol.ResponseConnControl;
-import org.apache.http.protocol.ResponseContent;
-import org.apache.http.protocol.ResponseDate;
-import org.apache.http.protocol.ResponseServer;
-import org.apache.http.testserver.SimpleEventListener;
-import org.apache.http.testserver.SimpleHttpRequestHandlerResolver;
-import org.apache.http.util.EncodingUtils;
-import org.junit.After;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-
-/**
- * HttpCore NIO integration tests using throttling versions of the
- * protocol handlers.
- */
- at Deprecated
-public class TestThrottlingNHttpHandlers extends HttpCoreNIOTestBase {
-
-    @Before
-    public void setUp() throws Exception {
-        initServer();
-        initClient();
-    }
-
-    @After
-    public void tearDown() throws Exception {
-        shutDownClient();
-        shutDownServer();
-    }
-
-    @Override
-    protected NHttpConnectionFactory<DefaultNHttpServerConnection> createServerConnectionFactory(
-            final HttpParams params) throws Exception {
-        return new LoggingServerConnectionFactory(params);
-    }
-
-    @Override
-    protected NHttpConnectionFactory<DefaultNHttpClientConnection> createClientConnectionFactory(
-            final HttpParams params) throws Exception {
-        return new LoggingClientConnectionFactory(params);
-    }
-
-    private ExecutorService execService;
-
-    @Before
-    public void initExecService() throws Exception {
-        this.execService = Executors.newCachedThreadPool();
-    }
-
-    @After
-    public void shutDownExecService() {
-        this.execService.shutdownNow();
-    }
-
-    private void executeStandardTest(
-            final HttpRequestHandler requestHandler,
-            final HttpRequestExecutionHandler requestExecutionHandler) throws Exception {
-        int connNo = 3;
-        int reqNo = 20;
-        Job[] jobs = new Job[connNo * reqNo];
-        for (int i = 0; i < jobs.length; i++) {
-            jobs[i] = new Job();
-        }
-        Queue<Job> queue = new ConcurrentLinkedQueue<Job>();
-        for (int i = 0; i < jobs.length; i++) {
-            queue.add(jobs[i]);
-        }
-
-        ThrottlingHttpServiceHandler serviceHandler = new ThrottlingHttpServiceHandler(
-                this.serverHttpProc,
-                new DefaultHttpResponseFactory(),
-                new DefaultConnectionReuseStrategy(),
-                this.execService,
-                this.serverParams);
-
-        serviceHandler.setHandlerResolver(
-                new SimpleHttpRequestHandlerResolver(requestHandler));
-        serviceHandler.setEventListener(
-                new SimpleEventListener());
-
-        ThrottlingHttpClientHandler clientHandler = new ThrottlingHttpClientHandler(
-                this.clientHttpProc,
-                requestExecutionHandler,
-                new DefaultConnectionReuseStrategy(),
-                this.execService,
-                this.clientParams);
-
-        clientHandler.setEventListener(
-                new SimpleEventListener());
-
-        this.server.start(serviceHandler);
-        this.client.start(clientHandler);
-
-        ListenerEndpoint endpoint = this.server.getListenerEndpoint();
-        endpoint.waitFor();
-        InetSocketAddress serverAddress = (InetSocketAddress) endpoint.getAddress();
-
-        Assert.assertEquals("Test server status", IOReactorStatus.ACTIVE, this.server.getStatus());
-
-        Queue<SessionRequest> connRequests = new LinkedList<SessionRequest>();
-        for (int i = 0; i < connNo; i++) {
-            SessionRequest sessionRequest = this.client.openConnection(
-                    new InetSocketAddress("localhost", serverAddress.getPort()),
-                    queue);
-            connRequests.add(sessionRequest);
-        }
-
-        while (!connRequests.isEmpty()) {
-            SessionRequest sessionRequest = connRequests.remove();
-            sessionRequest.waitFor();
-            if (sessionRequest.getException() != null) {
-                throw sessionRequest.getException();
-            }
-            Assert.assertNotNull(sessionRequest.getSession());
-        }
-
-        Assert.assertEquals("Test client status", IOReactorStatus.ACTIVE, this.client.getStatus());
-
-        for (int i = 0; i < jobs.length; i++) {
-            Job testjob = jobs[i];
-            testjob.waitFor();
-            if (testjob.isSuccessful()) {
-                Assert.assertEquals(HttpStatus.SC_OK, testjob.getStatusCode());
-                Assert.assertEquals(testjob.getExpected(), testjob.getResult());
-            } else {
-                Assert.fail(testjob.getFailureMessage());
-            }
-        }
-    }
-
-    /**
-     * This test case executes a series of simple (non-pipelined) GET requests
-     * over multiple connections.
-     */
-    @Test
-    public void testSimpleHttpGets() throws Exception {
-        HttpRequestExecutionHandler requestExecutionHandler = new RequestExecutionHandler() {
-
-            @Override
-            protected HttpRequest generateRequest(Job testjob) {
-                String s = testjob.getPattern() + "x" + testjob.getCount();
-                return new BasicHttpRequest("GET", s);
-            }
-
-        };
-        executeStandardTest(new RequestHandler(), requestExecutionHandler);
-    }
-
-    /**
-     * This test case executes a series of simple (non-pipelined) POST requests
-     * with content length delimited content over multiple connections.
-     */
-    @Test
-    public void testSimpleHttpPostsWithContentLength() throws Exception {
-        HttpRequestExecutionHandler requestExecutionHandler = new RequestExecutionHandler() {
-
-            @Override
-            protected HttpRequest generateRequest(Job testjob) {
-                String s = testjob.getPattern() + "x" + testjob.getCount();
-                HttpEntityEnclosingRequest r = new BasicHttpEntityEnclosingRequest("POST", s);
-                NStringEntity entity = null;
-                try {
-                    entity = new NStringEntity(testjob.getExpected(), "US-ASCII");
-                    entity.setChunked(false);
-                } catch (UnsupportedEncodingException ignore) {
-                }
-                r.setEntity(entity);
-                return r;
-            }
-
-        };
-        executeStandardTest(new RequestHandler(), requestExecutionHandler);
-    }
-
-    /**
-     * This test case executes a series of simple (non-pipelined) POST requests
-     * with chunk coded content content over multiple connections.
-     */
-    @Test
-    public void testSimpleHttpPostsChunked() throws Exception {
-        HttpRequestExecutionHandler requestExecutionHandler = new RequestExecutionHandler() {
-
-            @Override
-            protected HttpRequest generateRequest(Job testjob) {
-                String s = testjob.getPattern() + "x" + testjob.getCount();
-                HttpEntityEnclosingRequest r = new BasicHttpEntityEnclosingRequest("POST", s);
-                NStringEntity entity = null;
-                try {
-                    entity = new NStringEntity(testjob.getExpected(), "US-ASCII");
-                    entity.setChunked(true);
-                } catch (UnsupportedEncodingException ignore) {
-                }
-                r.setEntity(entity);
-                return r;
-            }
-
-        };
-        executeStandardTest(new RequestHandler(), requestExecutionHandler);
-    }
-
-    /**
-     * This test case executes a series of simple (non-pipelined) HTTP/1.0
-     * POST requests over multiple persistent connections.
-     */
-    @Test
-    public void testSimpleHttpPostsHTTP10() throws Exception {
-        HttpRequestExecutionHandler requestExecutionHandler = new RequestExecutionHandler() {
-
-            @Override
-            protected HttpRequest generateRequest(Job testjob) {
-                String s = testjob.getPattern() + "x" + testjob.getCount();
-                HttpEntityEnclosingRequest r = new BasicHttpEntityEnclosingRequest("POST", s,
-                        HttpVersion.HTTP_1_0);
-                NStringEntity entity = null;
-                try {
-                    entity = new NStringEntity(testjob.getExpected(), "US-ASCII");
-                } catch (UnsupportedEncodingException ignore) {
-                }
-                r.setEntity(entity);
-                return r;
-            }
-
-        };
-        executeStandardTest(new RequestHandler(), requestExecutionHandler);
-    }
-
-    /**
-     * This test case executes a series of simple (non-pipelined) POST requests
-     * over multiple connections using the 'expect: continue' handshake.
-     */
-    @Test
-    public void testHttpPostsWithExpectContinue() throws Exception {
-        HttpRequestExecutionHandler requestExecutionHandler = new RequestExecutionHandler() {
-
-            @Override
-            protected HttpRequest generateRequest(Job testjob) {
-                String s = testjob.getPattern() + "x" + testjob.getCount();
-                HttpEntityEnclosingRequest r = new BasicHttpEntityEnclosingRequest("POST", s);
-                NStringEntity entity = null;
-                try {
-                    entity = new NStringEntity(testjob.getExpected(), "US-ASCII");
-                } catch (UnsupportedEncodingException ignore) {
-                }
-                r.setEntity(entity);
-                r.getParams().setBooleanParameter(CoreProtocolPNames.USE_EXPECT_CONTINUE, true);
-                return r;
-            }
-
-        };
-        executeStandardTest(new RequestHandler(), requestExecutionHandler);
-    }
-
-    /**
-     * This test case executes a series of simple (non-pipelined) POST requests
-     * over multiple connections that do not meet the target server expectations.
-     */
-    @Test
-    public void testHttpPostsWithExpectationVerification() throws Exception {
-        Job[] jobs = new Job[3];
-        jobs[0] = new Job("AAAAA", 10);
-        jobs[1] = new Job("AAAAA", 10);
-        jobs[2] = new Job("BBBBB", 20);
-        Queue<Job> queue = new ConcurrentLinkedQueue<Job>();
-        for (int i = 0; i < jobs.length; i++) {
-            queue.add(jobs[i]);
-        }
-
-        HttpExpectationVerifier expectationVerifier = new HttpExpectationVerifier() {
-
-            public void verify(
-                    final HttpRequest request,
-                    final HttpResponse response,
-                    final HttpContext context) throws HttpException {
-                String s = request.getRequestLine().getUri();
-                if (!s.equals("AAAAAx10")) {
-                    response.setStatusCode(HttpStatus.SC_EXPECTATION_FAILED);
-                    NByteArrayEntity outgoing = new NByteArrayEntity(
-                            EncodingUtils.getAsciiBytes("Expectation failed"));
-                    response.setEntity(outgoing);
-                }
-            }
-
-        };
-
-        HttpRequestExecutionHandler requestExecutionHandler = new RequestExecutionHandler() {
-
-            @Override
-            protected HttpRequest generateRequest(Job testjob) {
-                String s = testjob.getPattern() + "x" + testjob.getCount();
-                HttpEntityEnclosingRequest r = new BasicHttpEntityEnclosingRequest("POST", s);
-                NStringEntity entity = null;
-                try {
-                    entity = new NStringEntity(testjob.getExpected(), "US-ASCII");
-                } catch (UnsupportedEncodingException ignore) {
-                }
-                r.setEntity(entity);
-                r.getParams().setBooleanParameter(CoreProtocolPNames.USE_EXPECT_CONTINUE, true);
-                return r;
-            }
-
-        };
-
-        HttpProcessor serverHttpProc = new ImmutableHttpProcessor(new HttpResponseInterceptor[] {
-                new ResponseDate(),
-                new ResponseServer(),
-                new ResponseContent(),
-                new ResponseConnControl()
-        });
-
-        ThrottlingHttpServiceHandler serviceHandler = new ThrottlingHttpServiceHandler(
-                serverHttpProc,
-                new DefaultHttpResponseFactory(),
-                new DefaultConnectionReuseStrategy(),
-                this.execService,
-                this.serverParams);
-
-        serviceHandler.setHandlerResolver(
-                new SimpleHttpRequestHandlerResolver(new RequestHandler()));
-        serviceHandler.setExpectationVerifier(
-                expectationVerifier);
-        serviceHandler.setEventListener(
-                new SimpleEventListener());
-
-        HttpProcessor clientHttpProc = new ImmutableHttpProcessor(new HttpRequestInterceptor[] {
-                new RequestContent(),
-                new RequestTargetHost(),
-                new RequestConnControl(),
-                new RequestUserAgent(),
-                new RequestExpectContinue()});
-
-        ThrottlingHttpClientHandler clientHandler = new ThrottlingHttpClientHandler(
-                clientHttpProc,
-                requestExecutionHandler,
-                new DefaultConnectionReuseStrategy(),
-                this.execService,
-                this.clientParams);
-
-        clientHandler.setEventListener(
-                new SimpleEventListener());
-
-        this.server.start(serviceHandler);
-        this.client.start(clientHandler);
-
-        ListenerEndpoint endpoint = this.server.getListenerEndpoint();
-        endpoint.waitFor();
-        InetSocketAddress serverAddress = (InetSocketAddress) endpoint.getAddress();
-
-        Assert.assertEquals("Test server status", IOReactorStatus.ACTIVE, this.server.getStatus());
-
-        SessionRequest sessionRequest = this.client.openConnection(
-                new InetSocketAddress("localhost", serverAddress.getPort()),
-                queue);
-
-        sessionRequest.waitFor();
-        if (sessionRequest.getException() != null) {
-            throw sessionRequest.getException();
-        }
-        Assert.assertNotNull(sessionRequest.getSession());
-
-        Assert.assertEquals("Test client status", IOReactorStatus.ACTIVE, this.client.getStatus());
-
-        for (int i = 0; i < 2; i++) {
-            Job testjob = jobs[i];
-            testjob.waitFor();
-            if (testjob.isSuccessful()) {
-                Assert.assertEquals(testjob.getExpected(), testjob.getResult());
-            } else {
-                Assert.fail(testjob.getFailureMessage());
-            }
-        }
-        Job failedExpectation = jobs[2];
-        failedExpectation.waitFor();
-        Assert.assertEquals(HttpStatus.SC_EXPECTATION_FAILED, failedExpectation.getStatusCode());
-    }
-
-    /**
-     * This test case executes a series of simple (non-pipelined) HEAD requests
-     * over multiple connections.
-     */
-    @Test
-    public void testSimpleHttpHeads() throws Exception {
-        int connNo = 3;
-        int reqNo = 20;
-        Job[] jobs = new Job[connNo * reqNo];
-        for (int i = 0; i < jobs.length; i++) {
-            jobs[i] = new Job();
-        }
-        Queue<Job> queue = new ConcurrentLinkedQueue<Job>();
-        for (int i = 0; i < jobs.length; i++) {
-            queue.add(jobs[i]);
-        }
-
-        HttpRequestExecutionHandler requestExecutionHandler = new RequestExecutionHandler() {
-
-            @Override
-            protected HttpRequest generateRequest(Job testjob) {
-                String s = testjob.getPattern() + "x" + testjob.getCount();
-                return new BasicHttpRequest("HEAD", s);
-            }
-
-        };
-
-        HttpProcessor serverHttpProc = new ImmutableHttpProcessor(new HttpResponseInterceptor[] {
-                new ResponseDate(),
-                new ResponseServer(),
-                new ResponseContent(),
-                new ResponseConnControl()
-        });
-
-        ThrottlingHttpServiceHandler serviceHandler = new ThrottlingHttpServiceHandler(
-                serverHttpProc,
-                new DefaultHttpResponseFactory(),
-                new DefaultConnectionReuseStrategy(),
-                this.execService,
-                this.serverParams);
-
-        serviceHandler.setHandlerResolver(
-                new SimpleHttpRequestHandlerResolver(new RequestHandler()));
-        serviceHandler.setEventListener(
-                new SimpleEventListener());
-
-        HttpProcessor clientHttpProc = new ImmutableHttpProcessor(new HttpRequestInterceptor[] {
-                new RequestContent(),
-                new RequestTargetHost(),
-                new RequestConnControl(),
-                new RequestUserAgent(),
-                new RequestExpectContinue()});
-
-        ThrottlingHttpClientHandler clientHandler = new ThrottlingHttpClientHandler(
-                clientHttpProc,
-                requestExecutionHandler,
-                new DefaultConnectionReuseStrategy(),
-                this.execService,
-                this.clientParams);
-
-        clientHandler.setEventListener(new SimpleEventListener());
-
-        this.server.start(serviceHandler);
-        this.client.start(clientHandler);
-
-        ListenerEndpoint endpoint = this.server.getListenerEndpoint();
-        endpoint.waitFor();
-        InetSocketAddress serverAddress = (InetSocketAddress) endpoint.getAddress();
-
-        Assert.assertEquals("Test server status", IOReactorStatus.ACTIVE, this.server.getStatus());
-
-        Queue<SessionRequest> connRequests = new LinkedList<SessionRequest>();
-        for (int i = 0; i < connNo; i++) {
-            SessionRequest sessionRequest = this.client.openConnection(
-                    new InetSocketAddress("localhost", serverAddress.getPort()),
-                    queue);
-            connRequests.add(sessionRequest);
-        }
-
-        while (!connRequests.isEmpty()) {
-            SessionRequest sessionRequest = connRequests.remove();
-            sessionRequest.waitFor();
-            if (sessionRequest.getException() != null) {
-                throw sessionRequest.getException();
-            }
-            Assert.assertNotNull(sessionRequest.getSession());
-        }
-
-        Assert.assertEquals("Test client status", IOReactorStatus.ACTIVE, this.client.getStatus());
-
-        for (int i = 0; i < jobs.length; i++) {
-            Job testjob = jobs[i];
-            testjob.waitFor();
-            if (testjob.getFailureMessage() != null) {
-                Assert.fail(testjob.getFailureMessage());
-            }
-            Assert.assertEquals(HttpStatus.SC_OK, testjob.getStatusCode());
-            Assert.assertNull(testjob.getResult());
-        }
-    }
-
-    /**
-     * This test case tests if the protocol handler can correctly deal
-     * with requests with partially consumed content.
-     */
-    @Test
-    public void testSimpleHttpPostsContentNotConsumed() throws Exception {
-        HttpRequestHandler requestHandler = new HttpRequestHandler() {
-
-            public void handle(
-                    final HttpRequest request,
-                    final HttpResponse response,
-                    final HttpContext context) throws HttpException, IOException {
-
-                // Request content body has not been consumed!!!
-                response.setStatusCode(HttpStatus.SC_INTERNAL_SERVER_ERROR);
-                NStringEntity outgoing = new NStringEntity("Ooopsie");
-                response.setEntity(outgoing);
-            }
-
-        };
-        HttpRequestExecutionHandler requestExecutionHandler = new RequestExecutionHandler() {
-
-            @Override
-            protected HttpRequest generateRequest(Job testjob) {
-                String s = testjob.getPattern() + "x" + testjob.getCount();
-                HttpEntityEnclosingRequest r = new BasicHttpEntityEnclosingRequest("POST", s);
-                NStringEntity entity = null;
-                try {
-                    entity = new NStringEntity(testjob.getExpected(), "US-ASCII");
-                    entity.setChunked(testjob.getCount() % 2 == 0);
-                } catch (UnsupportedEncodingException ignore) {
-                }
-                r.setEntity(entity);
-                return r;
-            }
-
-        };
-        int connNo = 3;
-        int reqNo = 20;
-        Job[] jobs = new Job[connNo * reqNo];
-        for (int i = 0; i < jobs.length; i++) {
-            jobs[i] = new Job();
-        }
-        Queue<Job> queue = new ConcurrentLinkedQueue<Job>();
-        for (int i = 0; i < jobs.length; i++) {
-            queue.add(jobs[i]);
-        }
-
-        HttpProcessor serverHttpProc = new ImmutableHttpProcessor(new HttpResponseInterceptor[] {
-                new ResponseDate(),
-                new ResponseServer(),
-                new ResponseContent(),
-                new ResponseConnControl()
-        });
-
-        ThrottlingHttpServiceHandler serviceHandler = new ThrottlingHttpServiceHandler(
-                serverHttpProc,
-                new DefaultHttpResponseFactory(),
-                new DefaultConnectionReuseStrategy(),
-                this.execService,
-                this.serverParams);
-
-        serviceHandler.setHandlerResolver(
-                new SimpleHttpRequestHandlerResolver(requestHandler));
-        serviceHandler.setEventListener(
-                new SimpleEventListener());
-
-        HttpProcessor clientHttpProc = new ImmutableHttpProcessor(new HttpRequestInterceptor[] {
-                new RequestContent(),
-                new RequestTargetHost(),
-                new RequestConnControl(),
-                new RequestUserAgent(),
-                new RequestExpectContinue()});
-
-        ThrottlingHttpClientHandler clientHandler = new ThrottlingHttpClientHandler(
-                clientHttpProc,
-                requestExecutionHandler,
-                new DefaultConnectionReuseStrategy(),
-                this.execService,
-                this.clientParams);
-
-        clientHandler.setEventListener(
-                new SimpleEventListener());
-
-        this.server.start(serviceHandler);
-        this.client.start(clientHandler);
-
-        ListenerEndpoint endpoint = this.server.getListenerEndpoint();
-        endpoint.waitFor();
-        InetSocketAddress serverAddress = (InetSocketAddress) endpoint.getAddress();
-
-        Assert.assertEquals("Test server status", IOReactorStatus.ACTIVE, this.server.getStatus());
-
-        Queue<SessionRequest> connRequests = new LinkedList<SessionRequest>();
-        for (int i = 0; i < connNo; i++) {
-            SessionRequest sessionRequest = this.client.openConnection(
-                    new InetSocketAddress("localhost", serverAddress.getPort()),
-                    queue);
-            connRequests.add(sessionRequest);
-        }
-
-        while (!connRequests.isEmpty()) {
-            SessionRequest sessionRequest = connRequests.remove();
-            sessionRequest.waitFor();
-            if (sessionRequest.getException() != null) {
-                throw sessionRequest.getException();
-            }
-            Assert.assertNotNull(sessionRequest.getSession());
-        }
-
-        Assert.assertEquals("Test client status", IOReactorStatus.ACTIVE, this.client.getStatus());
-
-        for (int i = 0; i < jobs.length; i++) {
-            Job testjob = jobs[i];
-            testjob.waitFor();
-            if (testjob.isSuccessful()) {
-                Assert.assertEquals(HttpStatus.SC_INTERNAL_SERVER_ERROR, testjob.getStatusCode());
-                Assert.assertEquals("Ooopsie", testjob.getResult());
-            } else {
-                Assert.fail(testjob.getFailureMessage());
-            }
-        }
-    }
-
-    @Test
-    public void testInputThrottling() throws Exception {
-        HttpRequestExecutionHandler requestExecutionHandler = new HttpRequestExecutionHandler() {
-
-            public void initalizeContext(final HttpContext context, final Object attachment) {
-                context.setAttribute("queue", attachment);
-            }
-
-            public HttpRequest submitRequest(final HttpContext context) {
-
-                @SuppressWarnings("unchecked")
-                Queue<Job> queue = (Queue<Job>) context.getAttribute("queue");
-                if (queue == null) {
-                    throw new IllegalStateException("Queue is null");
-                }
-
-                Job testjob = queue.poll();
-                context.setAttribute("job", testjob);
-
-                if (testjob != null) {
-                    String s = testjob.getPattern() + "x" + testjob.getCount();
-                    HttpEntityEnclosingRequest r = new BasicHttpEntityEnclosingRequest("POST", s);
-                    StringEntity entity = null;
-                    try {
-                        entity = new StringEntity(testjob.getExpected(), "US-ASCII");
-                        entity.setChunked(testjob.getCount() % 2 == 0);
-                    } catch (UnsupportedEncodingException ignore) {
-                    }
-                    r.setEntity(entity);
-                    return r;
-                } else {
-                    return null;
-                }
-            }
-
-            public void handleResponse(final HttpResponse response, final HttpContext context) {
-                Job testjob = (Job) context.removeAttribute("job");
-                if (testjob == null) {
-                    throw new IllegalStateException("TestJob is null");
-                }
-
-                int statusCode = response.getStatusLine().getStatusCode();
-                String content = null;
-
-                HttpEntity entity = response.getEntity();
-                if (entity != null) {
-                    try {
-                        // Simulate slow response handling in order to cause the
-                        // internal content buffer to fill up, forcing the
-                        // protocol handler to throttle input rate
-                        ByteArrayOutputStream outstream = new ByteArrayOutputStream();
-                        InputStream instream = entity.getContent();
-                        byte[] tmp = new byte[2048];
-                        int l;
-                        while((l = instream.read(tmp)) != -1) {
-                            Thread.sleep(1);
-                            outstream.write(tmp, 0, l);
-                        }
-                        ContentType contentType = ContentType.getOrDefault(entity);
-                        Charset charset = contentType.getCharset();
-                        if (charset == null) {
-                            charset = HTTP.DEF_CONTENT_CHARSET;
-                        }
-                        content = new String(outstream.toByteArray(), charset.name());
-                    } catch (InterruptedException ex) {
-                        content = "Interrupted: " + ex.getMessage();
-                    } catch (IOException ex) {
-                        content = "I/O exception: " + ex.getMessage();
-                    }
-                }
-                testjob.setResult(statusCode, content);
-            }
-
-            public void finalizeContext(final HttpContext context) {
-                Job testjob = (Job) context.removeAttribute("job");
-                if (testjob != null) {
-                    testjob.fail("Request failed");
-                }
-            }
-
-        };
-        int connNo = 3;
-        int reqNo = 20;
-        Job[] jobs = new Job[connNo * reqNo];
-        for (int i = 0; i < jobs.length; i++) {
-            jobs[i] = new Job(10000);
-        }
-        Queue<Job> queue = new ConcurrentLinkedQueue<Job>();
-        for (int i = 0; i < jobs.length; i++) {
-            queue.add(jobs[i]);
-        }
-
-        HttpProcessor serverHttpProc = new ImmutableHttpProcessor(new HttpResponseInterceptor[] {
-                new ResponseDate(),
-                new ResponseServer(),
-                new ResponseContent(),
-                new ResponseConnControl()
-        });
-
-        ThrottlingHttpServiceHandler serviceHandler = new ThrottlingHttpServiceHandler(
-                serverHttpProc,
-                new DefaultHttpResponseFactory(),
-                new DefaultConnectionReuseStrategy(),
-                this.execService,
-                this.serverParams);
-
-        serviceHandler.setHandlerResolver(
-                new SimpleHttpRequestHandlerResolver(new RequestHandler()));
-        serviceHandler.setEventListener(
-                new SimpleEventListener());
-
-        HttpProcessor clientHttpProc = new ImmutableHttpProcessor(new HttpRequestInterceptor[] {
-                new RequestContent(),
-                new RequestTargetHost(),
-                new RequestConnControl(),
-                new RequestUserAgent(),
-                new RequestExpectContinue()});
-
-        ThrottlingHttpClientHandler clientHandler = new ThrottlingHttpClientHandler(
-                clientHttpProc,
-                requestExecutionHandler,
-                new DefaultConnectionReuseStrategy(),
-                this.execService,
-                this.clientParams);
-
-        clientHandler.setEventListener(
-                new SimpleEventListener());
-
-        this.server.start(serviceHandler);
-        this.client.start(clientHandler);
-
-        ListenerEndpoint endpoint = this.server.getListenerEndpoint();
-        endpoint.waitFor();
-        InetSocketAddress serverAddress = (InetSocketAddress) endpoint.getAddress();
-
-        Assert.assertEquals("Test server status", IOReactorStatus.ACTIVE, this.server.getStatus());
-
-        Queue<SessionRequest> connRequests = new LinkedList<SessionRequest>();
-        for (int i = 0; i < connNo; i++) {
-            SessionRequest sessionRequest = this.client.openConnection(
-                    new InetSocketAddress("localhost", serverAddress.getPort()),
-                    queue);
-            connRequests.add(sessionRequest);
-        }
-
-        while (!connRequests.isEmpty()) {
-            SessionRequest sessionRequest = connRequests.remove();
-            sessionRequest.waitFor();
-            if (sessionRequest.getException() != null) {
-                throw sessionRequest.getException();
-            }
-            Assert.assertNotNull(sessionRequest.getSession());
-        }
-
-        Assert.assertEquals("Test client status", IOReactorStatus.ACTIVE, this.client.getStatus());
-
-        for (int i = 0; i < jobs.length; i++) {
-            Job testjob = jobs[i];
-            testjob.waitFor();
-            if (testjob.isSuccessful()) {
-                Assert.assertEquals(HttpStatus.SC_OK, testjob.getStatusCode());
-                Assert.assertEquals(testjob.getExpected(), testjob.getResult());
-            } else {
-                Assert.fail(testjob.getFailureMessage());
-            }
-        }
-    }
-
-}
diff --git a/httpcore-nio/src/test/java/org/apache/http/nio/integration/TestTruncatedChunks.java b/httpcore-nio/src/test/java/org/apache/http/nio/integration/TestTruncatedChunks.java
index 33576f6..b757316 100644
--- a/httpcore-nio/src/test/java/org/apache/http/nio/integration/TestTruncatedChunks.java
+++ b/httpcore-nio/src/test/java/org/apache/http/nio/integration/TestTruncatedChunks.java
@@ -35,24 +35,18 @@ import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Future;
 
 import org.apache.http.Consts;
-import org.apache.http.HttpCoreNIOTestBase;
 import org.apache.http.HttpEntity;
 import org.apache.http.HttpHost;
-import org.apache.http.HttpRequestFactory;
 import org.apache.http.HttpResponse;
 import org.apache.http.HttpStatus;
-import org.apache.http.LoggingClientConnectionFactory;
-import org.apache.http.LoggingNHttpServerConnection;
 import org.apache.http.MalformedChunkCodingException;
 import org.apache.http.TruncatedChunkException;
 import org.apache.http.entity.ContentLengthStrategy;
 import org.apache.http.entity.ContentType;
 import org.apache.http.entity.InputStreamEntity;
-import org.apache.http.impl.DefaultConnectionReuseStrategy;
 import org.apache.http.impl.io.HttpTransportMetricsImpl;
 import org.apache.http.impl.nio.DefaultNHttpClientConnection;
 import org.apache.http.impl.nio.DefaultNHttpServerConnection;
-import org.apache.http.impl.nio.DefaultNHttpServerConnectionFactory;
 import org.apache.http.impl.nio.codecs.AbstractContentEncoder;
 import org.apache.http.message.BasicHttpRequest;
 import org.apache.http.nio.ContentDecoder;
@@ -61,20 +55,18 @@ import org.apache.http.nio.IOControl;
 import org.apache.http.nio.NHttpConnectionFactory;
 import org.apache.http.nio.entity.ContentInputStream;
 import org.apache.http.nio.protocol.AbstractAsyncResponseConsumer;
-import org.apache.http.nio.protocol.BasicAsyncRequestProducer;
-import org.apache.http.nio.protocol.BasicAsyncResponseConsumer;
 import org.apache.http.nio.protocol.BasicAsyncRequestHandler;
-import org.apache.http.nio.protocol.HttpAsyncRequestExecutor;
-import org.apache.http.nio.protocol.HttpAsyncRequestHandlerRegistry;
-import org.apache.http.nio.protocol.HttpAsyncService;
+import org.apache.http.nio.protocol.BasicAsyncRequestProducer;
+import org.apache.http.nio.protocol.UriHttpAsyncRequestHandlerMapper;
 import org.apache.http.nio.reactor.IOReactorStatus;
 import org.apache.http.nio.reactor.IOSession;
 import org.apache.http.nio.reactor.ListenerEndpoint;
 import org.apache.http.nio.reactor.SessionOutputBuffer;
-import org.apache.http.nio.util.ByteBufferAllocator;
+import org.apache.http.nio.testserver.HttpCoreNIOTestBase;
+import org.apache.http.nio.testserver.LoggingClientConnectionFactory;
+import org.apache.http.nio.testserver.LoggingNHttpServerConnection;
 import org.apache.http.nio.util.HeapByteBufferAllocator;
 import org.apache.http.nio.util.SimpleInputBuffer;
-import org.apache.http.params.HttpParams;
 import org.apache.http.protocol.HttpContext;
 import org.apache.http.util.CharArrayBuffer;
 import org.apache.http.util.EntityUtils;
@@ -92,26 +84,22 @@ public class TestTruncatedChunks extends HttpCoreNIOTestBase {
     public void setUp() throws Exception {
         initServer();
         initClient();
-        initConnPool();
     }
 
     @After
     public void tearDown() throws Exception {
-        shutDownConnPool();
         shutDownClient();
         shutDownServer();
     }
 
     @Override
-    protected NHttpConnectionFactory<DefaultNHttpServerConnection> createServerConnectionFactory(
-            final HttpParams params) throws Exception {
-        return new CustomServerConnectionFactory(params);
+    protected NHttpConnectionFactory<DefaultNHttpServerConnection> createServerConnectionFactory() throws Exception {
+        return new CustomServerConnectionFactory();
     }
 
     @Override
-    protected NHttpConnectionFactory<DefaultNHttpClientConnection> createClientConnectionFactory(
-            final HttpParams params) throws Exception {
-        return new LoggingClientConnectionFactory(params);
+    protected NHttpConnectionFactory<DefaultNHttpClientConnection> createClientConnectionFactory() throws Exception {
+        return new LoggingClientConnectionFactory();
     }
 
     private static final byte[] GARBAGE = new byte[] {'1', '2', '3', '4', '5' };
@@ -131,10 +119,10 @@ public class TestTruncatedChunks extends HttpCoreNIOTestBase {
 
         @Override
         public void complete() throws IOException {
-            this.completed = true;
+            super.complete();
         }
 
-        public int write(ByteBuffer src) throws IOException {
+        public int write(final ByteBuffer src) throws IOException {
             int chunk;
             if (!this.done) {
                 this.lineBuffer.clear();
@@ -146,7 +134,7 @@ public class TestTruncatedChunks extends HttpCoreNIOTestBase {
             } else {
                 chunk = 0;
             }
-            long bytesWritten = this.buffer.flush(this.channel);
+            final long bytesWritten = this.buffer.flush(this.channel);
             if (bytesWritten > 0) {
                 this.metrics.incrementBytesTransferred(bytesWritten);
             }
@@ -158,33 +146,27 @@ public class TestTruncatedChunks extends HttpCoreNIOTestBase {
 
     }
 
-    static class CustomServerConnectionFactory extends DefaultNHttpServerConnectionFactory {
+    static class CustomServerConnectionFactory implements NHttpConnectionFactory<DefaultNHttpServerConnection> {
 
-        public CustomServerConnectionFactory(final HttpParams params) {
-            super(params);
+        public CustomServerConnectionFactory() {
+            super();
         }
 
-        @Override
-        protected DefaultNHttpServerConnection createConnection(
-                final IOSession session,
-                final HttpRequestFactory requestFactory,
-                final ByteBufferAllocator allocator,
-                final HttpParams params) {
-
-            return new LoggingNHttpServerConnection(session, requestFactory, allocator, params) {
-
-                        @Override
-                        protected ContentEncoder createContentEncoder(
-                                final long len,
-                                final WritableByteChannel channel,
-                                final SessionOutputBuffer buffer,
-                                final HttpTransportMetricsImpl metrics) {
-                            if (len == ContentLengthStrategy.CHUNKED) {
-                                return new BrokenChunkEncoder(channel, buffer, metrics);
-                            } else {
-                                return super.createContentEncoder(len, channel, buffer, metrics);
-                            }
-                        }
+        public DefaultNHttpServerConnection createConnection(final IOSession session) {
+            return new LoggingNHttpServerConnection(session) {
+
+                @Override
+                protected ContentEncoder createContentEncoder(
+                        final long len,
+                        final WritableByteChannel channel,
+                        final SessionOutputBuffer buffer,
+                        final HttpTransportMetricsImpl metrics) {
+                    if (len == ContentLengthStrategy.CHUNKED) {
+                        return new BrokenChunkEncoder(channel, buffer, metrics);
+                    } else {
+                        return super.createContentEncoder(len, channel, buffer, metrics);
+                    }
+                }
 
             };
         }
@@ -193,36 +175,27 @@ public class TestTruncatedChunks extends HttpCoreNIOTestBase {
 
     @Test
     public void testTruncatedChunkException() throws Exception {
-        HttpAsyncRequestHandlerRegistry registry = new HttpAsyncRequestHandlerRegistry();
+        final UriHttpAsyncRequestHandlerMapper registry = new UriHttpAsyncRequestHandlerMapper();
         registry.register("*", new BasicAsyncRequestHandler(new SimpleRequestHandler(true)));
-        HttpAsyncService serviceHandler = new HttpAsyncService(
-                this.serverHttpProc,
-                new DefaultConnectionReuseStrategy(),
-                registry,
-                this.serverParams);
-        HttpAsyncRequestExecutor clientHandler = new HttpAsyncRequestExecutor();
-        this.server.start(serviceHandler);
-        this.client.start(clientHandler);
-
-        ListenerEndpoint endpoint = this.server.getListenerEndpoint();
+        this.server.start(registry);
+        this.client.start();
+
+        final ListenerEndpoint endpoint = this.server.getListenerEndpoint();
         endpoint.waitFor();
 
         Assert.assertEquals("Test server status", IOReactorStatus.ACTIVE, this.server.getStatus());
 
-        String pattern = RndTestPatternGenerator.generateText();
-        int count = RndTestPatternGenerator.generateCount(1000);
+        final String pattern = RndTestPatternGenerator.generateText();
+        final int count = RndTestPatternGenerator.generateCount(1000);
 
-        HttpHost target = new HttpHost("localhost", ((InetSocketAddress)endpoint.getAddress()).getPort());
-        BasicHttpRequest request = new BasicHttpRequest("GET", pattern + "x" + count);
-        Future<HttpResponse> future = this.executor.execute(
-                new BasicAsyncRequestProducer(target, request),
-                new BasicAsyncResponseConsumer(),
-                this.connpool);
+        final HttpHost target = new HttpHost("localhost", ((InetSocketAddress)endpoint.getAddress()).getPort());
+        final BasicHttpRequest request = new BasicHttpRequest("GET", pattern + "x" + count);
+        final Future<HttpResponse> future = this.client.execute(target, request);
         try {
             future.get();
             Assert.fail("ExecutionException should have been thrown");
-        } catch (ExecutionException ex) {
-            Throwable cause = ex.getCause();
+        } catch (final ExecutionException ex) {
+            final Throwable cause = ex.getCause();
             Assert.assertTrue(cause instanceof MalformedChunkCodingException);
         }
     }
@@ -234,7 +207,7 @@ public class TestTruncatedChunks extends HttpCoreNIOTestBase {
 
         public LenientAsyncResponseConsumer() {
             super();
-            this.buffer = new SimpleInputBuffer(2048, new HeapByteBufferAllocator());
+            this.buffer = new SimpleInputBuffer(2048, HeapByteBufferAllocator.INSTANCE);
         }
 
         @Override
@@ -255,7 +228,7 @@ public class TestTruncatedChunks extends HttpCoreNIOTestBase {
                 if (decoder.isCompleted()) {
                     finished = true;
                 }
-            } catch (TruncatedChunkException ex) {
+            } catch (final TruncatedChunkException ex) {
                 this.buffer.shutdown();
                 finished = true;
             }
@@ -278,33 +251,27 @@ public class TestTruncatedChunks extends HttpCoreNIOTestBase {
 
     @Test
     public void testIgnoreTruncatedChunkException() throws Exception {
-        HttpAsyncRequestHandlerRegistry registry = new HttpAsyncRequestHandlerRegistry();
+        final UriHttpAsyncRequestHandlerMapper registry = new UriHttpAsyncRequestHandlerMapper();
         registry.register("*", new BasicAsyncRequestHandler(new SimpleRequestHandler(true)));
-        HttpAsyncService serviceHandler = new HttpAsyncService(
-                this.serverHttpProc,
-                new DefaultConnectionReuseStrategy(),
-                registry,
-                this.serverParams);
-        HttpAsyncRequestExecutor clientHandler = new HttpAsyncRequestExecutor();
-        this.server.start(serviceHandler);
-        this.client.start(clientHandler);
-
-        ListenerEndpoint endpoint = this.server.getListenerEndpoint();
+        this.server.start(registry);
+        this.client.start();
+
+        final ListenerEndpoint endpoint = this.server.getListenerEndpoint();
         endpoint.waitFor();
 
         Assert.assertEquals("Test server status", IOReactorStatus.ACTIVE, this.server.getStatus());
 
-        String pattern = RndTestPatternGenerator.generateText();
-        int count = RndTestPatternGenerator.generateCount(1000);
+        final String pattern = RndTestPatternGenerator.generateText();
+        final int count = RndTestPatternGenerator.generateCount(1000);
 
-        HttpHost target = new HttpHost("localhost", ((InetSocketAddress)endpoint.getAddress()).getPort());
-        BasicHttpRequest request = new BasicHttpRequest("GET", pattern + "x" + count);
-        Future<HttpResponse> future = this.executor.execute(
+        final HttpHost target = new HttpHost("localhost", ((InetSocketAddress)endpoint.getAddress()).getPort());
+        final BasicHttpRequest request = new BasicHttpRequest("GET", pattern + "x" + count);
+        final Future<HttpResponse> future = this.client.execute(
                 new BasicAsyncRequestProducer(target, request),
                 new LenientAsyncResponseConsumer(),
-                this.connpool);
+                null, null);
 
-        HttpResponse response = future.get();
+        final HttpResponse response = future.get();
         Assert.assertNotNull(response);
         Assert.assertEquals(HttpStatus.SC_OK, response.getStatusLine().getStatusCode());
         Assert.assertEquals(new String(GARBAGE, Consts.ISO_8859_1.name()),
diff --git a/httpcore-nio/src/test/java/org/apache/http/nio/pool/TestNIOConnPool.java b/httpcore-nio/src/test/java/org/apache/http/nio/pool/TestNIOConnPool.java
index ea265a3..867962f 100644
--- a/httpcore-nio/src/test/java/org/apache/http/nio/pool/TestNIOConnPool.java
+++ b/httpcore-nio/src/test/java/org/apache/http/nio/pool/TestNIOConnPool.java
@@ -30,12 +30,11 @@ import java.io.IOException;
 import java.net.InetSocketAddress;
 import java.net.SocketAddress;
 import java.net.SocketTimeoutException;
+import java.net.UnknownHostException;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Future;
 import java.util.concurrent.TimeUnit;
 
-import junit.framework.Assert;
-
 import org.apache.http.concurrent.BasicFuture;
 import org.apache.http.nio.reactor.ConnectingIOReactor;
 import org.apache.http.nio.reactor.IOSession;
@@ -43,6 +42,7 @@ import org.apache.http.nio.reactor.SessionRequest;
 import org.apache.http.nio.reactor.SessionRequestCallback;
 import org.apache.http.pool.PoolEntry;
 import org.apache.http.pool.PoolStats;
+import org.junit.Assert;
 import org.junit.Test;
 import org.mockito.Mockito;
 
@@ -50,45 +50,60 @@ public class TestNIOConnPool {
 
     static class LocalPoolEntry extends PoolEntry<String, IOSession> {
 
+        private boolean closed;
+
         public LocalPoolEntry(final String route, final IOSession conn) {
             super(null, route, conn);
         }
 
         @Override
         public void close() {
+            if (this.closed) {
+                return;
+            }
+            this.closed = true;
             getConnection().close();
         }
 
         @Override
         public boolean isClosed() {
-            return getConnection().isClosed();
+            return this.closed;
         }
 
     }
 
     static class LocalConnFactory implements NIOConnFactory<String, IOSession> {
 
-        public IOSession create(String route, IOSession session) throws IOException {
+        public IOSession create(final String route, final IOSession session) throws IOException {
             return session;
         }
 
     }
 
-    static class LocalSessionPool extends AbstractNIOConnPool<String, IOSession, LocalPoolEntry> {
+    static class LocalAddressResolver implements SocketAddressResolver<String> {
 
-        public LocalSessionPool(
-                final ConnectingIOReactor ioreactor, int defaultMaxPerRoute, int maxTotal) {
-            super(ioreactor, new LocalConnFactory(), defaultMaxPerRoute, maxTotal);
+        public SocketAddress resolveLocalAddress(final String route) {
+            return null;
         }
 
-        @Override
-        protected SocketAddress resolveRemoteAddress(final String route) {
+        public SocketAddress resolveRemoteAddress(final String route) {
             return InetSocketAddress.createUnresolved(route, 80);
         }
 
-        @Override
-        protected SocketAddress resolveLocalAddress(final String route) {
-            return InetSocketAddress.createUnresolved(route, 80);
+    }
+
+    static class LocalSessionPool extends AbstractNIOConnPool<String, IOSession, LocalPoolEntry> {
+
+        public LocalSessionPool(
+                final ConnectingIOReactor ioreactor, final int defaultMaxPerRoute, final int maxTotal) {
+            super(ioreactor, new LocalConnFactory(), new LocalAddressResolver(), defaultMaxPerRoute, maxTotal);
+        }
+
+        public LocalSessionPool(
+                final ConnectingIOReactor ioreactor,
+                final SocketAddressResolver<String> addressResolver,
+                final int defaultMaxPerRoute, final int maxTotal) {
+            super(ioreactor, new LocalConnFactory(), addressResolver, defaultMaxPerRoute, maxTotal);
         }
 
         @Override
@@ -100,14 +115,14 @@ public class TestNIOConnPool {
 
     @Test
     public void testEmptyPool() throws Exception {
-        ConnectingIOReactor ioreactor = Mockito.mock(ConnectingIOReactor.class);
-        LocalSessionPool pool = new LocalSessionPool(ioreactor, 2, 10);
-        PoolStats totals = pool.getTotalStats();
+        final ConnectingIOReactor ioreactor = Mockito.mock(ConnectingIOReactor.class);
+        final LocalSessionPool pool = new LocalSessionPool(ioreactor, 2, 10);
+        final PoolStats totals = pool.getTotalStats();
         Assert.assertEquals(0, totals.getAvailable());
         Assert.assertEquals(0, totals.getLeased());
         Assert.assertEquals(0, totals.getPending());
         Assert.assertEquals(10, totals.getMax());
-        PoolStats stats = pool.getStats("somehost");
+        final PoolStats stats = pool.getStats("somehost");
         Assert.assertEquals(0, stats.getAvailable());
         Assert.assertEquals(0, stats.getLeased());
         Assert.assertEquals(0, stats.getPending());
@@ -117,46 +132,46 @@ public class TestNIOConnPool {
 
     @Test
     public void testInternalLeaseRequest() throws Exception {
-        LeaseRequest<String, IOSession, LocalPoolEntry> leaseRequest =
-            new LeaseRequest<String, IOSession, LocalPoolEntry>("somehost", null, 0,
+        final LeaseRequest<String, IOSession, LocalPoolEntry> leaseRequest =
+            new LeaseRequest<String, IOSession, LocalPoolEntry>("somehost", null, 0, 0,
                     new BasicFuture<LocalPoolEntry>(null));
         Assert.assertEquals("[somehost][null]", leaseRequest.toString());
     }
 
     @Test
     public void testInvalidConstruction() throws Exception {
-        ConnectingIOReactor ioreactor = Mockito.mock(ConnectingIOReactor.class);
+        final ConnectingIOReactor ioreactor = Mockito.mock(ConnectingIOReactor.class);
         try {
             new LocalSessionPool(null, 1, 1);
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException expected) {
+        } catch (final IllegalArgumentException expected) {
         }
         try {
             new LocalSessionPool(ioreactor, -1, 1);
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException expected) {
+        } catch (final IllegalArgumentException expected) {
         }
         try {
             new LocalSessionPool(ioreactor, 1, -1);
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException expected) {
+        } catch (final IllegalArgumentException expected) {
         }
     }
 
     @Test
     public void testSuccessfulConnect() throws Exception {
-        IOSession iosession = Mockito.mock(IOSession.class);
-        SessionRequest sessionRequest = Mockito.mock(SessionRequest.class);
+        final IOSession iosession = Mockito.mock(IOSession.class);
+        final SessionRequest sessionRequest = Mockito.mock(SessionRequest.class);
         Mockito.when(sessionRequest.getAttachment()).thenReturn("somehost");
         Mockito.when(sessionRequest.getSession()).thenReturn(iosession);
-        ConnectingIOReactor ioreactor = Mockito.mock(ConnectingIOReactor.class);
+        final ConnectingIOReactor ioreactor = Mockito.mock(ConnectingIOReactor.class);
         Mockito.when(ioreactor.connect(
                 Mockito.any(SocketAddress.class),
                 Mockito.any(SocketAddress.class),
                 Mockito.any(), Mockito.any(SessionRequestCallback.class))).
                 thenReturn(sessionRequest);
-        LocalSessionPool pool = new LocalSessionPool(ioreactor, 2, 10);
-        Future<LocalPoolEntry> future = pool.lease("somehost", null, 100, TimeUnit.MILLISECONDS, null);
+        final LocalSessionPool pool = new LocalSessionPool(ioreactor, 2, 10);
+        final Future<LocalPoolEntry> future = pool.lease("somehost", null, 100, TimeUnit.MILLISECONDS, null);
         Mockito.verify(sessionRequest).setConnectTimeout(100);
 
         PoolStats totals = pool.getTotalStats();
@@ -168,7 +183,7 @@ public class TestNIOConnPool {
 
         Assert.assertTrue(future.isDone());
         Assert.assertFalse(future.isCancelled());
-        LocalPoolEntry entry = future.get();
+        final LocalPoolEntry entry = future.get();
         Assert.assertNotNull(entry);
 
         totals = pool.getTotalStats();
@@ -179,17 +194,17 @@ public class TestNIOConnPool {
 
     @Test
     public void testFailedConnect() throws Exception {
-        SessionRequest sessionRequest = Mockito.mock(SessionRequest.class);
+        final SessionRequest sessionRequest = Mockito.mock(SessionRequest.class);
         Mockito.when(sessionRequest.getAttachment()).thenReturn("somehost");
         Mockito.when(sessionRequest.getException()).thenReturn(new IOException());
-        ConnectingIOReactor ioreactor = Mockito.mock(ConnectingIOReactor.class);
+        final ConnectingIOReactor ioreactor = Mockito.mock(ConnectingIOReactor.class);
         Mockito.when(ioreactor.connect(
                 Mockito.any(SocketAddress.class),
                 Mockito.any(SocketAddress.class),
                 Mockito.any(), Mockito.any(SessionRequestCallback.class))).
                 thenReturn(sessionRequest);
-        LocalSessionPool pool = new LocalSessionPool(ioreactor, 2, 10);
-        Future<LocalPoolEntry> future = pool.lease("somehost", null);
+        final LocalSessionPool pool = new LocalSessionPool(ioreactor, 2, 10);
+        final Future<LocalPoolEntry> future = pool.lease("somehost", null);
 
         PoolStats totals = pool.getTotalStats();
         Assert.assertEquals(0, totals.getAvailable());
@@ -203,7 +218,7 @@ public class TestNIOConnPool {
         try {
             future.get();
             Assert.fail("ExecutionException should have been thrown");
-        } catch (ExecutionException ex) {
+        } catch (final ExecutionException ex) {
             Assert.assertTrue(ex.getCause() instanceof IOException);
         }
 
@@ -215,18 +230,18 @@ public class TestNIOConnPool {
 
     @Test
     public void testCencelledConnect() throws Exception {
-        IOSession iosession = Mockito.mock(IOSession.class);
-        SessionRequest sessionRequest = Mockito.mock(SessionRequest.class);
+        final IOSession iosession = Mockito.mock(IOSession.class);
+        final SessionRequest sessionRequest = Mockito.mock(SessionRequest.class);
         Mockito.when(sessionRequest.getAttachment()).thenReturn("somehost");
         Mockito.when(sessionRequest.getSession()).thenReturn(iosession);
-        ConnectingIOReactor ioreactor = Mockito.mock(ConnectingIOReactor.class);
+        final ConnectingIOReactor ioreactor = Mockito.mock(ConnectingIOReactor.class);
         Mockito.when(ioreactor.connect(
                 Mockito.any(SocketAddress.class),
                 Mockito.any(SocketAddress.class),
                 Mockito.any(), Mockito.any(SessionRequestCallback.class))).
                 thenReturn(sessionRequest);
-        LocalSessionPool pool = new LocalSessionPool(ioreactor, 2, 10);
-        Future<LocalPoolEntry> future = pool.lease("somehost", null);
+        final LocalSessionPool pool = new LocalSessionPool(ioreactor, 2, 10);
+        final Future<LocalPoolEntry> future = pool.lease("somehost", null);
 
         PoolStats totals = pool.getTotalStats();
         Assert.assertEquals(0, totals.getAvailable());
@@ -237,7 +252,7 @@ public class TestNIOConnPool {
 
         Assert.assertTrue(future.isDone());
         Assert.assertTrue(future.isCancelled());
-        LocalPoolEntry entry = future.get();
+        final LocalPoolEntry entry = future.get();
         Assert.assertNull(entry);
 
         totals = pool.getTotalStats();
@@ -248,18 +263,18 @@ public class TestNIOConnPool {
 
     @Test
     public void testTimeoutConnect() throws Exception {
-        IOSession iosession = Mockito.mock(IOSession.class);
-        SessionRequest sessionRequest = Mockito.mock(SessionRequest.class);
+        final IOSession iosession = Mockito.mock(IOSession.class);
+        final SessionRequest sessionRequest = Mockito.mock(SessionRequest.class);
         Mockito.when(sessionRequest.getAttachment()).thenReturn("somehost");
         Mockito.when(sessionRequest.getSession()).thenReturn(iosession);
-        ConnectingIOReactor ioreactor = Mockito.mock(ConnectingIOReactor.class);
+        final ConnectingIOReactor ioreactor = Mockito.mock(ConnectingIOReactor.class);
         Mockito.when(ioreactor.connect(
                 Mockito.any(SocketAddress.class),
                 Mockito.any(SocketAddress.class),
                 Mockito.any(), Mockito.any(SessionRequestCallback.class))).
                 thenReturn(sessionRequest);
-        LocalSessionPool pool = new LocalSessionPool(ioreactor, 2, 10);
-        Future<LocalPoolEntry> future = pool.lease("somehost", null);
+        final LocalSessionPool pool = new LocalSessionPool(ioreactor, 2, 10);
+        final Future<LocalPoolEntry> future = pool.lease("somehost", null);
 
         PoolStats totals = pool.getTotalStats();
         Assert.assertEquals(0, totals.getAvailable());
@@ -273,7 +288,7 @@ public class TestNIOConnPool {
         try {
             future.get();
             Assert.fail("ExecutionException should have been thrown");
-        } catch (ExecutionException ex) {
+        } catch (final ExecutionException ex) {
             Assert.assertTrue(ex.getCause() instanceof SocketTimeoutException);
         }
 
@@ -284,18 +299,40 @@ public class TestNIOConnPool {
     }
 
     @Test
+    public void testConnectUnknownHost() throws Exception {
+        final SessionRequest sessionRequest = Mockito.mock(SessionRequest.class);
+        Mockito.when(sessionRequest.getAttachment()).thenReturn("somehost");
+        Mockito.when(sessionRequest.getException()).thenReturn(new IOException());
+        final ConnectingIOReactor ioreactor = Mockito.mock(ConnectingIOReactor.class);
+        @SuppressWarnings("unchecked")
+        final SocketAddressResolver<String> addressResolver = Mockito.mock(SocketAddressResolver.class);
+        Mockito.when(addressResolver.resolveRemoteAddress("somehost")).thenThrow(new UnknownHostException());
+        final LocalSessionPool pool = new LocalSessionPool(ioreactor, addressResolver, 2, 10);
+        final Future<LocalPoolEntry> future = pool.lease("somehost", null);
+
+        Assert.assertTrue(future.isDone());
+        Assert.assertFalse(future.isCancelled());
+        try {
+            future.get();
+            Assert.fail("ExecutionException should have been thrown");
+        } catch (final ExecutionException ex) {
+            Assert.assertTrue(ex.getCause() instanceof UnknownHostException);
+        }
+    }
+
+    @Test
     public void testLeaseRelease() throws Exception {
-        IOSession iosession1 = Mockito.mock(IOSession.class);
-        SessionRequest sessionRequest1 = Mockito.mock(SessionRequest.class);
+        final IOSession iosession1 = Mockito.mock(IOSession.class);
+        final SessionRequest sessionRequest1 = Mockito.mock(SessionRequest.class);
         Mockito.when(sessionRequest1.getAttachment()).thenReturn("somehost");
         Mockito.when(sessionRequest1.getSession()).thenReturn(iosession1);
 
-        IOSession iosession2 = Mockito.mock(IOSession.class);
-        SessionRequest sessionRequest2 = Mockito.mock(SessionRequest.class);
+        final IOSession iosession2 = Mockito.mock(IOSession.class);
+        final SessionRequest sessionRequest2 = Mockito.mock(SessionRequest.class);
         Mockito.when(sessionRequest2.getAttachment()).thenReturn("otherhost");
         Mockito.when(sessionRequest2.getSession()).thenReturn(iosession2);
 
-        ConnectingIOReactor ioreactor = Mockito.mock(ConnectingIOReactor.class);
+        final ConnectingIOReactor ioreactor = Mockito.mock(ConnectingIOReactor.class);
         Mockito.when(ioreactor.connect(
                 Mockito.eq(InetSocketAddress.createUnresolved("somehost", 80)),
                 Mockito.any(SocketAddress.class),
@@ -307,19 +344,19 @@ public class TestNIOConnPool {
                 Mockito.any(), Mockito.any(SessionRequestCallback.class))).
                 thenReturn(sessionRequest2);
 
-        LocalSessionPool pool = new LocalSessionPool(ioreactor, 2, 10);
-        Future<LocalPoolEntry> future1 = pool.lease("somehost", null);
+        final LocalSessionPool pool = new LocalSessionPool(ioreactor, 2, 10);
+        final Future<LocalPoolEntry> future1 = pool.lease("somehost", null);
         pool.requestCompleted(sessionRequest1);
-        Future<LocalPoolEntry> future2 = pool.lease("somehost", null);
+        final Future<LocalPoolEntry> future2 = pool.lease("somehost", null);
         pool.requestCompleted(sessionRequest1);
-        Future<LocalPoolEntry> future3 = pool.lease("otherhost", null);
+        final Future<LocalPoolEntry> future3 = pool.lease("otherhost", null);
         pool.requestCompleted(sessionRequest2);
 
-        LocalPoolEntry entry1 = future1.get();
+        final LocalPoolEntry entry1 = future1.get();
         Assert.assertNotNull(entry1);
-        LocalPoolEntry entry2 = future2.get();
+        final LocalPoolEntry entry2 = future2.get();
         Assert.assertNotNull(entry2);
-        LocalPoolEntry entry3 = future3.get();
+        final LocalPoolEntry entry3 = future3.get();
         Assert.assertNotNull(entry3);
 
         pool.release(entry1, true);
@@ -328,7 +365,7 @@ public class TestNIOConnPool {
         Mockito.verify(iosession1, Mockito.never()).close();
         Mockito.verify(iosession2, Mockito.times(1)).close();
 
-        PoolStats totals = pool.getTotalStats();
+        final PoolStats totals = pool.getTotalStats();
         Assert.assertEquals(2, totals.getAvailable());
         Assert.assertEquals(0, totals.getLeased());
         Assert.assertEquals(0, totals.getPending());
@@ -336,40 +373,40 @@ public class TestNIOConnPool {
 
     @Test
     public void testLeaseIllegal() throws Exception {
-        ConnectingIOReactor ioreactor = Mockito.mock(ConnectingIOReactor.class);
-        LocalSessionPool pool = new LocalSessionPool(ioreactor, 2, 10);
+        final ConnectingIOReactor ioreactor = Mockito.mock(ConnectingIOReactor.class);
+        final LocalSessionPool pool = new LocalSessionPool(ioreactor, 2, 10);
         try {
             pool.lease(null, null, 0, TimeUnit.MILLISECONDS, null);
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException expected) {
+        } catch (final IllegalArgumentException expected) {
         }
         try {
             pool.lease("somehost", null, 0, null, null);
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException expected) {
+        } catch (final IllegalArgumentException expected) {
         }
     }
 
     @Test
     public void testReleaseUnknownEntry() throws Exception {
-        ConnectingIOReactor ioreactor = Mockito.mock(ConnectingIOReactor.class);
-        LocalSessionPool pool = new LocalSessionPool(ioreactor, 2, 2);
+        final ConnectingIOReactor ioreactor = Mockito.mock(ConnectingIOReactor.class);
+        final LocalSessionPool pool = new LocalSessionPool(ioreactor, 2, 2);
         pool.release(new LocalPoolEntry("somehost", Mockito.mock(IOSession.class)), true);
     }
 
     @Test
     public void testMaxLimits() throws Exception {
-        IOSession iosession1 = Mockito.mock(IOSession.class);
-        SessionRequest sessionRequest1 = Mockito.mock(SessionRequest.class);
+        final IOSession iosession1 = Mockito.mock(IOSession.class);
+        final SessionRequest sessionRequest1 = Mockito.mock(SessionRequest.class);
         Mockito.when(sessionRequest1.getAttachment()).thenReturn("somehost");
         Mockito.when(sessionRequest1.getSession()).thenReturn(iosession1);
 
-        IOSession iosession2 = Mockito.mock(IOSession.class);
-        SessionRequest sessionRequest2 = Mockito.mock(SessionRequest.class);
+        final IOSession iosession2 = Mockito.mock(IOSession.class);
+        final SessionRequest sessionRequest2 = Mockito.mock(SessionRequest.class);
         Mockito.when(sessionRequest2.getAttachment()).thenReturn("otherhost");
         Mockito.when(sessionRequest2.getSession()).thenReturn(iosession2);
 
-        ConnectingIOReactor ioreactor = Mockito.mock(ConnectingIOReactor.class);
+        final ConnectingIOReactor ioreactor = Mockito.mock(ConnectingIOReactor.class);
         Mockito.when(ioreactor.connect(
                 Mockito.eq(InetSocketAddress.createUnresolved("somehost", 80)),
                 Mockito.any(SocketAddress.class),
@@ -381,49 +418,49 @@ public class TestNIOConnPool {
                 Mockito.any(), Mockito.any(SessionRequestCallback.class))).
                 thenReturn(sessionRequest2);
 
-        LocalSessionPool pool = new LocalSessionPool(ioreactor, 2, 10);
+        final LocalSessionPool pool = new LocalSessionPool(ioreactor, 2, 10);
         pool.setMaxPerRoute("somehost", 2);
         pool.setMaxPerRoute("otherhost", 1);
         pool.setMaxTotal(3);
 
-        Future<LocalPoolEntry> future1 = pool.lease("somehost", null);
+        final Future<LocalPoolEntry> future1 = pool.lease("somehost", null);
         pool.requestCompleted(sessionRequest1);
-        Future<LocalPoolEntry> future2 = pool.lease("somehost", null);
+        final Future<LocalPoolEntry> future2 = pool.lease("somehost", null);
         pool.requestCompleted(sessionRequest1);
-        Future<LocalPoolEntry> future3 = pool.lease("otherhost", null);
+        final Future<LocalPoolEntry> future3 = pool.lease("otherhost", null);
         pool.requestCompleted(sessionRequest2);
 
-        LocalPoolEntry entry1 = future1.get();
+        final LocalPoolEntry entry1 = future1.get();
         Assert.assertNotNull(entry1);
-        LocalPoolEntry entry2 = future2.get();
+        final LocalPoolEntry entry2 = future2.get();
         Assert.assertNotNull(entry2);
-        LocalPoolEntry entry3 = future3.get();
+        final LocalPoolEntry entry3 = future3.get();
         Assert.assertNotNull(entry3);
 
         pool.release(entry1, true);
         pool.release(entry2, true);
         pool.release(entry3, true);
 
-        PoolStats totals = pool.getTotalStats();
+        final PoolStats totals = pool.getTotalStats();
         Assert.assertEquals(3, totals.getAvailable());
         Assert.assertEquals(0, totals.getLeased());
         Assert.assertEquals(0, totals.getPending());
 
-        Future<LocalPoolEntry> future4 = pool.lease("somehost", null);
-        Future<LocalPoolEntry> future5 = pool.lease("somehost", null);
-        Future<LocalPoolEntry> future6 = pool.lease("otherhost", null);
-        Future<LocalPoolEntry> future7 = pool.lease("somehost", null);
-        Future<LocalPoolEntry> future8 = pool.lease("somehost", null);
-        Future<LocalPoolEntry> future9 = pool.lease("otherhost", null);
+        final Future<LocalPoolEntry> future4 = pool.lease("somehost", null);
+        final Future<LocalPoolEntry> future5 = pool.lease("somehost", null);
+        final Future<LocalPoolEntry> future6 = pool.lease("otherhost", null);
+        final Future<LocalPoolEntry> future7 = pool.lease("somehost", null);
+        final Future<LocalPoolEntry> future8 = pool.lease("somehost", null);
+        final Future<LocalPoolEntry> future9 = pool.lease("otherhost", null);
 
         Assert.assertTrue(future4.isDone());
-        LocalPoolEntry entry4 = future4.get();
+        final LocalPoolEntry entry4 = future4.get();
         Assert.assertNotNull(entry4);
         Assert.assertTrue(future5.isDone());
-        LocalPoolEntry entry5 = future5.get();
+        final LocalPoolEntry entry5 = future5.get();
         Assert.assertNotNull(entry5);
         Assert.assertTrue(future6.isDone());
-        LocalPoolEntry entry6 = future6.get();
+        final LocalPoolEntry entry6 = future6.get();
         Assert.assertNotNull(entry6);
         Assert.assertFalse(future7.isDone());
         Assert.assertFalse(future8.isDone());
@@ -448,27 +485,27 @@ public class TestNIOConnPool {
 
     @Test
     public void testConnectionRedistributionOnTotalMaxLimit() throws Exception {
-        IOSession iosession1 = Mockito.mock(IOSession.class);
-        SessionRequest sessionRequest1 = Mockito.mock(SessionRequest.class);
+        final IOSession iosession1 = Mockito.mock(IOSession.class);
+        final SessionRequest sessionRequest1 = Mockito.mock(SessionRequest.class);
         Mockito.when(sessionRequest1.getAttachment()).thenReturn("somehost");
         Mockito.when(sessionRequest1.getSession()).thenReturn(iosession1);
 
-        IOSession iosession2 = Mockito.mock(IOSession.class);
-        SessionRequest sessionRequest2 = Mockito.mock(SessionRequest.class);
+        final IOSession iosession2 = Mockito.mock(IOSession.class);
+        final SessionRequest sessionRequest2 = Mockito.mock(SessionRequest.class);
         Mockito.when(sessionRequest2.getAttachment()).thenReturn("somehost");
         Mockito.when(sessionRequest2.getSession()).thenReturn(iosession2);
 
-        IOSession iosession3 = Mockito.mock(IOSession.class);
-        SessionRequest sessionRequest3 = Mockito.mock(SessionRequest.class);
+        final IOSession iosession3 = Mockito.mock(IOSession.class);
+        final SessionRequest sessionRequest3 = Mockito.mock(SessionRequest.class);
         Mockito.when(sessionRequest3.getAttachment()).thenReturn("otherhost");
         Mockito.when(sessionRequest3.getSession()).thenReturn(iosession3);
 
-        IOSession iosession4 = Mockito.mock(IOSession.class);
-        SessionRequest sessionRequest4 = Mockito.mock(SessionRequest.class);
+        final IOSession iosession4 = Mockito.mock(IOSession.class);
+        final SessionRequest sessionRequest4 = Mockito.mock(SessionRequest.class);
         Mockito.when(sessionRequest4.getAttachment()).thenReturn("otherhost");
         Mockito.when(sessionRequest4.getSession()).thenReturn(iosession4);
 
-        ConnectingIOReactor ioreactor = Mockito.mock(ConnectingIOReactor.class);
+        final ConnectingIOReactor ioreactor = Mockito.mock(ConnectingIOReactor.class);
         Mockito.when(ioreactor.connect(
                 Mockito.eq(InetSocketAddress.createUnresolved("somehost", 80)),
                 Mockito.any(SocketAddress.class),
@@ -480,15 +517,15 @@ public class TestNIOConnPool {
                 Mockito.any(), Mockito.any(SessionRequestCallback.class))).
                 thenReturn(sessionRequest3, sessionRequest4, sessionRequest3);
 
-        LocalSessionPool pool = new LocalSessionPool(ioreactor, 2, 10);
+        final LocalSessionPool pool = new LocalSessionPool(ioreactor, 2, 10);
         pool.setMaxPerRoute("somehost", 2);
         pool.setMaxPerRoute("otherhost", 2);
         pool.setMaxTotal(2);
 
-        Future<LocalPoolEntry> future1 = pool.lease("somehost", null);
-        Future<LocalPoolEntry> future2 = pool.lease("somehost", null);
-        Future<LocalPoolEntry> future3 = pool.lease("otherhost", null);
-        Future<LocalPoolEntry> future4 = pool.lease("otherhost", null);
+        final Future<LocalPoolEntry> future1 = pool.lease("somehost", null);
+        final Future<LocalPoolEntry> future2 = pool.lease("somehost", null);
+        final Future<LocalPoolEntry> future3 = pool.lease("otherhost", null);
+        final Future<LocalPoolEntry> future4 = pool.lease("otherhost", null);
 
         Mockito.verify(ioreactor, Mockito.times(2)).connect(
                 Mockito.eq(InetSocketAddress.createUnresolved("somehost", 80)),
@@ -504,10 +541,10 @@ public class TestNIOConnPool {
         pool.requestCompleted(sessionRequest2);
 
         Assert.assertTrue(future1.isDone());
-        LocalPoolEntry entry1 = future1.get();
+        final LocalPoolEntry entry1 = future1.get();
         Assert.assertNotNull(entry1);
         Assert.assertTrue(future2.isDone());
-        LocalPoolEntry entry2 = future2.get();
+        final LocalPoolEntry entry2 = future2.get();
         Assert.assertNotNull(entry2);
 
         Assert.assertFalse(future3.isDone());
@@ -535,10 +572,10 @@ public class TestNIOConnPool {
         pool.requestCompleted(sessionRequest4);
 
         Assert.assertTrue(future3.isDone());
-        LocalPoolEntry entry3 = future3.get();
+        final LocalPoolEntry entry3 = future3.get();
         Assert.assertNotNull(entry3);
         Assert.assertTrue(future4.isDone());
-        LocalPoolEntry entry4 = future4.get();
+        final LocalPoolEntry entry4 = future4.get();
         Assert.assertNotNull(entry4);
 
         totals = pool.getTotalStats();
@@ -546,8 +583,8 @@ public class TestNIOConnPool {
         Assert.assertEquals(2, totals.getLeased());
         Assert.assertEquals(0, totals.getPending());
 
-        Future<LocalPoolEntry> future5 = pool.lease("somehost", null);
-        Future<LocalPoolEntry> future6 = pool.lease("otherhost", null);
+        final Future<LocalPoolEntry> future5 = pool.lease("somehost", null);
+        final Future<LocalPoolEntry> future6 = pool.lease("otherhost", null);
 
         Mockito.verify(ioreactor, Mockito.times(2)).connect(
                 Mockito.eq(InetSocketAddress.createUnresolved("somehost", 80)),
@@ -575,10 +612,10 @@ public class TestNIOConnPool {
         pool.requestCompleted(sessionRequest1);
 
         Assert.assertTrue(future5.isDone());
-        LocalPoolEntry entry5 = future5.get();
+        final LocalPoolEntry entry5 = future5.get();
         Assert.assertNotNull(entry5);
         Assert.assertTrue(future6.isDone());
-        LocalPoolEntry entry6 = future6.get();
+        final LocalPoolEntry entry6 = future6.get();
         Assert.assertNotNull(entry6);
 
         totals = pool.getTotalStats();
@@ -607,34 +644,34 @@ public class TestNIOConnPool {
 
     @Test
     public void testStatefulConnectionRedistributionOnPerRouteMaxLimit() throws Exception {
-        IOSession iosession1 = Mockito.mock(IOSession.class);
-        SessionRequest sessionRequest1 = Mockito.mock(SessionRequest.class);
+        final IOSession iosession1 = Mockito.mock(IOSession.class);
+        final SessionRequest sessionRequest1 = Mockito.mock(SessionRequest.class);
         Mockito.when(sessionRequest1.getAttachment()).thenReturn("somehost");
         Mockito.when(sessionRequest1.getSession()).thenReturn(iosession1);
 
-        IOSession iosession2 = Mockito.mock(IOSession.class);
-        SessionRequest sessionRequest2 = Mockito.mock(SessionRequest.class);
+        final IOSession iosession2 = Mockito.mock(IOSession.class);
+        final SessionRequest sessionRequest2 = Mockito.mock(SessionRequest.class);
         Mockito.when(sessionRequest2.getAttachment()).thenReturn("somehost");
         Mockito.when(sessionRequest2.getSession()).thenReturn(iosession2);
 
-        IOSession iosession3 = Mockito.mock(IOSession.class);
-        SessionRequest sessionRequest3 = Mockito.mock(SessionRequest.class);
+        final IOSession iosession3 = Mockito.mock(IOSession.class);
+        final SessionRequest sessionRequest3 = Mockito.mock(SessionRequest.class);
         Mockito.when(sessionRequest3.getAttachment()).thenReturn("somehost");
         Mockito.when(sessionRequest3.getSession()).thenReturn(iosession3);
 
-        ConnectingIOReactor ioreactor = Mockito.mock(ConnectingIOReactor.class);
+        final ConnectingIOReactor ioreactor = Mockito.mock(ConnectingIOReactor.class);
         Mockito.when(ioreactor.connect(
                 Mockito.eq(InetSocketAddress.createUnresolved("somehost", 80)),
                 Mockito.any(SocketAddress.class),
                 Mockito.any(), Mockito.any(SessionRequestCallback.class))).
                 thenReturn(sessionRequest1, sessionRequest2, sessionRequest3);
 
-        LocalSessionPool pool = new LocalSessionPool(ioreactor, 2, 10);
+        final LocalSessionPool pool = new LocalSessionPool(ioreactor, 2, 10);
         pool.setMaxPerRoute("somehost", 2);
         pool.setMaxTotal(2);
 
-        Future<LocalPoolEntry> future1 = pool.lease("somehost", null);
-        Future<LocalPoolEntry> future2 = pool.lease("somehost", null);
+        final Future<LocalPoolEntry> future1 = pool.lease("somehost", null);
+        final Future<LocalPoolEntry> future2 = pool.lease("somehost", null);
 
         Mockito.verify(ioreactor, Mockito.times(2)).connect(
                 Mockito.eq(InetSocketAddress.createUnresolved("somehost", 80)),
@@ -645,10 +682,10 @@ public class TestNIOConnPool {
         pool.requestCompleted(sessionRequest2);
 
         Assert.assertTrue(future1.isDone());
-        LocalPoolEntry entry1 = future1.get();
+        final LocalPoolEntry entry1 = future1.get();
         Assert.assertNotNull(entry1);
         Assert.assertTrue(future2.isDone());
-        LocalPoolEntry entry2 = future2.get();
+        final LocalPoolEntry entry2 = future2.get();
         Assert.assertNotNull(entry2);
 
         PoolStats totals = pool.getTotalStats();
@@ -661,14 +698,14 @@ public class TestNIOConnPool {
         entry2.setState("some-stuff");
         pool.release(entry2, true);
 
-        Future<LocalPoolEntry> future3 = pool.lease("somehost", "some-stuff");
-        Future<LocalPoolEntry> future4 = pool.lease("somehost", "some-stuff");
+        final Future<LocalPoolEntry> future3 = pool.lease("somehost", "some-stuff");
+        final Future<LocalPoolEntry> future4 = pool.lease("somehost", "some-stuff");
 
         Assert.assertTrue(future1.isDone());
-        LocalPoolEntry entry3 = future3.get();
+        final LocalPoolEntry entry3 = future3.get();
         Assert.assertNotNull(entry3);
         Assert.assertTrue(future4.isDone());
-        LocalPoolEntry entry4 = future4.get();
+        final LocalPoolEntry entry4 = future4.get();
         Assert.assertNotNull(entry4);
 
         Mockito.verify(ioreactor, Mockito.times(2)).connect(
@@ -684,7 +721,7 @@ public class TestNIOConnPool {
         Assert.assertEquals(0, totals.getLeased());
         Assert.assertEquals(0, totals.getPending());
 
-        Future<LocalPoolEntry> future5 = pool.lease("somehost", "some-other-stuff");
+        final Future<LocalPoolEntry> future5 = pool.lease("somehost", "some-other-stuff");
 
         Assert.assertFalse(future5.isDone());
 
@@ -704,22 +741,22 @@ public class TestNIOConnPool {
 
     @Test
     public void testCreateNewIfExpired() throws Exception {
-        IOSession iosession1 = Mockito.mock(IOSession.class);
+        final IOSession iosession1 = Mockito.mock(IOSession.class);
         Mockito.when(iosession1.isClosed()).thenReturn(Boolean.TRUE);
-        SessionRequest sessionRequest1 = Mockito.mock(SessionRequest.class);
+        final SessionRequest sessionRequest1 = Mockito.mock(SessionRequest.class);
         Mockito.when(sessionRequest1.getAttachment()).thenReturn("somehost");
         Mockito.when(sessionRequest1.getSession()).thenReturn(iosession1);
 
-        ConnectingIOReactor ioreactor = Mockito.mock(ConnectingIOReactor.class);
+        final ConnectingIOReactor ioreactor = Mockito.mock(ConnectingIOReactor.class);
         Mockito.when(ioreactor.connect(
                 Mockito.eq(InetSocketAddress.createUnresolved("somehost", 80)),
                 Mockito.any(SocketAddress.class),
                 Mockito.any(), Mockito.any(SessionRequestCallback.class))).
                 thenReturn(sessionRequest1);
 
-        LocalSessionPool pool = new LocalSessionPool(ioreactor, 2, 2);
+        final LocalSessionPool pool = new LocalSessionPool(ioreactor, 2, 2);
 
-        Future<LocalPoolEntry> future1 = pool.lease("somehost", null);
+        final Future<LocalPoolEntry> future1 = pool.lease("somehost", null);
 
         Mockito.verify(ioreactor, Mockito.times(1)).connect(
                 Mockito.any(SocketAddress.class), Mockito.any(SocketAddress.class),
@@ -728,7 +765,7 @@ public class TestNIOConnPool {
         pool.requestCompleted(sessionRequest1);
 
         Assert.assertTrue(future1.isDone());
-        LocalPoolEntry entry1 = future1.get();
+        final LocalPoolEntry entry1 = future1.get();
         Assert.assertNotNull(entry1);
 
         entry1.updateExpiry(1, TimeUnit.MILLISECONDS);
@@ -736,7 +773,7 @@ public class TestNIOConnPool {
 
         Thread.sleep(200L);
 
-        Future<LocalPoolEntry> future2 = pool.lease("somehost", null);
+        final Future<LocalPoolEntry> future2 = pool.lease("somehost", null);
 
         Assert.assertFalse(future2.isDone());
 
@@ -745,11 +782,11 @@ public class TestNIOConnPool {
                 Mockito.any(SocketAddress.class), Mockito.any(SocketAddress.class),
                 Mockito.any(), Mockito.any(SessionRequestCallback.class));
 
-        PoolStats totals = pool.getTotalStats();
+        final PoolStats totals = pool.getTotalStats();
         Assert.assertEquals(0, totals.getAvailable());
         Assert.assertEquals(0, totals.getLeased());
         Assert.assertEquals(1, totals.getPending());
-        PoolStats stats = pool.getStats("somehost");
+        final PoolStats stats = pool.getStats("somehost");
         Assert.assertEquals(0, stats.getAvailable());
         Assert.assertEquals(0, stats.getLeased());
         Assert.assertEquals(1, stats.getPending());
@@ -757,36 +794,36 @@ public class TestNIOConnPool {
 
     @Test
     public void testCloseExpired() throws Exception {
-        IOSession iosession1 = Mockito.mock(IOSession.class);
+        final IOSession iosession1 = Mockito.mock(IOSession.class);
         Mockito.when(iosession1.isClosed()).thenReturn(Boolean.TRUE);
-        SessionRequest sessionRequest1 = Mockito.mock(SessionRequest.class);
+        final SessionRequest sessionRequest1 = Mockito.mock(SessionRequest.class);
         Mockito.when(sessionRequest1.getAttachment()).thenReturn("somehost");
         Mockito.when(sessionRequest1.getSession()).thenReturn(iosession1);
 
-        IOSession iosession2 = Mockito.mock(IOSession.class);
-        SessionRequest sessionRequest2 = Mockito.mock(SessionRequest.class);
+        final IOSession iosession2 = Mockito.mock(IOSession.class);
+        final SessionRequest sessionRequest2 = Mockito.mock(SessionRequest.class);
         Mockito.when(sessionRequest2.getAttachment()).thenReturn("somehost");
         Mockito.when(sessionRequest2.getSession()).thenReturn(iosession2);
 
-        ConnectingIOReactor ioreactor = Mockito.mock(ConnectingIOReactor.class);
+        final ConnectingIOReactor ioreactor = Mockito.mock(ConnectingIOReactor.class);
         Mockito.when(ioreactor.connect(
                 Mockito.any(SocketAddress.class), Mockito.any(SocketAddress.class),
                 Mockito.any(), Mockito.any(SessionRequestCallback.class))).
                 thenReturn(sessionRequest1, sessionRequest2);
 
-        LocalSessionPool pool = new LocalSessionPool(ioreactor, 2, 2);
+        final LocalSessionPool pool = new LocalSessionPool(ioreactor, 2, 2);
 
-        Future<LocalPoolEntry> future1 = pool.lease("somehost", null);
-        Future<LocalPoolEntry> future2 = pool.lease("somehost", null);
+        final Future<LocalPoolEntry> future1 = pool.lease("somehost", null);
+        final Future<LocalPoolEntry> future2 = pool.lease("somehost", null);
 
         pool.requestCompleted(sessionRequest1);
         pool.requestCompleted(sessionRequest2);
 
         Assert.assertTrue(future1.isDone());
-        LocalPoolEntry entry1 = future1.get();
+        final LocalPoolEntry entry1 = future1.get();
         Assert.assertNotNull(entry1);
         Assert.assertTrue(future2.isDone());
-        LocalPoolEntry entry2 = future2.get();
+        final LocalPoolEntry entry2 = future2.get();
         Assert.assertNotNull(entry2);
 
         entry1.updateExpiry(1, TimeUnit.MILLISECONDS);
@@ -802,11 +839,11 @@ public class TestNIOConnPool {
         Mockito.verify(iosession1).close();
         Mockito.verify(iosession2, Mockito.never()).close();
 
-        PoolStats totals = pool.getTotalStats();
+        final PoolStats totals = pool.getTotalStats();
         Assert.assertEquals(1, totals.getAvailable());
         Assert.assertEquals(0, totals.getLeased());
         Assert.assertEquals(0, totals.getPending());
-        PoolStats stats = pool.getStats("somehost");
+        final PoolStats stats = pool.getStats("somehost");
         Assert.assertEquals(1, stats.getAvailable());
         Assert.assertEquals(0, stats.getLeased());
         Assert.assertEquals(0, stats.getPending());
@@ -814,35 +851,35 @@ public class TestNIOConnPool {
 
     @Test
     public void testCloseIdle() throws Exception {
-        IOSession iosession1 = Mockito.mock(IOSession.class);
-        SessionRequest sessionRequest1 = Mockito.mock(SessionRequest.class);
+        final IOSession iosession1 = Mockito.mock(IOSession.class);
+        final SessionRequest sessionRequest1 = Mockito.mock(SessionRequest.class);
         Mockito.when(sessionRequest1.getAttachment()).thenReturn("somehost");
         Mockito.when(sessionRequest1.getSession()).thenReturn(iosession1);
 
-        IOSession iosession2 = Mockito.mock(IOSession.class);
-        SessionRequest sessionRequest2 = Mockito.mock(SessionRequest.class);
+        final IOSession iosession2 = Mockito.mock(IOSession.class);
+        final SessionRequest sessionRequest2 = Mockito.mock(SessionRequest.class);
         Mockito.when(sessionRequest2.getAttachment()).thenReturn("somehost");
         Mockito.when(sessionRequest2.getSession()).thenReturn(iosession2);
 
-        ConnectingIOReactor ioreactor = Mockito.mock(ConnectingIOReactor.class);
+        final ConnectingIOReactor ioreactor = Mockito.mock(ConnectingIOReactor.class);
         Mockito.when(ioreactor.connect(
                 Mockito.any(SocketAddress.class), Mockito.any(SocketAddress.class),
                 Mockito.any(), Mockito.any(SessionRequestCallback.class))).
                 thenReturn(sessionRequest1, sessionRequest2);
 
-        LocalSessionPool pool = new LocalSessionPool(ioreactor, 2, 2);
+        final LocalSessionPool pool = new LocalSessionPool(ioreactor, 2, 2);
 
-        Future<LocalPoolEntry> future1 = pool.lease("somehost", null);
-        Future<LocalPoolEntry> future2 = pool.lease("somehost", null);
+        final Future<LocalPoolEntry> future1 = pool.lease("somehost", null);
+        final Future<LocalPoolEntry> future2 = pool.lease("somehost", null);
 
         pool.requestCompleted(sessionRequest1);
         pool.requestCompleted(sessionRequest2);
 
         Assert.assertTrue(future1.isDone());
-        LocalPoolEntry entry1 = future1.get();
+        final LocalPoolEntry entry1 = future1.get();
         Assert.assertNotNull(entry1);
         Assert.assertTrue(future2.isDone());
-        LocalPoolEntry entry2 = future2.get();
+        final LocalPoolEntry entry2 = future2.get();
         Assert.assertNotNull(entry2);
 
         entry1.updateExpiry(0, TimeUnit.MILLISECONDS);
@@ -883,28 +920,28 @@ public class TestNIOConnPool {
 
     @Test
     public void testLeaseRequestTimeout() throws Exception {
-        IOSession iosession1 = Mockito.mock(IOSession.class);
+        final IOSession iosession1 = Mockito.mock(IOSession.class);
         Mockito.when(iosession1.isClosed()).thenReturn(Boolean.TRUE);
-        SessionRequest sessionRequest1 = Mockito.mock(SessionRequest.class);
+        final SessionRequest sessionRequest1 = Mockito.mock(SessionRequest.class);
         Mockito.when(sessionRequest1.getAttachment()).thenReturn("somehost");
         Mockito.when(sessionRequest1.getSession()).thenReturn(iosession1);
 
-        ConnectingIOReactor ioreactor = Mockito.mock(ConnectingIOReactor.class);
+        final ConnectingIOReactor ioreactor = Mockito.mock(ConnectingIOReactor.class);
         Mockito.when(ioreactor.connect(
                 Mockito.any(SocketAddress.class), Mockito.any(SocketAddress.class),
                 Mockito.any(), Mockito.any(SessionRequestCallback.class))).
                 thenReturn(sessionRequest1);
 
-        LocalSessionPool pool = new LocalSessionPool(ioreactor, 1, 1);
+        final LocalSessionPool pool = new LocalSessionPool(ioreactor, 1, 1);
 
-        Future<LocalPoolEntry> future1 = pool.lease("somehost", null, 0, TimeUnit.MILLISECONDS, null);
-        Future<LocalPoolEntry> future2 = pool.lease("somehost", null, 0, TimeUnit.MILLISECONDS, null);
-        Future<LocalPoolEntry> future3 = pool.lease("somehost", null, 10, TimeUnit.MILLISECONDS, null);
+        final Future<LocalPoolEntry> future1 = pool.lease("somehost", null, 0, TimeUnit.MILLISECONDS, null);
+        final Future<LocalPoolEntry> future2 = pool.lease("somehost", null, 0, TimeUnit.MILLISECONDS, null);
+        final Future<LocalPoolEntry> future3 = pool.lease("somehost", null, 10, TimeUnit.MILLISECONDS, null);
 
         pool.requestCompleted(sessionRequest1);
 
         Assert.assertTrue(future1.isDone());
-        LocalPoolEntry entry1 = future1.get();
+        final LocalPoolEntry entry1 = future1.get();
         Assert.assertNotNull(entry1);
         Assert.assertFalse(future2.isDone());
         Assert.assertFalse(future3.isDone());
@@ -919,48 +956,48 @@ public class TestNIOConnPool {
 
     @Test(expected=IllegalArgumentException.class)
     public void testCloseIdleInvalid() throws Exception {
-        ConnectingIOReactor ioreactor = Mockito.mock(ConnectingIOReactor.class);
-        LocalSessionPool pool = new LocalSessionPool(ioreactor, 2, 2);
+        final ConnectingIOReactor ioreactor = Mockito.mock(ConnectingIOReactor.class);
+        final LocalSessionPool pool = new LocalSessionPool(ioreactor, 2, 2);
         pool.closeIdle(50, null);
     }
 
     @Test(expected=IllegalArgumentException.class)
     public void testGetStatsInvalid() throws Exception {
-        ConnectingIOReactor ioreactor = Mockito.mock(ConnectingIOReactor.class);
-        LocalSessionPool pool = new LocalSessionPool(ioreactor, 2, 2);
+        final ConnectingIOReactor ioreactor = Mockito.mock(ConnectingIOReactor.class);
+        final LocalSessionPool pool = new LocalSessionPool(ioreactor, 2, 2);
         pool.getStats(null);
     }
 
     @Test
     public void testSetMaxInvalid() throws Exception {
-        ConnectingIOReactor ioreactor = Mockito.mock(ConnectingIOReactor.class);
-        LocalSessionPool pool = new LocalSessionPool(ioreactor, 2, 2);
+        final ConnectingIOReactor ioreactor = Mockito.mock(ConnectingIOReactor.class);
+        final LocalSessionPool pool = new LocalSessionPool(ioreactor, 2, 2);
         try {
             pool.setMaxTotal(-1);
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException expected) {
+        } catch (final IllegalArgumentException expected) {
         }
         try {
             pool.setMaxPerRoute(null, 1);
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException expected) {
+        } catch (final IllegalArgumentException expected) {
         }
         try {
             pool.setMaxPerRoute("somehost", -1);
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException expected) {
+        } catch (final IllegalArgumentException expected) {
         }
         try {
             pool.setDefaultMaxPerRoute(-1);
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException expected) {
+        } catch (final IllegalArgumentException expected) {
         }
     }
 
     @Test
     public void testShutdown() throws Exception {
-        ConnectingIOReactor ioreactor = Mockito.mock(ConnectingIOReactor.class);
-        LocalSessionPool pool = new LocalSessionPool(ioreactor, 2, 2);
+        final ConnectingIOReactor ioreactor = Mockito.mock(ConnectingIOReactor.class);
+        final LocalSessionPool pool = new LocalSessionPool(ioreactor, 2, 2);
         pool.shutdown(1000);
         Mockito.verify(ioreactor, Mockito.times(1)).shutdown(1000);
         pool.shutdown(1000);
@@ -968,7 +1005,7 @@ public class TestNIOConnPool {
         try {
             pool.lease("somehost", null);
             Assert.fail("IllegalStateException should have been thrown");
-        } catch (IllegalStateException expected) {
+        } catch (final IllegalStateException expected) {
         }
         // Ignored if shut down
         pool.release(new LocalPoolEntry("somehost", Mockito.mock(IOSession.class)), true);
diff --git a/httpcore-nio/src/test/java/org/apache/http/nio/pool/TestRouteSpecificPool.java b/httpcore-nio/src/test/java/org/apache/http/nio/pool/TestRouteSpecificPool.java
index 7e9cba0..cc10378 100644
--- a/httpcore-nio/src/test/java/org/apache/http/nio/pool/TestRouteSpecificPool.java
+++ b/httpcore-nio/src/test/java/org/apache/http/nio/pool/TestRouteSpecificPool.java
@@ -30,12 +30,11 @@ import java.io.IOException;
 import java.net.SocketTimeoutException;
 import java.util.concurrent.ExecutionException;
 
-import junit.framework.Assert;
-
 import org.apache.http.concurrent.BasicFuture;
 import org.apache.http.nio.reactor.IOSession;
 import org.apache.http.nio.reactor.SessionRequest;
 import org.apache.http.pool.PoolEntry;
+import org.junit.Assert;
 import org.junit.Test;
 import org.mockito.Mockito;
 
@@ -74,7 +73,7 @@ public class TestRouteSpecificPool {
 
     @Test
     public void testEmptyPool() throws Exception {
-        LocalRoutePool pool = new LocalRoutePool();
+        final LocalRoutePool pool = new LocalRoutePool();
         Assert.assertEquals(0, pool.getAllocatedCount());
         Assert.assertEquals(0, pool.getAvailableCount());
         Assert.assertEquals(0, pool.getLeasedCount());
@@ -85,17 +84,17 @@ public class TestRouteSpecificPool {
 
     @Test
     public void testSuccessfulConnect() throws Exception {
-        LocalRoutePool pool = new LocalRoutePool();
-        IOSession session = Mockito.mock(IOSession.class);
-        SessionRequest sessionRequest = Mockito.mock(SessionRequest.class);
+        final LocalRoutePool pool = new LocalRoutePool();
+        final IOSession session = Mockito.mock(IOSession.class);
+        final SessionRequest sessionRequest = Mockito.mock(SessionRequest.class);
         Mockito.when(sessionRequest.getSession()).thenReturn(session);
-        BasicFuture<LocalPoolEntry> future = new BasicFuture<LocalPoolEntry>(null);
+        final BasicFuture<LocalPoolEntry> future = new BasicFuture<LocalPoolEntry>(null);
         pool.addPending(sessionRequest, future);
         Assert.assertEquals(1, pool.getAllocatedCount());
         Assert.assertEquals(0, pool.getAvailableCount());
         Assert.assertEquals(0, pool.getLeasedCount());
         Assert.assertEquals(1, pool.getPendingCount());
-        LocalPoolEntry entry = pool.createEntry(sessionRequest, session);
+        final LocalPoolEntry entry = pool.createEntry(sessionRequest, session);
         Assert.assertNotNull(entry);
         Assert.assertSame(session, entry.getConnection());
         Assert.assertFalse(future.isDone());
@@ -112,9 +111,9 @@ public class TestRouteSpecificPool {
 
     @Test
     public void testFailedConnect() throws Exception {
-        LocalRoutePool pool = new LocalRoutePool();
-        SessionRequest sessionRequest = Mockito.mock(SessionRequest.class);
-        BasicFuture<LocalPoolEntry> future = new BasicFuture<LocalPoolEntry>(null);
+        final LocalRoutePool pool = new LocalRoutePool();
+        final SessionRequest sessionRequest = Mockito.mock(SessionRequest.class);
+        final BasicFuture<LocalPoolEntry> future = new BasicFuture<LocalPoolEntry>(null);
         pool.addPending(sessionRequest, future);
         Assert.assertEquals(1, pool.getAllocatedCount());
         Assert.assertEquals(0, pool.getAvailableCount());
@@ -126,7 +125,7 @@ public class TestRouteSpecificPool {
         try {
             future.get();
             Assert.fail("ExecutionException should have been thrown");
-        } catch (ExecutionException ex) {
+        } catch (final ExecutionException ex) {
             Assert.assertTrue(ex.getCause() instanceof IOException);
         }
         Assert.assertEquals(0, pool.getAllocatedCount());
@@ -137,9 +136,9 @@ public class TestRouteSpecificPool {
 
     @Test
     public void testCancelledConnect() throws Exception {
-        LocalRoutePool pool = new LocalRoutePool();
-        SessionRequest sessionRequest = Mockito.mock(SessionRequest.class);
-        BasicFuture<LocalPoolEntry> future = new BasicFuture<LocalPoolEntry>(null);
+        final LocalRoutePool pool = new LocalRoutePool();
+        final SessionRequest sessionRequest = Mockito.mock(SessionRequest.class);
+        final BasicFuture<LocalPoolEntry> future = new BasicFuture<LocalPoolEntry>(null);
         pool.addPending(sessionRequest, future);
         Assert.assertEquals(1, pool.getAllocatedCount());
         Assert.assertEquals(0, pool.getAvailableCount());
@@ -157,9 +156,9 @@ public class TestRouteSpecificPool {
 
     @Test
     public void testConnectTimeout() throws Exception {
-        LocalRoutePool pool = new LocalRoutePool();
-        SessionRequest sessionRequest = Mockito.mock(SessionRequest.class);
-        BasicFuture<LocalPoolEntry> future = new BasicFuture<LocalPoolEntry>(null);
+        final LocalRoutePool pool = new LocalRoutePool();
+        final SessionRequest sessionRequest = Mockito.mock(SessionRequest.class);
+        final BasicFuture<LocalPoolEntry> future = new BasicFuture<LocalPoolEntry>(null);
         pool.addPending(sessionRequest, future);
         Assert.assertEquals(1, pool.getAllocatedCount());
         Assert.assertEquals(0, pool.getAvailableCount());
@@ -171,7 +170,7 @@ public class TestRouteSpecificPool {
         try {
             future.get();
             Assert.fail("ExecutionException should have been thrown");
-        } catch (ExecutionException ex) {
+        } catch (final ExecutionException ex) {
             Assert.assertTrue(ex.getCause() instanceof SocketTimeoutException);
         }
         Assert.assertEquals(0, pool.getAllocatedCount());
@@ -182,21 +181,21 @@ public class TestRouteSpecificPool {
 
     @Test
     public void testLeaseRelease() throws Exception {
-        LocalRoutePool pool = new LocalRoutePool();
-        IOSession session1 = Mockito.mock(IOSession.class);
-        SessionRequest sessionRequest1 = Mockito.mock(SessionRequest.class);
+        final LocalRoutePool pool = new LocalRoutePool();
+        final IOSession session1 = Mockito.mock(IOSession.class);
+        final SessionRequest sessionRequest1 = Mockito.mock(SessionRequest.class);
         Mockito.when(sessionRequest1.getSession()).thenReturn(session1);
-        BasicFuture<LocalPoolEntry> future1 = new BasicFuture<LocalPoolEntry>(null);
+        final BasicFuture<LocalPoolEntry> future1 = new BasicFuture<LocalPoolEntry>(null);
         pool.addPending(sessionRequest1, future1);
-        IOSession session2 = Mockito.mock(IOSession.class);
-        SessionRequest sessionRequest2 = Mockito.mock(SessionRequest.class);
+        final IOSession session2 = Mockito.mock(IOSession.class);
+        final SessionRequest sessionRequest2 = Mockito.mock(SessionRequest.class);
         Mockito.when(sessionRequest2.getSession()).thenReturn(session2);
-        BasicFuture<LocalPoolEntry> future2 = new BasicFuture<LocalPoolEntry>(null);
+        final BasicFuture<LocalPoolEntry> future2 = new BasicFuture<LocalPoolEntry>(null);
         pool.addPending(sessionRequest2, future2);
-        IOSession session3 = Mockito.mock(IOSession.class);
-        SessionRequest sessionRequest3 = Mockito.mock(SessionRequest.class);
+        final IOSession session3 = Mockito.mock(IOSession.class);
+        final SessionRequest sessionRequest3 = Mockito.mock(SessionRequest.class);
         Mockito.when(sessionRequest3.getSession()).thenReturn(session3);
-        BasicFuture<LocalPoolEntry> future3 = new BasicFuture<LocalPoolEntry>(null);
+        final BasicFuture<LocalPoolEntry> future3 = new BasicFuture<LocalPoolEntry>(null);
         pool.addPending(sessionRequest3, future3);
 
         Assert.assertEquals(3, pool.getAllocatedCount());
@@ -204,13 +203,13 @@ public class TestRouteSpecificPool {
         Assert.assertEquals(0, pool.getLeasedCount());
         Assert.assertEquals(3, pool.getPendingCount());
 
-        LocalPoolEntry entry1 = pool.createEntry(sessionRequest1, session1);
+        final LocalPoolEntry entry1 = pool.createEntry(sessionRequest1, session1);
         pool.completed(sessionRequest1, entry1);
         Assert.assertNotNull(entry1);
-        LocalPoolEntry entry2 = pool.createEntry(sessionRequest2, session2);
+        final LocalPoolEntry entry2 = pool.createEntry(sessionRequest2, session2);
         pool.completed(sessionRequest2, entry2);
         Assert.assertNotNull(entry2);
-        LocalPoolEntry entry3 = pool.createEntry(sessionRequest3, session3);
+        final LocalPoolEntry entry3 = pool.createEntry(sessionRequest3, session3);
         pool.completed(sessionRequest3, entry3);
         Assert.assertNotNull(entry3);
 
@@ -242,21 +241,21 @@ public class TestRouteSpecificPool {
 
     @Test
     public void testLeaseOrder() throws Exception {
-        LocalRoutePool pool = new LocalRoutePool();
-        IOSession session1 = Mockito.mock(IOSession.class);
-        SessionRequest sessionRequest1 = Mockito.mock(SessionRequest.class);
+        final LocalRoutePool pool = new LocalRoutePool();
+        final IOSession session1 = Mockito.mock(IOSession.class);
+        final SessionRequest sessionRequest1 = Mockito.mock(SessionRequest.class);
         Mockito.when(sessionRequest1.getSession()).thenReturn(session1);
-        BasicFuture<LocalPoolEntry> future1 = new BasicFuture<LocalPoolEntry>(null);
+        final BasicFuture<LocalPoolEntry> future1 = new BasicFuture<LocalPoolEntry>(null);
         pool.addPending(sessionRequest1, future1);
-        IOSession session2 = Mockito.mock(IOSession.class);
-        SessionRequest sessionRequest2 = Mockito.mock(SessionRequest.class);
+        final IOSession session2 = Mockito.mock(IOSession.class);
+        final SessionRequest sessionRequest2 = Mockito.mock(SessionRequest.class);
         Mockito.when(sessionRequest2.getSession()).thenReturn(session2);
-        BasicFuture<LocalPoolEntry> future2 = new BasicFuture<LocalPoolEntry>(null);
+        final BasicFuture<LocalPoolEntry> future2 = new BasicFuture<LocalPoolEntry>(null);
         pool.addPending(sessionRequest2, future2);
-        IOSession session3 = Mockito.mock(IOSession.class);
-        SessionRequest sessionRequest3 = Mockito.mock(SessionRequest.class);
+        final IOSession session3 = Mockito.mock(IOSession.class);
+        final SessionRequest sessionRequest3 = Mockito.mock(SessionRequest.class);
         Mockito.when(sessionRequest3.getSession()).thenReturn(session3);
-        BasicFuture<LocalPoolEntry> future3 = new BasicFuture<LocalPoolEntry>(null);
+        final BasicFuture<LocalPoolEntry> future3 = new BasicFuture<LocalPoolEntry>(null);
         pool.addPending(sessionRequest3, future3);
 
         Assert.assertEquals(3, pool.getAllocatedCount());
@@ -264,13 +263,13 @@ public class TestRouteSpecificPool {
         Assert.assertEquals(0, pool.getLeasedCount());
         Assert.assertEquals(3, pool.getPendingCount());
 
-        LocalPoolEntry entry1 = pool.createEntry(sessionRequest1, session1);
+        final LocalPoolEntry entry1 = pool.createEntry(sessionRequest1, session1);
         pool.completed(sessionRequest1, entry1);
         Assert.assertNotNull(entry1);
-        LocalPoolEntry entry2 = pool.createEntry(sessionRequest2, session2);
+        final LocalPoolEntry entry2 = pool.createEntry(sessionRequest2, session2);
         pool.completed(sessionRequest2, entry2);
         Assert.assertNotNull(entry2);
-        LocalPoolEntry entry3 = pool.createEntry(sessionRequest3, session3);
+        final LocalPoolEntry entry3 = pool.createEntry(sessionRequest3, session3);
         pool.completed(sessionRequest3, entry3);
         Assert.assertNotNull(entry3);
 
@@ -292,31 +291,31 @@ public class TestRouteSpecificPool {
 
     @Test
     public void testLeaseReleaseStateful() throws Exception {
-        LocalRoutePool pool = new LocalRoutePool();
+        final LocalRoutePool pool = new LocalRoutePool();
 
-        IOSession session1 = Mockito.mock(IOSession.class);
-        SessionRequest sessionRequest1 = Mockito.mock(SessionRequest.class);
+        final IOSession session1 = Mockito.mock(IOSession.class);
+        final SessionRequest sessionRequest1 = Mockito.mock(SessionRequest.class);
         Mockito.when(sessionRequest1.getSession()).thenReturn(session1);
-        BasicFuture<LocalPoolEntry> future1 = new BasicFuture<LocalPoolEntry>(null);
+        final BasicFuture<LocalPoolEntry> future1 = new BasicFuture<LocalPoolEntry>(null);
         pool.addPending(sessionRequest1, future1);
-        IOSession session2 = Mockito.mock(IOSession.class);
-        SessionRequest sessionRequest2 = Mockito.mock(SessionRequest.class);
+        final IOSession session2 = Mockito.mock(IOSession.class);
+        final SessionRequest sessionRequest2 = Mockito.mock(SessionRequest.class);
         Mockito.when(sessionRequest2.getSession()).thenReturn(session2);
-        BasicFuture<LocalPoolEntry> future2 = new BasicFuture<LocalPoolEntry>(null);
+        final BasicFuture<LocalPoolEntry> future2 = new BasicFuture<LocalPoolEntry>(null);
         pool.addPending(sessionRequest2, future2);
-        IOSession session3 = Mockito.mock(IOSession.class);
-        SessionRequest sessionRequest3 = Mockito.mock(SessionRequest.class);
+        final IOSession session3 = Mockito.mock(IOSession.class);
+        final SessionRequest sessionRequest3 = Mockito.mock(SessionRequest.class);
         Mockito.when(sessionRequest3.getSession()).thenReturn(session3);
-        BasicFuture<LocalPoolEntry> future3 = new BasicFuture<LocalPoolEntry>(null);
+        final BasicFuture<LocalPoolEntry> future3 = new BasicFuture<LocalPoolEntry>(null);
         pool.addPending(sessionRequest3, future3);
 
-        LocalPoolEntry entry1 = pool.createEntry(sessionRequest1, session1);
+        final LocalPoolEntry entry1 = pool.createEntry(sessionRequest1, session1);
         pool.completed(sessionRequest1, entry1);
         Assert.assertNotNull(entry1);
-        LocalPoolEntry entry2 = pool.createEntry(sessionRequest2, session2);
+        final LocalPoolEntry entry2 = pool.createEntry(sessionRequest2, session2);
         pool.completed(sessionRequest2, entry2);
         Assert.assertNotNull(entry2);
-        LocalPoolEntry entry3 = pool.createEntry(sessionRequest3, session3);
+        final LocalPoolEntry entry3 = pool.createEntry(sessionRequest3, session3);
         pool.completed(sessionRequest3, entry3);
         Assert.assertNotNull(entry3);
 
@@ -347,29 +346,29 @@ public class TestRouteSpecificPool {
 
     @Test(expected=IllegalStateException.class)
     public void testReleaseInvalidEntry() throws Exception {
-        LocalRoutePool pool = new LocalRoutePool();
-        IOSession session = Mockito.mock(IOSession.class);
-        LocalPoolEntry entry = new LocalPoolEntry("whatever", session);
+        final LocalRoutePool pool = new LocalRoutePool();
+        final IOSession session = Mockito.mock(IOSession.class);
+        final LocalPoolEntry entry = new LocalPoolEntry("whatever", session);
         pool.free(entry, true);
     }
 
     @Test
     public void testRemove() throws Exception {
-        LocalRoutePool pool = new LocalRoutePool();
-        IOSession session1 = Mockito.mock(IOSession.class);
-        SessionRequest sessionRequest1 = Mockito.mock(SessionRequest.class);
+        final LocalRoutePool pool = new LocalRoutePool();
+        final IOSession session1 = Mockito.mock(IOSession.class);
+        final SessionRequest sessionRequest1 = Mockito.mock(SessionRequest.class);
         Mockito.when(sessionRequest1.getSession()).thenReturn(session1);
-        BasicFuture<LocalPoolEntry> future1 = new BasicFuture<LocalPoolEntry>(null);
+        final BasicFuture<LocalPoolEntry> future1 = new BasicFuture<LocalPoolEntry>(null);
         pool.addPending(sessionRequest1, future1);
-        IOSession session2 = Mockito.mock(IOSession.class);
-        SessionRequest sessionRequest2 = Mockito.mock(SessionRequest.class);
+        final IOSession session2 = Mockito.mock(IOSession.class);
+        final SessionRequest sessionRequest2 = Mockito.mock(SessionRequest.class);
         Mockito.when(sessionRequest2.getSession()).thenReturn(session2);
-        BasicFuture<LocalPoolEntry> future2 = new BasicFuture<LocalPoolEntry>(null);
+        final BasicFuture<LocalPoolEntry> future2 = new BasicFuture<LocalPoolEntry>(null);
         pool.addPending(sessionRequest2, future2);
-        IOSession session3 = Mockito.mock(IOSession.class);
-        SessionRequest sessionRequest3 = Mockito.mock(SessionRequest.class);
+        final IOSession session3 = Mockito.mock(IOSession.class);
+        final SessionRequest sessionRequest3 = Mockito.mock(SessionRequest.class);
         Mockito.when(sessionRequest3.getSession()).thenReturn(session3);
-        BasicFuture<LocalPoolEntry> future3 = new BasicFuture<LocalPoolEntry>(null);
+        final BasicFuture<LocalPoolEntry> future3 = new BasicFuture<LocalPoolEntry>(null);
         pool.addPending(sessionRequest3, future3);
 
         Assert.assertEquals(3, pool.getAllocatedCount());
@@ -377,13 +376,13 @@ public class TestRouteSpecificPool {
         Assert.assertEquals(0, pool.getLeasedCount());
         Assert.assertEquals(3, pool.getPendingCount());
 
-        LocalPoolEntry entry1 = pool.createEntry(sessionRequest1, session1);
+        final LocalPoolEntry entry1 = pool.createEntry(sessionRequest1, session1);
         pool.completed(sessionRequest1, entry1);
         Assert.assertNotNull(entry1);
-        LocalPoolEntry entry2 = pool.createEntry(sessionRequest2, session2);
+        final LocalPoolEntry entry2 = pool.createEntry(sessionRequest2, session2);
         pool.completed(sessionRequest2, entry2);
         Assert.assertNotNull(entry2);
-        LocalPoolEntry entry3 = pool.createEntry(sessionRequest3, session3);
+        final LocalPoolEntry entry3 = pool.createEntry(sessionRequest3, session3);
         pool.completed(sessionRequest3, entry3);
         Assert.assertNotNull(entry3);
 
@@ -419,39 +418,39 @@ public class TestRouteSpecificPool {
 
     @Test(expected=IllegalArgumentException.class)
     public void testReleaseInvalid() throws Exception {
-        LocalRoutePool pool = new LocalRoutePool();
+        final LocalRoutePool pool = new LocalRoutePool();
         pool.free(null, true);
     }
 
     @Test(expected=IllegalArgumentException.class)
     public void testRemoveInvalid() throws Exception {
-        LocalRoutePool pool = new LocalRoutePool();
+        final LocalRoutePool pool = new LocalRoutePool();
         pool.remove(null);
     }
 
     @Test
     public void testShutdown() throws Exception {
-        LocalRoutePool pool = new LocalRoutePool();
-        IOSession session1 = Mockito.mock(IOSession.class);
-        SessionRequest sessionRequest1 = Mockito.mock(SessionRequest.class);
+        final LocalRoutePool pool = new LocalRoutePool();
+        final IOSession session1 = Mockito.mock(IOSession.class);
+        final SessionRequest sessionRequest1 = Mockito.mock(SessionRequest.class);
         Mockito.when(sessionRequest1.getSession()).thenReturn(session1);
-        BasicFuture<LocalPoolEntry> future1 = new BasicFuture<LocalPoolEntry>(null);
+        final BasicFuture<LocalPoolEntry> future1 = new BasicFuture<LocalPoolEntry>(null);
         pool.addPending(sessionRequest1, future1);
-        IOSession session2 = Mockito.mock(IOSession.class);
-        SessionRequest sessionRequest2 = Mockito.mock(SessionRequest.class);
+        final IOSession session2 = Mockito.mock(IOSession.class);
+        final SessionRequest sessionRequest2 = Mockito.mock(SessionRequest.class);
         Mockito.when(sessionRequest2.getSession()).thenReturn(session2);
-        BasicFuture<LocalPoolEntry> future2 = new BasicFuture<LocalPoolEntry>(null);
+        final BasicFuture<LocalPoolEntry> future2 = new BasicFuture<LocalPoolEntry>(null);
         pool.addPending(sessionRequest2, future2);
-        IOSession session3 = Mockito.mock(IOSession.class);
-        SessionRequest sessionRequest3 = Mockito.mock(SessionRequest.class);
+        final IOSession session3 = Mockito.mock(IOSession.class);
+        final SessionRequest sessionRequest3 = Mockito.mock(SessionRequest.class);
         Mockito.when(sessionRequest3.getSession()).thenReturn(session3);
-        BasicFuture<LocalPoolEntry> future3 = new BasicFuture<LocalPoolEntry>(null);
+        final BasicFuture<LocalPoolEntry> future3 = new BasicFuture<LocalPoolEntry>(null);
         pool.addPending(sessionRequest3, future3);
 
-        LocalPoolEntry entry1 = pool.createEntry(sessionRequest1, session1);
+        final LocalPoolEntry entry1 = pool.createEntry(sessionRequest1, session1);
         pool.completed(sessionRequest1, entry1);
         Assert.assertNotNull(entry1);
-        LocalPoolEntry entry2 = pool.createEntry(sessionRequest2, session2);
+        final LocalPoolEntry entry2 = pool.createEntry(sessionRequest2, session2);
         pool.completed(sessionRequest2, entry2);
         Assert.assertNotNull(entry2);
 
diff --git a/httpcore-nio/src/test/java/org/apache/http/nio/protocol/TestBasicAsyncRequestExecutionHandler.java b/httpcore-nio/src/test/java/org/apache/http/nio/protocol/TestBasicAsyncClientExchangeHandler.java
similarity index 71%
rename from httpcore-nio/src/test/java/org/apache/http/nio/protocol/TestBasicAsyncRequestExecutionHandler.java
rename to httpcore-nio/src/test/java/org/apache/http/nio/protocol/TestBasicAsyncClientExchangeHandler.java
index 7421892..cae9430 100644
--- a/httpcore-nio/src/test/java/org/apache/http/nio/protocol/TestBasicAsyncRequestExecutionHandler.java
+++ b/httpcore-nio/src/test/java/org/apache/http/nio/protocol/TestBasicAsyncClientExchangeHandler.java
@@ -31,8 +31,8 @@ import java.util.concurrent.ExecutionException;
 
 import junit.framework.Assert;
 
+import org.apache.http.ConnectionClosedException;
 import org.apache.http.ConnectionReuseStrategy;
-import org.apache.http.HttpHost;
 import org.apache.http.HttpRequest;
 import org.apache.http.HttpVersion;
 import org.apache.http.message.BasicHttpRequest;
@@ -40,17 +40,16 @@ import org.apache.http.message.BasicHttpResponse;
 import org.apache.http.nio.ContentDecoder;
 import org.apache.http.nio.ContentEncoder;
 import org.apache.http.nio.NHttpClientConnection;
-import org.apache.http.params.BasicHttpParams;
-import org.apache.http.params.HttpParams;
 import org.apache.http.protocol.BasicHttpContext;
 import org.apache.http.protocol.HttpContext;
+import org.apache.http.protocol.HttpCoreContext;
 import org.apache.http.protocol.HttpProcessor;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.mockito.Mockito;
 
-public class TestBasicAsyncRequestExecutionHandler {
+public class TestBasicAsyncClientExchangeHandler {
 
     private HttpAsyncRequestProducer requestProducer;
     private HttpAsyncResponseConsumer<Object> responseConsumer;
@@ -58,8 +57,7 @@ public class TestBasicAsyncRequestExecutionHandler {
     private HttpProcessor httpProcessor;
     private NHttpClientConnection conn;
     private ConnectionReuseStrategy reuseStrategy;
-    private HttpParams params;
-    private BasicAsyncRequestExecutionHandler<Object> exchangeHandler;
+    private BasicAsyncClientExchangeHandler<Object> exchangeHandler;
     private ContentEncoder encoder;
     private ContentDecoder decoder;
 
@@ -69,16 +67,17 @@ public class TestBasicAsyncRequestExecutionHandler {
         this.requestProducer = Mockito.mock(HttpAsyncRequestProducer.class);
         this.responseConsumer = Mockito.mock(HttpAsyncResponseConsumer.class);
         this.context = new BasicHttpContext();
+        this.conn = Mockito.mock(NHttpClientConnection.class);
         this.httpProcessor = Mockito.mock(HttpProcessor.class);
         this.reuseStrategy = Mockito.mock(ConnectionReuseStrategy.class);
-        this.params = new BasicHttpParams();
-        this.exchangeHandler = new BasicAsyncRequestExecutionHandler<Object>(
+        this.exchangeHandler = new BasicAsyncClientExchangeHandler<Object>(
                 this.requestProducer,
                 this.responseConsumer,
+                null,
                 this.context,
+                this.conn,
                 this.httpProcessor,
-                this.reuseStrategy,
-                this.params);
+                this.reuseStrategy);
         this.encoder = Mockito.mock(ContentEncoder.class);
         this.decoder = Mockito.mock(ContentDecoder.class);
     }
@@ -90,70 +89,64 @@ public class TestBasicAsyncRequestExecutionHandler {
     @Test
     public void testInvalidExecution() throws Exception {
         try {
-            new BasicAsyncRequestExecutionHandler<Object>(
+            new BasicAsyncClientExchangeHandler<Object>(
                     null,
                     this.responseConsumer,
+                    null,
                     this.context,
+                    this.conn,
                     this.httpProcessor,
-                    this.reuseStrategy,
-                    this.params);
+                    this.reuseStrategy);
             Assert.fail("IllegalArgumentException expected");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
         }
         try {
-            new BasicAsyncRequestExecutionHandler<Object>(
+            new BasicAsyncClientExchangeHandler<Object>(
                     this.requestProducer,
                     null,
+                    null,
                     this.context,
+                    this.conn,
                     this.httpProcessor,
-                    this.reuseStrategy,
-                    this.params);
+                    this.reuseStrategy);
             Assert.fail("IllegalArgumentException expected");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
         }
         try {
-            new BasicAsyncRequestExecutionHandler<Object>(
+            new BasicAsyncClientExchangeHandler<Object>(
                     this.requestProducer,
                     this.responseConsumer,
                     null,
+                    null,
+                    this.conn,
                     this.httpProcessor,
-                    this.reuseStrategy,
-                    this.params);
+                    this.reuseStrategy);
             Assert.fail("IllegalArgumentException expected");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
         }
         try {
-            new BasicAsyncRequestExecutionHandler<Object>(
+            new BasicAsyncClientExchangeHandler<Object>(
                     this.requestProducer,
                     this.responseConsumer,
-                    this.context,
                     null,
-                    this.reuseStrategy,
-                    this.params);
-            Assert.fail("IllegalArgumentException expected");
-        } catch (IllegalArgumentException ex) {
-        }
-        try {
-            new BasicAsyncRequestExecutionHandler<Object>(
-                    this.requestProducer,
-                    this.responseConsumer,
                     this.context,
-                    this.httpProcessor,
                     null,
-                    this.params);
+                    this.httpProcessor,
+                    this.reuseStrategy);
             Assert.fail("IllegalArgumentException expected");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
         }
         try {
-            new BasicAsyncRequestExecutionHandler<Object>(
+            new BasicAsyncClientExchangeHandler<Object>(
                     this.requestProducer,
                     this.responseConsumer,
+                    null,
                     this.context,
-                    this.httpProcessor,
-                    this.reuseStrategy,
-                    null);
+                    this.conn,
+                    null,
+                    this.reuseStrategy);
             Assert.fail("IllegalArgumentException expected");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
         }
     }
 
@@ -167,22 +160,18 @@ public class TestBasicAsyncRequestExecutionHandler {
     }
 
     @Test
-    public void testGetTarget() throws Exception {
-        HttpHost target = new HttpHost("somehost");
-        Mockito.when(this.requestProducer.getTarget()).thenReturn(target);
-        Assert.assertSame(target, this.exchangeHandler.getTarget());
-    }
-
-    @Test
     public void testGenerateRequest() throws Exception {
-        BasicHttpRequest request = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1);
+        final BasicHttpRequest request = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1);
         Mockito.when(this.requestProducer.generateRequest()).thenReturn(request);
 
-        HttpRequest result = this.exchangeHandler.generateRequest();
+        final HttpRequest result = this.exchangeHandler.generateRequest();
 
         Assert.assertSame(request, result);
 
         Mockito.verify(this.requestProducer).generateRequest();
+        Assert.assertSame(request, this.context.getAttribute(HttpCoreContext.HTTP_REQUEST));
+        Assert.assertSame(this.conn, this.context.getAttribute(HttpCoreContext.HTTP_CONNECTION));
+        Mockito.verify(this.httpProcessor).process(request, this.context);
     }
 
     @Test
@@ -205,18 +194,20 @@ public class TestBasicAsyncRequestExecutionHandler {
 
     @Test
     public void testRequestCompleted() throws Exception {
-        this.exchangeHandler.requestCompleted(this.context);
+        this.exchangeHandler.requestCompleted();
 
         Mockito.verify(this.requestProducer).requestCompleted(this.context);
     }
 
     @Test
     public void testResponseReceived() throws Exception {
-        BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
+        final BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
 
         this.exchangeHandler.responseReceived(response);
 
         Mockito.verify(this.responseConsumer).responseReceived(response);
+        Assert.assertSame(response, this.context.getAttribute(HttpCoreContext.HTTP_RESPONSE));
+        Mockito.verify(this.httpProcessor).process(response, this.context);
     }
 
     @Test
@@ -228,7 +219,7 @@ public class TestBasicAsyncRequestExecutionHandler {
 
     @Test
     public void testFailed() throws Exception {
-        Exception ooopsie = new Exception();
+        final Exception ooopsie = new Exception();
         this.exchangeHandler.failed(ooopsie);
 
         Mockito.verify(this.requestProducer).failed(ooopsie);
@@ -237,15 +228,15 @@ public class TestBasicAsyncRequestExecutionHandler {
         Mockito.verify(this.responseConsumer).close();
         try {
             this.exchangeHandler.getFuture().get();
-        } catch (ExecutionException ex) {
+        } catch (final ExecutionException ex) {
             Assert.assertSame(ooopsie, ex.getCause());
         }
     }
 
     @Test
     public void testFailedAfterRequest() throws Exception {
-        Exception ooopsie = new Exception();
-        this.exchangeHandler.requestCompleted(this.context);
+        final Exception ooopsie = new Exception();
+        this.exchangeHandler.requestCompleted();
         this.exchangeHandler.failed(ooopsie);
 
         Mockito.verify(this.requestProducer, Mockito.never()).failed(ooopsie);
@@ -254,24 +245,24 @@ public class TestBasicAsyncRequestExecutionHandler {
         Mockito.verify(this.responseConsumer).close();
         try {
             this.exchangeHandler.getFuture().get();
-        } catch (ExecutionException ex) {
+        } catch (final ExecutionException ex) {
             Assert.assertSame(ooopsie, ex.getCause());
         }
     }
 
     @Test
     public void testFailedwithException() throws Exception {
-        Exception ooopsie = new Exception();
+        final Exception ooopsie = new Exception();
         Mockito.doThrow(new RuntimeException()).when(this.responseConsumer).failed(ooopsie);
         try {
             this.exchangeHandler.failed(ooopsie);
             Assert.fail("RuntimeException expected");
-        } catch (RuntimeException ex) {
+        } catch (final RuntimeException ex) {
             Mockito.verify(this.requestProducer).close();
             Mockito.verify(this.responseConsumer).close();
             try {
                 this.exchangeHandler.getFuture().get();
-            } catch (ExecutionException exex) {
+            } catch (final ExecutionException exex) {
                 Assert.assertSame(ooopsie, exex.getCause());
             }
         }
@@ -293,44 +284,44 @@ public class TestBasicAsyncRequestExecutionHandler {
         try {
             this.exchangeHandler.cancel();
             Assert.fail("RuntimeException expected");
-        } catch (RuntimeException ex) {
+        } catch (final RuntimeException ex) {
             Mockito.verify(this.requestProducer).close();
             Mockito.verify(this.responseConsumer).close();
             try {
                 this.exchangeHandler.getFuture().get();
                 Assert.fail("ExecutionException expected");
-            } catch (ExecutionException exex) {
+            } catch (final ExecutionException exex) {
             }
         }
     }
 
     @Test
     public void testResponseCompleted() throws Exception {
-        Object obj = new Object();
+        final Object obj = new Object();
         Mockito.when(this.responseConsumer.getResult()).thenReturn(obj);
 
-        this.exchangeHandler.responseCompleted(this.context);
+        this.exchangeHandler.responseCompleted();
 
         Mockito.verify(this.responseConsumer).responseCompleted(this.context);
         Mockito.verify(this.requestProducer).close();
         Mockito.verify(this.responseConsumer).close();
-        Object result = this.exchangeHandler.getFuture().get();
+        final Object result = this.exchangeHandler.getFuture().get();
         Assert.assertSame(obj, result);
     }
 
     @Test
     public void testResponseFailure() throws Exception {
-        Exception ooopsie = new Exception();
+        final Exception ooopsie = new Exception();
         Mockito.when(this.responseConsumer.getException()).thenReturn(ooopsie);
 
-        this.exchangeHandler.responseCompleted(this.context);
+        this.exchangeHandler.responseCompleted();
 
         Mockito.verify(this.responseConsumer).responseCompleted(this.context);
         Mockito.verify(this.requestProducer).close();
         Mockito.verify(this.responseConsumer).close();
         try {
             this.exchangeHandler.getFuture().get();
-        } catch (ExecutionException exex) {
+        } catch (final ExecutionException exex) {
             Assert.assertSame(ooopsie, exex.getCause());
         }
     }
@@ -339,41 +330,49 @@ public class TestBasicAsyncRequestExecutionHandler {
     public void testResponseCompletedWithException() throws Exception {
         Mockito.doThrow(new RuntimeException()).when(this.responseConsumer).responseCompleted(this.context);
         try {
-            this.exchangeHandler.responseCompleted(this.context);
+            this.exchangeHandler.responseCompleted();
             Assert.fail("RuntimeException expected");
-        } catch (RuntimeException ex) {
+        } catch (final RuntimeException ex) {
             Mockito.verify(this.requestProducer).close();
             Mockito.verify(this.responseConsumer).close();
             try {
                 this.exchangeHandler.getFuture().get();
                 Assert.fail("ExecutionException expected");
-            } catch (ExecutionException exex) {
+            } catch (final ExecutionException exex) {
             }
         }
     }
 
     @Test
-    public void testMisc() throws Exception {
-        Assert.assertFalse(this.exchangeHandler.isRepeatable());
-        Object obj = new Object();
+    public void testResponseNoKeepAlive() throws Exception {
+        final Object obj = new Object();
         Mockito.when(this.responseConsumer.getResult()).thenReturn(obj);
 
-        Object result = this.exchangeHandler.getResult();
-        Assert.assertSame(obj, result);
-        Mockito.verify(this.responseConsumer).getResult();
+        final BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
 
-        Exception ooopsie = new Exception();
-        Mockito.when(this.responseConsumer.getException()).thenReturn(ooopsie);
+        Mockito.when(reuseStrategy.keepAlive(response, this.context)).thenReturn(Boolean.FALSE);
 
-        Exception ex = this.exchangeHandler.getException();
-        Assert.assertSame(ooopsie, ex);
-        Mockito.verify(this.responseConsumer).getException();
+        this.exchangeHandler.responseReceived(response);
+        this.exchangeHandler.responseCompleted();
+
+        Mockito.verify(this.conn).close();
+    }
 
+    @Test
+    public void testInputTerminated() throws Exception {
+        this.exchangeHandler.inputTerminated();
+        Mockito.verify(this.responseConsumer).failed(Mockito.<ConnectionClosedException>any());
+        try {
+            this.exchangeHandler.getFuture().get();
+            Assert.fail("ExecutionException expected");
+        } catch (final ExecutionException exex) {
+        }
+    }
+
+    @Test
+    public void testIsDone() throws Exception {
         this.exchangeHandler.isDone();
         Mockito.verify(this.responseConsumer).isDone();
-
-        Assert.assertSame(this.context, this.exchangeHandler.getContext());
-        Assert.assertSame(this.reuseStrategy, this.exchangeHandler.getConnectionReuseStrategy());
     }
 
 }
diff --git a/httpcore-nio/src/test/java/org/apache/http/nio/protocol/TestBasicAsyncRequestConsumer.java b/httpcore-nio/src/test/java/org/apache/http/nio/protocol/TestBasicAsyncRequestConsumer.java
index a2ab689..2d2bd68 100644
--- a/httpcore-nio/src/test/java/org/apache/http/nio/protocol/TestBasicAsyncRequestConsumer.java
+++ b/httpcore-nio/src/test/java/org/apache/http/nio/protocol/TestBasicAsyncRequestConsumer.java
@@ -30,7 +30,6 @@ package org.apache.http.nio.protocol;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
-import junit.framework.Assert;
 
 import org.apache.http.HttpEntityEnclosingRequest;
 import org.apache.http.entity.StringEntity;
@@ -38,6 +37,7 @@ import org.apache.http.nio.ContentDecoder;
 import org.apache.http.nio.IOControl;
 import org.apache.http.protocol.HttpContext;
 import org.junit.After;
+import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
 import org.mockito.Mock;
@@ -84,7 +84,7 @@ public class TestBasicAsyncRequestConsumer {
     @Test
     public void testResponseProcessingWithException() throws Exception {
         when(request.getEntity()).thenReturn(new StringEntity("stuff"));
-        RuntimeException ooopsie = new RuntimeException();
+        final RuntimeException ooopsie = new RuntimeException();
         when(consumer.buildResult(context)).thenThrow(ooopsie);
 
         consumer.requestReceived(request);
diff --git a/httpcore-nio/src/test/java/org/apache/http/nio/protocol/TestBasicAsyncRequestHandler.java b/httpcore-nio/src/test/java/org/apache/http/nio/protocol/TestBasicAsyncRequestHandler.java
index 2da0380..866d989 100644
--- a/httpcore-nio/src/test/java/org/apache/http/nio/protocol/TestBasicAsyncRequestHandler.java
+++ b/httpcore-nio/src/test/java/org/apache/http/nio/protocol/TestBasicAsyncRequestHandler.java
@@ -27,8 +27,6 @@
 
 package org.apache.http.nio.protocol;
 
-import junit.framework.Assert;
-
 import org.apache.http.HttpRequest;
 import org.apache.http.HttpResponse;
 import org.apache.http.HttpVersion;
@@ -37,6 +35,7 @@ import org.apache.http.protocol.BasicHttpContext;
 import org.apache.http.protocol.HttpContext;
 import org.apache.http.protocol.HttpRequestHandler;
 import org.junit.After;
+import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
 import org.mockito.Mockito;
@@ -72,13 +71,13 @@ public class TestBasicAsyncRequestHandler {
         try {
             new BasicAsyncRequestHandler(null);
             Assert.fail("IllegalArgumentException expected");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
         }
     }
 
     @Test
     public void testProcessRequest() throws Exception {
-        HttpAsyncRequestConsumer<HttpRequest> requestConsumer = this.asyncRequestHandler.processRequest(
+        final HttpAsyncRequestConsumer<HttpRequest> requestConsumer = this.asyncRequestHandler.processRequest(
                 this.request, this.context);
         Assert.assertTrue(requestConsumer instanceof BasicAsyncRequestConsumer);
     }
diff --git a/httpcore-nio/src/test/java/org/apache/http/nio/protocol/TestBasicAsyncRequestProducer.java b/httpcore-nio/src/test/java/org/apache/http/nio/protocol/TestBasicAsyncRequestProducer.java
index 5e600d3..a0359ed 100644
--- a/httpcore-nio/src/test/java/org/apache/http/nio/protocol/TestBasicAsyncRequestProducer.java
+++ b/httpcore-nio/src/test/java/org/apache/http/nio/protocol/TestBasicAsyncRequestProducer.java
@@ -30,7 +30,6 @@ package org.apache.http.nio.protocol;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
-import junit.framework.Assert;
 
 import org.apache.http.HttpEntityEnclosingRequest;
 import org.apache.http.HttpHost;
@@ -38,6 +37,7 @@ import org.apache.http.HttpRequest;
 import org.apache.http.nio.ContentEncoder;
 import org.apache.http.nio.entity.HttpAsyncContentProducer;
 import org.junit.After;
+import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
 import org.mockito.Mock;
@@ -84,30 +84,32 @@ public class TestBasicAsyncRequestProducer {
 
     @Test
     public void testGenerateRequest() {
-        HttpRequest res = producer.generateRequest();
+        final HttpRequest res = producer.generateRequest();
 
         Assert.assertSame(request, res);
     }
 
     @Test
     public void testGetTarget() {
-        HttpHost res = producer.getTarget();
+        final HttpHost res = producer.getTarget();
 
         Assert.assertSame(target, res);
     }
 
+    @SuppressWarnings("boxing")
     @Test
     public void testProduceContentEncoderCompleted() throws Exception {
-        when(encoder.isCompleted()).thenReturn(true);
+        when(encoder.isCompleted()).thenReturn(Boolean.TRUE);
 
         producer.produceContent(encoder,  null);
 
         verify(contentProducer, times(1)).close();
     }
 
+    @SuppressWarnings("boxing")
     @Test
     public void testProduceContentEncoderNotCompleted() throws Exception {
-        when(encoder.isCompleted()).thenReturn(false);
+        when(encoder.isCompleted()).thenReturn(Boolean.FALSE);
 
         producer.produceContent(encoder,  null);
 
diff --git a/httpcore-nio/src/test/java/org/apache/http/nio/protocol/TestBasicAsyncResponseConsumer.java b/httpcore-nio/src/test/java/org/apache/http/nio/protocol/TestBasicAsyncResponseConsumer.java
index 1d0a000..959dd20 100644
--- a/httpcore-nio/src/test/java/org/apache/http/nio/protocol/TestBasicAsyncResponseConsumer.java
+++ b/httpcore-nio/src/test/java/org/apache/http/nio/protocol/TestBasicAsyncResponseConsumer.java
@@ -30,7 +30,6 @@ package org.apache.http.nio.protocol;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
-import junit.framework.Assert;
 
 import org.apache.http.HttpResponse;
 import org.apache.http.entity.StringEntity;
@@ -38,6 +37,7 @@ import org.apache.http.nio.ContentDecoder;
 import org.apache.http.nio.IOControl;
 import org.apache.http.protocol.HttpContext;
 import org.junit.After;
+import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
 import org.mockito.Mock;
@@ -84,7 +84,7 @@ public class TestBasicAsyncResponseConsumer {
     @Test
     public void testResponseProcessingWithException() throws Exception {
         when(response.getEntity()).thenReturn(new StringEntity("stuff"));
-        RuntimeException ooopsie = new RuntimeException();
+        final RuntimeException ooopsie = new RuntimeException();
         when(consumer.buildResult(context)).thenThrow(ooopsie);
 
         consumer.responseReceived(response);
@@ -109,7 +109,7 @@ public class TestBasicAsyncResponseConsumer {
 
     @Test
     public void testFailed() throws Exception {
-        RuntimeException ooopsie = new RuntimeException();
+        final RuntimeException ooopsie = new RuntimeException();
 
         consumer.failed(ooopsie);
 
@@ -120,7 +120,7 @@ public class TestBasicAsyncResponseConsumer {
 
     @Test
     public void testFailedAfterDone() throws Exception {
-        RuntimeException ooopsie = new RuntimeException();
+        final RuntimeException ooopsie = new RuntimeException();
 
         consumer.cancel();
         consumer.failed(ooopsie);
diff --git a/httpcore-nio/src/test/java/org/apache/http/nio/protocol/TestBasicAsyncResponseProducer.java b/httpcore-nio/src/test/java/org/apache/http/nio/protocol/TestBasicAsyncResponseProducer.java
index 30bbd3c..5205248 100644
--- a/httpcore-nio/src/test/java/org/apache/http/nio/protocol/TestBasicAsyncResponseProducer.java
+++ b/httpcore-nio/src/test/java/org/apache/http/nio/protocol/TestBasicAsyncResponseProducer.java
@@ -27,16 +27,16 @@
 
 package org.apache.http.nio.protocol;
 
+import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
-import static org.mockito.Mockito.never;
-import junit.framework.Assert;
 
 import org.apache.http.HttpResponse;
 import org.apache.http.nio.ContentEncoder;
 import org.apache.http.nio.entity.HttpAsyncContentProducer;
 import org.junit.After;
+import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
 import org.mockito.Mock;
@@ -66,23 +66,25 @@ public class TestBasicAsyncResponseProducer {
 
     @Test
     public void testGenerateRequest() {
-        HttpResponse res = producer.generateResponse();
+        final HttpResponse res = producer.generateResponse();
 
         Assert.assertSame(response, res);
     }
 
+    @SuppressWarnings("boxing")
     @Test
     public void testProduceContentEncoderCompleted() throws Exception {
-        when(encoder.isCompleted()).thenReturn(true);
+        when(encoder.isCompleted()).thenReturn(Boolean.TRUE);
 
         producer.produceContent(encoder,  null);
 
         verify(contentProducer, times(1)).close();
     }
 
+    @SuppressWarnings("boxing")
     @Test
     public void testProduceContentEncoderNotCompleted() throws Exception {
-        when(encoder.isCompleted()).thenReturn(false);
+        when(encoder.isCompleted()).thenReturn(Boolean.FALSE);
 
         producer.produceContent(encoder,  null);
 
diff --git a/httpcore-nio/src/test/java/org/apache/http/nio/protocol/TestErrorResponseProducer.java b/httpcore-nio/src/test/java/org/apache/http/nio/protocol/TestErrorResponseProducer.java
index 94bf13d..0481714 100644
--- a/httpcore-nio/src/test/java/org/apache/http/nio/protocol/TestErrorResponseProducer.java
+++ b/httpcore-nio/src/test/java/org/apache/http/nio/protocol/TestErrorResponseProducer.java
@@ -27,8 +27,6 @@
 
 package org.apache.http.nio.protocol;
 
-import junit.framework.Assert;
-
 import org.apache.http.HttpEntity;
 import org.apache.http.HttpResponse;
 import org.apache.http.HttpVersion;
@@ -36,6 +34,7 @@ import org.apache.http.entity.StringEntity;
 import org.apache.http.message.BasicHttpResponse;
 import org.apache.http.protocol.HTTP;
 import org.junit.After;
+import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
 
@@ -58,7 +57,7 @@ public class TestErrorResponseProducer {
     @Test
     public void testGenerateResponseKeepAlive() {
         erp = new ErrorResponseProducer(response, entity, true);
-        HttpResponse res = erp.generateResponse();
+        final HttpResponse res = erp.generateResponse();
 
         Assert.assertEquals(HTTP.CONN_KEEP_ALIVE, res.getFirstHeader(HTTP.CONN_DIRECTIVE).getValue());
         Assert.assertEquals(entity, res.getEntity());
@@ -68,7 +67,7 @@ public class TestErrorResponseProducer {
     @Test
     public void testGenerateResponseClose() {
         erp = new ErrorResponseProducer(response, entity, false);
-        HttpResponse res = erp.generateResponse();
+        final HttpResponse res = erp.generateResponse();
 
         Assert.assertEquals(HTTP.CONN_CLOSE, res.getFirstHeader(HTTP.CONN_DIRECTIVE).getValue());
         Assert.assertEquals(entity, res.getEntity());
diff --git a/httpcore-nio/src/test/java/org/apache/http/nio/protocol/TestHttpAsyncRequestExecutor.java b/httpcore-nio/src/test/java/org/apache/http/nio/protocol/TestHttpAsyncRequestExecutor.java
index 76a33b2..c09ca50 100644
--- a/httpcore-nio/src/test/java/org/apache/http/nio/protocol/TestHttpAsyncRequestExecutor.java
+++ b/httpcore-nio/src/test/java/org/apache/http/nio/protocol/TestHttpAsyncRequestExecutor.java
@@ -30,10 +30,7 @@ package org.apache.http.nio.protocol;
 import java.io.IOException;
 import java.net.SocketTimeoutException;
 
-import junit.framework.Assert;
-
 import org.apache.http.ConnectionClosedException;
-import org.apache.http.ConnectionReuseStrategy;
 import org.apache.http.HttpException;
 import org.apache.http.HttpRequest;
 import org.apache.http.HttpStatus;
@@ -49,11 +46,10 @@ import org.apache.http.nio.NHttpConnection;
 import org.apache.http.nio.entity.NStringEntity;
 import org.apache.http.nio.protocol.HttpAsyncRequestExecutor.State;
 import org.apache.http.protocol.BasicHttpContext;
-import org.apache.http.protocol.ExecutionContext;
 import org.apache.http.protocol.HTTP;
 import org.apache.http.protocol.HttpContext;
-import org.apache.http.protocol.HttpProcessor;
 import org.junit.After;
+import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
 import org.mockito.Mockito;
@@ -63,29 +59,19 @@ public class TestHttpAsyncRequestExecutor {
     private HttpAsyncRequestExecutor protocolHandler;
     private HttpContext connContext;
     private NHttpClientConnection conn;
-    private HttpAsyncRequestExecutionHandler<?> exchangeHandler;
-    private HttpContext exchangeContext;
+    private HttpAsyncClientExchangeHandler exchangeHandler;
     private ContentEncoder encoder;
     private ContentDecoder decoder;
-    private HttpProcessor httpprocessor;
-    private ConnectionReuseStrategy reuseStrategy;
 
     @Before
     public void setUp() throws Exception {
         this.protocolHandler = new HttpAsyncRequestExecutor();
         this.connContext = new BasicHttpContext();
         this.conn = Mockito.mock(NHttpClientConnection.class);
-        this.exchangeHandler = Mockito.mock(HttpAsyncRequestExecutionHandler.class);
-        this.exchangeContext = new BasicHttpContext();
+        this.exchangeHandler = Mockito.mock(HttpAsyncClientExchangeHandler.class);
         this.encoder = Mockito.mock(ContentEncoder.class);
         this.decoder = Mockito.mock(ContentDecoder.class);
-        this.httpprocessor = Mockito.mock(HttpProcessor.class);
-        this.reuseStrategy = Mockito.mock(ConnectionReuseStrategy.class);
-
         Mockito.when(this.conn.getContext()).thenReturn(this.connContext);
-        Mockito.when(this.exchangeHandler.getContext()).thenReturn(this.exchangeContext);
-        Mockito.when(this.exchangeHandler.getHttpProcessor()).thenReturn(this.httpprocessor);
-        Mockito.when(this.exchangeHandler.getConnectionReuseStrategy()).thenReturn(this.reuseStrategy);
     }
 
     @After
@@ -94,19 +80,19 @@ public class TestHttpAsyncRequestExecutor {
 
     @Test
     public void testConnected() throws Exception {
-        HttpRequest request = new BasicHttpRequest("GET", "/");
+        final HttpRequest request = new BasicHttpRequest("GET", "/");
         Mockito.when(this.exchangeHandler.generateRequest()).thenReturn(request);
         this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_HANDLER, this.exchangeHandler);
 
         this.protocolHandler.connected(this.conn, null);
 
-        State state = (State) this.connContext.getAttribute(
+        final State state = (State) this.connContext.getAttribute(
                 HttpAsyncRequestExecutor.HTTP_EXCHANGE_STATE);
         Assert.assertNotNull(state);
         Mockito.verify(this.exchangeHandler).generateRequest();
         Assert.assertSame(request, state.getRequest());
         Mockito.verify(this.conn).submitRequest(request);
-        Mockito.verify(this.exchangeHandler).requestCompleted(this.exchangeContext);
+        Mockito.verify(this.exchangeHandler).requestCompleted();
         Assert.assertEquals(MessageState.COMPLETED, state.getRequestState());
         Assert.assertEquals("request state: COMPLETED; request: GET / HTTP/1.1; " +
                 "response state: READY; response: ; valid: true;", state.toString());
@@ -114,7 +100,7 @@ public class TestHttpAsyncRequestExecutor {
 
     @Test
     public void testClosed() throws Exception {
-        State state = new HttpAsyncRequestExecutor.State();
+        final State state = new HttpAsyncRequestExecutor.State();
         state.setRequestState(MessageState.COMPLETED);
         state.setResponseState(MessageState.COMPLETED);
         this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_EXCHANGE_STATE, state);
@@ -138,13 +124,13 @@ public class TestHttpAsyncRequestExecutor {
 
     @Test
     public void testHttpExceptionHandling() throws Exception {
-        State state = new HttpAsyncRequestExecutor.State();
+        final State state = new HttpAsyncRequestExecutor.State();
         state.setRequestState(MessageState.COMPLETED);
         state.setResponseState(MessageState.COMPLETED);
         this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_EXCHANGE_STATE, state);
         this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_HANDLER, this.exchangeHandler);
 
-        HttpException httpex = new HttpException();
+        final HttpException httpex = new HttpException();
         this.protocolHandler.exception(this.conn, httpex);
 
         Mockito.verify(this.exchangeHandler).failed(httpex);
@@ -153,13 +139,13 @@ public class TestHttpAsyncRequestExecutor {
 
     @Test
     public void testIOExceptionHandling() throws Exception {
-        State state = new HttpAsyncRequestExecutor.State();
+        final State state = new HttpAsyncRequestExecutor.State();
         state.setRequestState(MessageState.COMPLETED);
         state.setResponseState(MessageState.COMPLETED);
         this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_EXCHANGE_STATE, state);
         this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_HANDLER, this.exchangeHandler);
 
-        IOException ioex = new IOException();
+        final IOException ioex = new IOException();
         this.protocolHandler.exception(this.conn, ioex);
 
         Mockito.verify(this.exchangeHandler).failed(ioex);
@@ -168,10 +154,10 @@ public class TestHttpAsyncRequestExecutor {
 
     @Test
     public void testBasicRequest() throws Exception {
-        State state = new HttpAsyncRequestExecutor.State();
+        final State state = new HttpAsyncRequestExecutor.State();
         this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_EXCHANGE_STATE, state);
         this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_HANDLER, this.exchangeHandler);
-        HttpRequest request = new BasicHttpRequest("GET", "/");
+        final HttpRequest request = new BasicHttpRequest("GET", "/");
         Mockito.when(this.exchangeHandler.generateRequest()).thenReturn(request);
 
         this.protocolHandler.requestReady(this.conn);
@@ -179,22 +165,17 @@ public class TestHttpAsyncRequestExecutor {
         Mockito.verify(this.exchangeHandler).generateRequest();
         Assert.assertSame(request, state.getRequest());
 
-        Assert.assertSame(request, this.exchangeContext.getAttribute(ExecutionContext.HTTP_REQUEST));
-        Assert.assertSame(this.conn, this.exchangeContext.getAttribute(ExecutionContext.HTTP_CONNECTION));
-        Mockito.verify(this.httpprocessor).process(request, this.exchangeContext);
-
-
         Mockito.verify(this.conn).submitRequest(request);
-        Mockito.verify(this.exchangeHandler).requestCompleted(this.exchangeContext);
+        Mockito.verify(this.exchangeHandler).requestCompleted();
         Assert.assertEquals(MessageState.COMPLETED, state.getRequestState());
     }
 
     @Test
     public void testEntityEnclosingRequestWithoutExpectContinue() throws Exception {
-        State state = new HttpAsyncRequestExecutor.State();
+        final State state = new HttpAsyncRequestExecutor.State();
         this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_EXCHANGE_STATE, state);
         this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_HANDLER, this.exchangeHandler);
-        BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/");
+        final BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/");
         request.setEntity(new NStringEntity("stuff"));
         Mockito.when(this.exchangeHandler.generateRequest()).thenReturn(request);
 
@@ -203,16 +184,16 @@ public class TestHttpAsyncRequestExecutor {
         Mockito.verify(this.exchangeHandler).generateRequest();
         Assert.assertSame(request, state.getRequest());
         Mockito.verify(this.conn).submitRequest(request);
-        Mockito.verify(this.exchangeHandler, Mockito.never()).requestCompleted(this.exchangeContext);
+        Mockito.verify(this.exchangeHandler, Mockito.never()).requestCompleted();
         Assert.assertEquals(MessageState.BODY_STREAM, state.getRequestState());
     }
 
     @Test
     public void testEntityEnclosingRequestWithExpectContinue() throws Exception {
-        State state = new HttpAsyncRequestExecutor.State();
+        final State state = new HttpAsyncRequestExecutor.State();
         this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_EXCHANGE_STATE, state);
         this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_HANDLER, this.exchangeHandler);
-        BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/");
+        final BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/");
         request.setHeader(HTTP.EXPECT_DIRECTIVE, HTTP.EXPECT_CONTINUE);
         Mockito.when(this.exchangeHandler.generateRequest()).thenReturn(request);
         Mockito.when(this.conn.getSocketTimeout()).thenReturn(1000);
@@ -224,16 +205,16 @@ public class TestHttpAsyncRequestExecutor {
         Mockito.verify(this.conn).submitRequest(request);
         Mockito.verify(this.conn).setSocketTimeout(3000);
         Assert.assertEquals(1000, state.getTimeout());
-        Mockito.verify(this.exchangeHandler, Mockito.never()).requestCompleted(this.exchangeContext);
+        Mockito.verify(this.exchangeHandler, Mockito.never()).requestCompleted();
         Assert.assertEquals(MessageState.ACK_EXPECTED, state.getRequestState());
     }
 
     @Test
     public void testRequestContentOutput() throws Exception {
-        State state = new HttpAsyncRequestExecutor.State();
+        final State state = new HttpAsyncRequestExecutor.State();
         this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_EXCHANGE_STATE, state);
         this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_HANDLER, this.exchangeHandler);
-        Mockito.when(this.encoder.isCompleted()).thenReturn(false);
+        Mockito.when(this.encoder.isCompleted()).thenReturn(Boolean.FALSE);
 
         this.protocolHandler.outputReady(this.conn, this.encoder);
 
@@ -243,21 +224,21 @@ public class TestHttpAsyncRequestExecutor {
 
     @Test
     public void testRequestContentOutputCompleted() throws Exception {
-        State state = new HttpAsyncRequestExecutor.State();
+        final State state = new HttpAsyncRequestExecutor.State();
         this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_EXCHANGE_STATE, state);
         this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_HANDLER, this.exchangeHandler);
-        Mockito.when(this.encoder.isCompleted()).thenReturn(true);
+        Mockito.when(this.encoder.isCompleted()).thenReturn(Boolean.TRUE);
 
         this.protocolHandler.outputReady(this.conn, this.encoder);
 
         Mockito.verify(this.exchangeHandler).produceContent(this.encoder, this.conn);
-        Mockito.verify(this.exchangeHandler).requestCompleted(this.exchangeContext);
+        Mockito.verify(this.exchangeHandler).requestCompleted();
         Assert.assertEquals(MessageState.COMPLETED, state.getRequestState());
     }
 
     @Test
     public void testRequestContentContinueExpected() throws Exception {
-        State state = new HttpAsyncRequestExecutor.State();
+        final State state = new HttpAsyncRequestExecutor.State();
         state.setRequestState(MessageState.ACK_EXPECTED);
         this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_EXCHANGE_STATE, state);
         this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_HANDLER, this.exchangeHandler);
@@ -271,33 +252,31 @@ public class TestHttpAsyncRequestExecutor {
 
     @Test
     public void testBasicResponse() throws Exception {
-        State state = new HttpAsyncRequestExecutor.State();
-        HttpRequest request = new BasicHttpRequest("GET", "/");
+        final State state = new HttpAsyncRequestExecutor.State();
+        final HttpRequest request = new BasicHttpRequest("GET", "/");
         state.setRequest(request);
         this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_EXCHANGE_STATE, state);
         this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_HANDLER, this.exchangeHandler);
-        BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
+        final BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
         Mockito.when(this.conn.getHttpResponse()).thenReturn(response);
 
         this.protocolHandler.responseReceived(this.conn);
 
         Assert.assertSame(response, state.getResponse());
         Assert.assertEquals(MessageState.BODY_STREAM, state.getResponseState());
-        Assert.assertSame(response, this.exchangeContext.getAttribute(ExecutionContext.HTTP_RESPONSE));
-        Mockito.verify(this.httpprocessor).process(response, this.exchangeContext);
     }
 
     @Test
     public void testResponseContinue() throws Exception {
-        State state = new HttpAsyncRequestExecutor.State();
+        final State state = new HttpAsyncRequestExecutor.State();
         state.setRequestState(MessageState.ACK_EXPECTED);
         state.setTimeout(1000);
-        BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/");
+        final BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/");
         request.setEntity(new NStringEntity("stuff"));
         state.setRequest(request);
         this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_EXCHANGE_STATE, state);
         this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_HANDLER, this.exchangeHandler);
-        BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 100, "Continue");
+        final BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 100, "Continue");
         Mockito.when(this.conn.getHttpResponse()).thenReturn(response);
 
         this.protocolHandler.responseReceived(this.conn);
@@ -311,14 +290,14 @@ public class TestHttpAsyncRequestExecutor {
 
     @Test
     public void testResponseContinueOutOfSequence() throws Exception {
-        State state = new HttpAsyncRequestExecutor.State();
+        final State state = new HttpAsyncRequestExecutor.State();
         state.setRequestState(MessageState.COMPLETED);
-        BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/");
+        final BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/");
         request.setEntity(new NStringEntity("stuff"));
         state.setRequest(request);
         this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_EXCHANGE_STATE, state);
         this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_HANDLER, this.exchangeHandler);
-        BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 100, "Continue");
+        final BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 100, "Continue");
         Mockito.when(this.conn.getHttpResponse()).thenReturn(response);
 
         this.protocolHandler.responseReceived(this.conn);
@@ -330,15 +309,15 @@ public class TestHttpAsyncRequestExecutor {
 
     @Test(expected=HttpException.class)
     public void testResponseUnsupported1xx() throws Exception {
-        State state = new HttpAsyncRequestExecutor.State();
+        final State state = new HttpAsyncRequestExecutor.State();
         state.setRequestState(MessageState.ACK_EXPECTED);
         state.setTimeout(1000);
-        BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/");
+        final BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/");
         request.setEntity(new NStringEntity("stuff"));
         state.setRequest(request);
         this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_EXCHANGE_STATE, state);
         this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_HANDLER, this.exchangeHandler);
-        BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 111, "WTF?");
+        final BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 111, "WTF?");
         Mockito.when(this.conn.getHttpResponse()).thenReturn(response);
 
         this.protocolHandler.responseReceived(this.conn);
@@ -346,15 +325,15 @@ public class TestHttpAsyncRequestExecutor {
 
     @Test
     public void testResponseExpectationFailed() throws Exception {
-        State state = new HttpAsyncRequestExecutor.State();
+        final State state = new HttpAsyncRequestExecutor.State();
         state.setRequestState(MessageState.ACK_EXPECTED);
         state.setTimeout(1000);
-        BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/");
+        final BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/");
         request.setEntity(new NStringEntity("stuff"));
         state.setRequest(request);
         this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_EXCHANGE_STATE, state);
         this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_HANDLER, this.exchangeHandler);
-        BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 403, "Unauthorized");
+        final BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 403, "Unauthorized");
         Mockito.when(this.conn.getHttpResponse()).thenReturn(response);
 
         this.protocolHandler.responseReceived(this.conn);
@@ -368,15 +347,15 @@ public class TestHttpAsyncRequestExecutor {
 
     @Test
     public void testEarlyResponse() throws Exception {
-        State state = new HttpAsyncRequestExecutor.State();
+        final State state = new HttpAsyncRequestExecutor.State();
         state.setRequestState(MessageState.BODY_STREAM);
         state.setTimeout(1000);
-        BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/");
+        final BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/");
         request.setEntity(new NStringEntity("stuff"));
         state.setRequest(request);
         this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_EXCHANGE_STATE, state);
         this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_HANDLER, this.exchangeHandler);
-        BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 403, "Unauthorized");
+        final BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 403, "Unauthorized");
         Mockito.when(this.conn.getHttpResponse()).thenReturn(response);
 
         this.protocolHandler.responseReceived(this.conn);
@@ -391,14 +370,13 @@ public class TestHttpAsyncRequestExecutor {
 
     @Test
     public void testResponseToHead() throws Exception {
-        State state = new HttpAsyncRequestExecutor.State();
-        HttpRequest request = new BasicHttpRequest("HEAD", "/");
+        final State state = new HttpAsyncRequestExecutor.State();
+        final HttpRequest request = new BasicHttpRequest("HEAD", "/");
         state.setRequest(request);
         this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_EXCHANGE_STATE, state);
         this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_HANDLER, this.exchangeHandler);
-        BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
+        final BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
         Mockito.when(this.conn.getHttpResponse()).thenReturn(response);
-        Mockito.when(this.reuseStrategy.keepAlive(response, this.exchangeContext)).thenReturn(true);
 
         this.protocolHandler.responseReceived(this.conn);
 
@@ -413,14 +391,13 @@ public class TestHttpAsyncRequestExecutor {
 
     @Test
     public void testResponseToConnect() throws Exception {
-        State state = new HttpAsyncRequestExecutor.State();
-        HttpRequest request = new BasicHttpRequest("Connect", "/");
+        final State state = new HttpAsyncRequestExecutor.State();
+        final HttpRequest request = new BasicHttpRequest("Connect", "/");
         state.setRequest(request);
         this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_EXCHANGE_STATE, state);
         this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_HANDLER, this.exchangeHandler);
-        BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
+        final BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
         Mockito.when(this.conn.getHttpResponse()).thenReturn(response);
-        Mockito.when(this.reuseStrategy.keepAlive(response, this.exchangeContext)).thenReturn(true);
 
         this.protocolHandler.responseReceived(this.conn);
 
@@ -435,16 +412,15 @@ public class TestHttpAsyncRequestExecutor {
 
     @Test
     public void testResponseNotModified() throws Exception {
-        State state = new HttpAsyncRequestExecutor.State();
-        HttpRequest request = new BasicHttpRequest("Connect", "/");
+        final State state = new HttpAsyncRequestExecutor.State();
+        final HttpRequest request = new BasicHttpRequest("Connect", "/");
         state.setRequest(request);
         this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_EXCHANGE_STATE, state);
         this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_HANDLER, this.exchangeHandler);
-        BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1,
+        final BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1,
                 HttpStatus.SC_NOT_MODIFIED, "Not modified");
         response.setEntity(new BasicHttpEntity());
         Mockito.when(this.conn.getHttpResponse()).thenReturn(response);
-        Mockito.when(this.reuseStrategy.keepAlive(response, this.exchangeContext)).thenReturn(true);
 
         this.protocolHandler.responseReceived(this.conn);
 
@@ -460,10 +436,10 @@ public class TestHttpAsyncRequestExecutor {
 
     @Test
     public void testResponseContentInput() throws Exception {
-        State state = new HttpAsyncRequestExecutor.State();
+        final State state = new HttpAsyncRequestExecutor.State();
         this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_EXCHANGE_STATE, state);
         this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_HANDLER, this.exchangeHandler);
-        Mockito.when(this.decoder.isCompleted()).thenReturn(false);
+        Mockito.when(this.decoder.isCompleted()).thenReturn(Boolean.FALSE);
 
         this.protocolHandler.inputReady(this.conn, this.decoder);
 
@@ -473,70 +449,69 @@ public class TestHttpAsyncRequestExecutor {
 
     @Test
     public void testResponseContentOutputCompleted() throws Exception {
-        State state = new HttpAsyncRequestExecutor.State();
-        HttpRequest request = new BasicHttpRequest("GET", "/");
+        final State state = new HttpAsyncRequestExecutor.State();
+        final HttpRequest request = new BasicHttpRequest("GET", "/");
         state.setRequest(request);
-        BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
+        final BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
         state.setResponse(response);
+        Mockito.when(this.exchangeHandler.isDone()).thenReturn(Boolean.TRUE);
         this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_EXCHANGE_STATE, state);
         this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_HANDLER, this.exchangeHandler);
-        Mockito.when(this.reuseStrategy.keepAlive(response, this.exchangeContext)).thenReturn(true);
-        Mockito.when(this.decoder.isCompleted()).thenReturn(true);
+        Mockito.when(this.decoder.isCompleted()).thenReturn(Boolean.TRUE);
 
         this.protocolHandler.inputReady(this.conn, this.decoder);
 
         Assert.assertEquals(MessageState.READY, state.getRequestState());
         Assert.assertEquals(MessageState.READY, state.getResponseState());
         Mockito.verify(this.exchangeHandler).consumeContent(this.decoder, this.conn);
-        Mockito.verify(this.exchangeHandler).responseCompleted(this.exchangeContext);
+        Mockito.verify(this.exchangeHandler).responseCompleted();
         Mockito.verify(this.conn, Mockito.never()).close();
     }
 
     @Test
-    public void testResponseInvalidState() throws Exception {
-        State state = new HttpAsyncRequestExecutor.State();
-        HttpRequest request = new BasicHttpRequest("GET", "/");
+    public void testResponseContentOutputCompletedHandlerNotDone() throws Exception {
+        final State state = new HttpAsyncRequestExecutor.State();
+        final HttpRequest request = new BasicHttpRequest("GET", "/");
         state.setRequest(request);
-        BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
+        final BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
         state.setResponse(response);
-        state.invalidate();
+        Mockito.when(this.exchangeHandler.isDone()).thenReturn(Boolean.FALSE);
         this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_EXCHANGE_STATE, state);
         this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_HANDLER, this.exchangeHandler);
-        Mockito.when(this.decoder.isCompleted()).thenReturn(true);
+        Mockito.when(this.decoder.isCompleted()).thenReturn(Boolean.TRUE);
 
         this.protocolHandler.inputReady(this.conn, this.decoder);
 
         Assert.assertEquals(MessageState.READY, state.getRequestState());
         Assert.assertEquals(MessageState.READY, state.getResponseState());
         Mockito.verify(this.exchangeHandler).consumeContent(this.decoder, this.conn);
-        Mockito.verify(this.conn).close();
-        Mockito.verify(this.exchangeHandler, Mockito.never()).getConnectionReuseStrategy();
+        Mockito.verify(this.exchangeHandler).responseCompleted();
+        Mockito.verify(this.conn).requestOutput();
     }
 
     @Test
-    public void testResponseNoKeepAlive() throws Exception {
-        State state = new HttpAsyncRequestExecutor.State();
-        HttpRequest request = new BasicHttpRequest("GET", "/");
+    public void testResponseInvalidState() throws Exception {
+        final State state = new HttpAsyncRequestExecutor.State();
+        final HttpRequest request = new BasicHttpRequest("GET", "/");
         state.setRequest(request);
-        BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
+        final BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
         state.setResponse(response);
+        state.invalidate();
         this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_EXCHANGE_STATE, state);
         this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_HANDLER, this.exchangeHandler);
-        Mockito.when(this.reuseStrategy.keepAlive(response, this.exchangeContext)).thenReturn(false);
-        Mockito.when(this.decoder.isCompleted()).thenReturn(true);
+        Mockito.when(this.decoder.isCompleted()).thenReturn(Boolean.TRUE);
 
         this.protocolHandler.inputReady(this.conn, this.decoder);
 
         Assert.assertEquals(MessageState.READY, state.getRequestState());
         Assert.assertEquals(MessageState.READY, state.getResponseState());
         Mockito.verify(this.exchangeHandler).consumeContent(this.decoder, this.conn);
-        Mockito.verify(this.exchangeHandler).responseCompleted(this.exchangeContext);
         Mockito.verify(this.conn).close();
     }
 
     @Test
     public void testEndOfInput() throws Exception {
-        State state = new HttpAsyncRequestExecutor.State();
+        final State state = new HttpAsyncRequestExecutor.State();
         this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_EXCHANGE_STATE, state);
 
         this.protocolHandler.endOfInput(this.conn);
@@ -546,7 +521,7 @@ public class TestHttpAsyncRequestExecutor {
 
     @Test
     public void testPrematureEndOfInput() throws Exception {
-        State state = new HttpAsyncRequestExecutor.State();
+        final State state = new HttpAsyncRequestExecutor.State();
         state.setRequestState(MessageState.COMPLETED);
         this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_EXCHANGE_STATE, state);
         this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_HANDLER, this.exchangeHandler);
@@ -560,8 +535,22 @@ public class TestHttpAsyncRequestExecutor {
     }
 
     @Test
+    public void testPrematureEndOfInputRequestReady() throws Exception {
+        final State state = new HttpAsyncRequestExecutor.State();
+        state.setRequestState(MessageState.READY);
+        this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_EXCHANGE_STATE, state);
+        this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_HANDLER, this.exchangeHandler);
+
+        this.protocolHandler.endOfInput(this.conn);
+
+        Assert.assertTrue(state.isValid());
+
+        Mockito.verify(this.exchangeHandler).inputTerminated();
+    }
+
+    @Test
     public void testTimeoutNoHandler() throws Exception {
-        State state = new HttpAsyncRequestExecutor.State();
+        final State state = new HttpAsyncRequestExecutor.State();
         this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_EXCHANGE_STATE, state);
 
         Mockito.when(this.conn.getStatus()).thenReturn(
@@ -575,7 +564,7 @@ public class TestHttpAsyncRequestExecutor {
 
     @Test
     public void testExpectContinueTimeout() throws Exception {
-        State state = new HttpAsyncRequestExecutor.State();
+        final State state = new HttpAsyncRequestExecutor.State();
         state.setRequestState(MessageState.ACK_EXPECTED);
         state.setTimeout(1000);
         this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_EXCHANGE_STATE, state);
@@ -591,7 +580,7 @@ public class TestHttpAsyncRequestExecutor {
 
     @Test
     public void testTimeoutActiveConnection() throws Exception {
-        State state = new HttpAsyncRequestExecutor.State();
+        final State state = new HttpAsyncRequestExecutor.State();
         state.setRequestState(MessageState.BODY_STREAM);
         this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_EXCHANGE_STATE, state);
         this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_HANDLER, this.exchangeHandler);
@@ -609,7 +598,7 @@ public class TestHttpAsyncRequestExecutor {
 
     @Test
     public void testTimeoutActiveConnectionBufferedData() throws Exception {
-        State state = new HttpAsyncRequestExecutor.State();
+        final State state = new HttpAsyncRequestExecutor.State();
         state.setRequestState(MessageState.BODY_STREAM);
         this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_EXCHANGE_STATE, state);
         this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_HANDLER, this.exchangeHandler);
@@ -627,7 +616,7 @@ public class TestHttpAsyncRequestExecutor {
 
     @Test
     public void testTimeoutClosingConnection() throws Exception {
-        State state = new HttpAsyncRequestExecutor.State();
+        final State state = new HttpAsyncRequestExecutor.State();
         state.setRequestState(MessageState.BODY_STREAM);
         this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_EXCHANGE_STATE, state);
         this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_HANDLER, this.exchangeHandler);
@@ -644,14 +633,14 @@ public class TestHttpAsyncRequestExecutor {
 
     @Test
     public void testExchangeDone() throws Exception {
-        State state = new HttpAsyncRequestExecutor.State();
-        HttpRequest request = new BasicHttpRequest("GET", "/");
+        final State state = new HttpAsyncRequestExecutor.State();
+        final HttpRequest request = new BasicHttpRequest("GET", "/");
         state.setRequest(request);
-        BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
+        final BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
         state.setResponse(response);
         this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_EXCHANGE_STATE, state);
         this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_HANDLER, this.exchangeHandler);
-        Mockito.when(this.exchangeHandler.isDone()).thenReturn(true);
+        Mockito.when(this.exchangeHandler.isDone()).thenReturn(Boolean.TRUE);
 
         Assert.assertEquals("request state: READY; request: GET / HTTP/1.1; " +
                 "response state: READY; response: HTTP/1.1 200 OK; valid: true;",
diff --git a/httpcore-nio/src/test/java/org/apache/http/nio/protocol/TestHttpAsyncRequester.java b/httpcore-nio/src/test/java/org/apache/http/nio/protocol/TestHttpAsyncRequester.java
index 7006760..55a4f06 100644
--- a/httpcore-nio/src/test/java/org/apache/http/nio/protocol/TestHttpAsyncRequester.java
+++ b/httpcore-nio/src/test/java/org/apache/http/nio/protocol/TestHttpAsyncRequester.java
@@ -30,8 +30,6 @@ package org.apache.http.nio.protocol;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Future;
 
-import junit.framework.Assert;
-
 import org.apache.http.ConnectionClosedException;
 import org.apache.http.ConnectionReuseStrategy;
 import org.apache.http.HttpHost;
@@ -39,14 +37,13 @@ import org.apache.http.concurrent.FutureCallback;
 import org.apache.http.impl.nio.pool.BasicNIOPoolEntry;
 import org.apache.http.nio.NHttpClientConnection;
 import org.apache.http.nio.protocol.HttpAsyncRequester.ConnRequestCallback;
-import org.apache.http.params.BasicHttpParams;
-import org.apache.http.params.HttpParams;
 import org.apache.http.pool.ConnPool;
 import org.apache.http.pool.PoolEntry;
 import org.apache.http.protocol.BasicHttpContext;
 import org.apache.http.protocol.HttpContext;
 import org.apache.http.protocol.HttpProcessor;
 import org.junit.After;
+import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
 import org.mockito.ArgumentCaptor;
@@ -56,7 +53,6 @@ public class TestHttpAsyncRequester {
 
     private HttpProcessor httpProcessor;
     private ConnectionReuseStrategy reuseStrategy;
-    private HttpParams params;
     private HttpAsyncRequester requester;
     private HttpContext exchangeContext;
     private HttpContext connContext;
@@ -71,9 +67,7 @@ public class TestHttpAsyncRequester {
     public void setUp() throws Exception {
         this.httpProcessor = Mockito.mock(HttpProcessor.class);
         this.reuseStrategy = Mockito.mock(ConnectionReuseStrategy.class);
-        this.params = new BasicHttpParams();
-        this.requester = new HttpAsyncRequester(
-                this.httpProcessor, this.reuseStrategy, this.params);
+        this.requester = new HttpAsyncRequester(this.httpProcessor, this.reuseStrategy);
         this.exchangeContext = new BasicHttpContext();
         this.requestProducer = Mockito.mock(HttpAsyncRequestProducer.class);
         this.responseConsumer = Mockito.mock(HttpAsyncResponseConsumer.class);
@@ -97,7 +91,7 @@ public class TestHttpAsyncRequester {
                     this.responseConsumer,
                     this.conn);
             Assert.fail("IllegalArgumentException expected");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
         }
         try {
             this.requester.execute(
@@ -105,7 +99,7 @@ public class TestHttpAsyncRequester {
                     null,
                     this.conn);
             Assert.fail("IllegalArgumentException expected");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
         }
         try {
             this.requester.execute(
@@ -113,7 +107,7 @@ public class TestHttpAsyncRequester {
                     this.responseConsumer,
                     (NHttpClientConnection) null);
             Assert.fail("IllegalArgumentException expected");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
         }
         try {
             this.requester.execute(
@@ -122,7 +116,7 @@ public class TestHttpAsyncRequester {
                     this.conn,
                     null);
             Assert.fail("IllegalArgumentException expected");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
         }
 
         try {
@@ -131,7 +125,7 @@ public class TestHttpAsyncRequester {
                     this.responseConsumer,
                     this.connPool);
             Assert.fail("IllegalArgumentException expected");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
         }
         try {
             this.requester.execute(
@@ -139,7 +133,7 @@ public class TestHttpAsyncRequester {
                     null,
                     this.connPool);
             Assert.fail("IllegalArgumentException expected");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
         }
         try {
             this.requester.execute(
@@ -147,7 +141,7 @@ public class TestHttpAsyncRequester {
                     this.responseConsumer,
                     (ConnPool<HttpHost, PoolEntry<HttpHost, NHttpClientConnection>>) null);
             Assert.fail("IllegalArgumentException expected");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
         }
         try {
             this.requester.execute(
@@ -156,14 +150,14 @@ public class TestHttpAsyncRequester {
                     this.connPool,
                     null);
             Assert.fail("IllegalArgumentException expected");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
         }
     }
 
     @Test
     public void testSimpleExecute() throws Exception {
         Mockito.when(this.conn.isOpen()).thenReturn(Boolean.TRUE);
-        Future<Object> future = this.requester.execute(
+        final Future<Object> future = this.requester.execute(
                 this.requestProducer,
                 this.responseConsumer,
                 this.conn, this.exchangeContext, null);
@@ -175,7 +169,7 @@ public class TestHttpAsyncRequester {
     @Test
     public void testExecuteConnectionClosedUnexpectedly() throws Exception {
         Mockito.when(this.conn.isOpen()).thenReturn(false);
-        Future<Object> future = this.requester.execute(
+        final Future<Object> future = this.requester.execute(
                 this.requestProducer,
                 this.responseConsumer,
                 this.conn, this.exchangeContext, null);
@@ -188,8 +182,8 @@ public class TestHttpAsyncRequester {
         Assert.assertNotNull(future.isDone());
         try {
             future.get();
-        } catch (ExecutionException ex) {
-            Throwable cause =  ex.getCause();
+        } catch (final ExecutionException ex) {
+            final Throwable cause =  ex.getCause();
             Assert.assertNotNull(cause);
             Assert.assertTrue(cause instanceof ConnectionClosedException);
         }
@@ -199,20 +193,20 @@ public class TestHttpAsyncRequester {
     @SuppressWarnings({ "rawtypes", "unchecked" })
     @Test
     public void testPooledConnectionRequestFailed() throws Exception {
-        HttpHost host = new HttpHost("somehost");
+        final HttpHost host = new HttpHost("somehost");
         Mockito.when(this.requestProducer.getTarget()).thenReturn(host);
 
-        Future<Object> future = this.requester.execute(
+        final Future<Object> future = this.requester.execute(
                 this.requestProducer,
                 this.responseConsumer,
                 this.connPool, this.exchangeContext, this.callback);
         Assert.assertNotNull(future);
-        ArgumentCaptor<FutureCallback> argCaptor = ArgumentCaptor.forClass(FutureCallback.class);
+        final ArgumentCaptor<FutureCallback> argCaptor = ArgumentCaptor.forClass(FutureCallback.class);
         Mockito.verify(this.connPool).lease(
                 Mockito.eq(host), Mockito.isNull(), argCaptor.capture());
-        ConnRequestCallback connRequestCallback = (ConnRequestCallback) argCaptor.getValue();
+        final ConnRequestCallback connRequestCallback = (ConnRequestCallback) argCaptor.getValue();
 
-        Exception oppsie = new Exception();
+        final Exception oppsie = new Exception();
         connRequestCallback.failed(oppsie);
         Mockito.verify(this.responseConsumer).failed(oppsie);
         Mockito.verify(this.callback).failed(oppsie);
@@ -223,18 +217,18 @@ public class TestHttpAsyncRequester {
     @SuppressWarnings({ "rawtypes", "unchecked" })
     @Test
     public void testPooledConnectionRequestCancelled() throws Exception {
-        HttpHost host = new HttpHost("somehost");
+        final HttpHost host = new HttpHost("somehost");
         Mockito.when(this.requestProducer.getTarget()).thenReturn(host);
 
-        Future<Object> future = this.requester.execute(
+        final Future<Object> future = this.requester.execute(
                 this.requestProducer,
                 this.responseConsumer,
                 this.connPool, this.exchangeContext, this.callback);
         Assert.assertNotNull(future);
-        ArgumentCaptor<FutureCallback> argCaptor = ArgumentCaptor.forClass(FutureCallback.class);
+        final ArgumentCaptor<FutureCallback> argCaptor = ArgumentCaptor.forClass(FutureCallback.class);
         Mockito.verify(this.connPool).lease(
                 Mockito.eq(host), Mockito.isNull(), argCaptor.capture());
-        ConnRequestCallback connRequestCallback = (ConnRequestCallback) argCaptor.getValue();
+        final ConnRequestCallback connRequestCallback = (ConnRequestCallback) argCaptor.getValue();
 
         connRequestCallback.cancelled();
         Mockito.verify(this.responseConsumer).cancel();
@@ -246,21 +240,21 @@ public class TestHttpAsyncRequester {
     @SuppressWarnings({ "rawtypes", "unchecked" })
     @Test
     public void testPooledConnectionAutoReleaseOnRequestCancel() throws Exception {
-        HttpHost host = new HttpHost("somehost");
+        final HttpHost host = new HttpHost("somehost");
         Mockito.when(this.requestProducer.getTarget()).thenReturn(host);
 
-        Future<Object> future = this.requester.execute(
+        final Future<Object> future = this.requester.execute(
                 this.requestProducer,
                 this.responseConsumer,
                 this.connPool, this.exchangeContext, this.callback);
         Assert.assertNotNull(future);
-        ArgumentCaptor<FutureCallback> argCaptor = ArgumentCaptor.forClass(FutureCallback.class);
+        final ArgumentCaptor<FutureCallback> argCaptor = ArgumentCaptor.forClass(FutureCallback.class);
         Mockito.verify(this.connPool).lease(
                 Mockito.eq(host), Mockito.isNull(), argCaptor.capture());
-        ConnRequestCallback connRequestCallback = (ConnRequestCallback) argCaptor.getValue();
+        final ConnRequestCallback connRequestCallback = (ConnRequestCallback) argCaptor.getValue();
 
         future.cancel(true);
-        BasicNIOPoolEntry entry = new BasicNIOPoolEntry("id", host, this.conn);
+        final BasicNIOPoolEntry entry = new BasicNIOPoolEntry("id", host, this.conn);
         connRequestCallback.completed(entry);
         Mockito.verify(this.connPool).release(entry, true);
         Mockito.verify(this.conn, Mockito.never()).requestOutput();
@@ -270,30 +264,30 @@ public class TestHttpAsyncRequester {
     @SuppressWarnings({ "rawtypes", "unchecked" })
     @Test
     public void testPooledRequestExecutionSucceeded() throws Exception {
-        HttpHost host = new HttpHost("somehost");
+        final HttpHost host = new HttpHost("somehost");
         Mockito.when(this.requestProducer.getTarget()).thenReturn(host);
         Mockito.when(this.conn.isOpen()).thenReturn(true);
 
-        Future<Object> future = this.requester.execute(
+        final Future<Object> future = this.requester.execute(
                 this.requestProducer,
                 this.responseConsumer,
                 this.connPool, this.exchangeContext, this.callback);
         Assert.assertNotNull(future);
-        ArgumentCaptor<FutureCallback> argCaptor = ArgumentCaptor.forClass(FutureCallback.class);
+        final ArgumentCaptor<FutureCallback> argCaptor = ArgumentCaptor.forClass(FutureCallback.class);
         Mockito.verify(this.connPool).lease(
                 Mockito.eq(host), Mockito.isNull(), argCaptor.capture());
-        ConnRequestCallback connRequestCallback = (ConnRequestCallback) argCaptor.getValue();
+        final ConnRequestCallback connRequestCallback = (ConnRequestCallback) argCaptor.getValue();
 
-        BasicNIOPoolEntry entry = new BasicNIOPoolEntry("id", host, this.conn);
+        final BasicNIOPoolEntry entry = new BasicNIOPoolEntry("id", host, this.conn);
         connRequestCallback.completed(entry);
-        BasicAsyncRequestExecutionHandler exchangeHandler = (BasicAsyncRequestExecutionHandler) this.connContext.getAttribute(
+        final BasicAsyncClientExchangeHandler exchangeHandler = (BasicAsyncClientExchangeHandler) this.connContext.getAttribute(
                 HttpAsyncRequestExecutor.HTTP_HANDLER);
         Assert.assertNotNull(exchangeHandler);
         Mockito.verify(this.conn).requestOutput();
 
-        Object result = new Object();
+        final Object result = new Object();
         Mockito.when(this.responseConsumer.getResult()).thenReturn(result);
-        exchangeHandler.responseCompleted(this.exchangeContext);
+        exchangeHandler.responseCompleted();
         Mockito.verify(this.callback).completed(result);
         Mockito.verify(this.responseConsumer).close();
         Mockito.verify(this.requestProducer).close();
@@ -303,28 +297,28 @@ public class TestHttpAsyncRequester {
     @SuppressWarnings({ "rawtypes", "unchecked" })
     @Test
     public void testPooledRequestExecutionFailed() throws Exception {
-        HttpHost host = new HttpHost("somehost");
+        final HttpHost host = new HttpHost("somehost");
         Mockito.when(this.requestProducer.getTarget()).thenReturn(host);
         Mockito.when(this.conn.isOpen()).thenReturn(true);
 
-        Future<Object> future = this.requester.execute(
+        final Future<Object> future = this.requester.execute(
                 this.requestProducer,
                 this.responseConsumer,
                 this.connPool, this.exchangeContext, this.callback);
         Assert.assertNotNull(future);
-        ArgumentCaptor<FutureCallback> argCaptor = ArgumentCaptor.forClass(FutureCallback.class);
+        final ArgumentCaptor<FutureCallback> argCaptor = ArgumentCaptor.forClass(FutureCallback.class);
         Mockito.verify(this.connPool).lease(
                 Mockito.eq(host), Mockito.isNull(), argCaptor.capture());
-        ConnRequestCallback connRequestCallback = (ConnRequestCallback) argCaptor.getValue();
+        final ConnRequestCallback connRequestCallback = (ConnRequestCallback) argCaptor.getValue();
 
-        BasicNIOPoolEntry entry = new BasicNIOPoolEntry("id", host, this.conn);
+        final BasicNIOPoolEntry entry = new BasicNIOPoolEntry("id", host, this.conn);
         connRequestCallback.completed(entry);
-        BasicAsyncRequestExecutionHandler exchangeHandler = (BasicAsyncRequestExecutionHandler) this.connContext.getAttribute(
+        final BasicAsyncClientExchangeHandler exchangeHandler = (BasicAsyncClientExchangeHandler) this.connContext.getAttribute(
                 HttpAsyncRequestExecutor.HTTP_HANDLER);
         Assert.assertNotNull(exchangeHandler);
         Mockito.verify(this.conn).requestOutput();
 
-        Exception oppsie = new Exception();
+        final Exception oppsie = new Exception();
         exchangeHandler.failed(oppsie);
         Mockito.verify(this.responseConsumer).failed(oppsie);
         Mockito.verify(this.callback).failed(oppsie);
@@ -336,23 +330,23 @@ public class TestHttpAsyncRequester {
     @SuppressWarnings({ "rawtypes", "unchecked" })
     @Test
     public void testPooledRequestExecutionCancelled() throws Exception {
-        HttpHost host = new HttpHost("somehost");
+        final HttpHost host = new HttpHost("somehost");
         Mockito.when(this.requestProducer.getTarget()).thenReturn(host);
         Mockito.when(this.conn.isOpen()).thenReturn(true);
 
-        Future<Object> future = this.requester.execute(
+        final Future<Object> future = this.requester.execute(
                 this.requestProducer,
                 this.responseConsumer,
                 this.connPool, this.exchangeContext, this.callback);
         Assert.assertNotNull(future);
-        ArgumentCaptor<FutureCallback> argCaptor = ArgumentCaptor.forClass(FutureCallback.class);
+        final ArgumentCaptor<FutureCallback> argCaptor = ArgumentCaptor.forClass(FutureCallback.class);
         Mockito.verify(this.connPool).lease(
                 Mockito.eq(host), Mockito.isNull(), argCaptor.capture());
-        ConnRequestCallback connRequestCallback = (ConnRequestCallback) argCaptor.getValue();
+        final ConnRequestCallback connRequestCallback = (ConnRequestCallback) argCaptor.getValue();
 
-        BasicNIOPoolEntry entry = new BasicNIOPoolEntry("id", host, this.conn);
+        final BasicNIOPoolEntry entry = new BasicNIOPoolEntry("id", host, this.conn);
         connRequestCallback.completed(entry);
-        BasicAsyncRequestExecutionHandler exchangeHandler = (BasicAsyncRequestExecutionHandler) this.connContext.getAttribute(
+        final BasicAsyncClientExchangeHandler exchangeHandler = (BasicAsyncClientExchangeHandler) this.connContext.getAttribute(
                 HttpAsyncRequestExecutor.HTTP_HANDLER);
         Assert.assertNotNull(exchangeHandler);
         Mockito.verify(this.conn).requestOutput();
diff --git a/httpcore-nio/src/test/java/org/apache/http/nio/protocol/TestHttpAsyncService.java b/httpcore-nio/src/test/java/org/apache/http/nio/protocol/TestHttpAsyncService.java
index fb1a3bb..e190fe2 100644
--- a/httpcore-nio/src/test/java/org/apache/http/nio/protocol/TestHttpAsyncService.java
+++ b/httpcore-nio/src/test/java/org/apache/http/nio/protocol/TestHttpAsyncService.java
@@ -30,8 +30,6 @@ package org.apache.http.nio.protocol;
 import java.io.IOException;
 import java.net.SocketTimeoutException;
 
-import junit.framework.Assert;
-
 import org.apache.http.ConnectionReuseStrategy;
 import org.apache.http.HttpException;
 import org.apache.http.HttpResponse;
@@ -50,14 +48,13 @@ import org.apache.http.nio.NHttpClientConnection;
 import org.apache.http.nio.NHttpServerConnection;
 import org.apache.http.nio.entity.NStringEntity;
 import org.apache.http.nio.protocol.HttpAsyncService.State;
-import org.apache.http.params.BasicHttpParams;
-import org.apache.http.params.HttpParams;
 import org.apache.http.protocol.BasicHttpContext;
-import org.apache.http.protocol.ExecutionContext;
 import org.apache.http.protocol.HTTP;
 import org.apache.http.protocol.HttpContext;
+import org.apache.http.protocol.HttpCoreContext;
 import org.apache.http.protocol.HttpProcessor;
 import org.junit.After;
+import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
 import org.mockito.ArgumentMatcher;
@@ -65,12 +62,11 @@ import org.mockito.Mockito;
 
 public class TestHttpAsyncService {
 
-    private HttpAsyncRequestHandlerRegistry handlerResolver;
+    private UriHttpAsyncRequestHandlerMapper handlerResolver;
     private HttpAsyncService protocolHandler;
     private HttpProcessor httpProcessor;
     private ConnectionReuseStrategy reuseStrategy;
     private HttpResponseFactory responseFactory;
-    private HttpParams params;
     private HttpContext connContext;
     private NHttpServerConnection conn;
     private HttpAsyncRequestHandler<Object> requestHandler;
@@ -86,14 +82,13 @@ public class TestHttpAsyncService {
         this.requestHandler = Mockito.mock(HttpAsyncRequestHandler.class);
         this.requestConsumer = Mockito.mock(HttpAsyncRequestConsumer.class);
         this.responseProducer = Mockito.mock(HttpAsyncResponseProducer.class);
-        this.handlerResolver = new HttpAsyncRequestHandlerRegistry();
+        this.handlerResolver = new UriHttpAsyncRequestHandlerMapper();
         this.handlerResolver.register("/", this.requestHandler);
         this.httpProcessor = Mockito.mock(HttpProcessor.class);
         this.reuseStrategy = Mockito.mock(ConnectionReuseStrategy.class);
-        this.responseFactory = new DefaultHttpResponseFactory();
-        this.params = new BasicHttpParams();
+        this.responseFactory = DefaultHttpResponseFactory.INSTANCE;
         this.protocolHandler = new HttpAsyncService(
-                this.httpProcessor, this.reuseStrategy, this.handlerResolver, this.params);
+                this.httpProcessor, this.reuseStrategy, this.responseFactory, this.handlerResolver, null);
         this.connContext = new BasicHttpContext();
         this.conn = Mockito.mock(NHttpServerConnection.class);
         this.encoder = Mockito.mock(ContentEncoder.class);
@@ -107,35 +102,16 @@ public class TestHttpAsyncService {
     public void tearDown() throws Exception {
     }
 
-    @Test
+    @Test(expected=IllegalArgumentException.class)
     public void testInvalidConstruction() throws Exception {
-        try {
-            new HttpAsyncService(null, this.reuseStrategy, this.responseFactory, null, null, this.params);
-            Assert.fail("IllegalArgumentException expected");
-        } catch (IllegalArgumentException ex) {
-        }
-        try {
-            new HttpAsyncService(this.httpProcessor, null, this.responseFactory, null, null, this.params);
-            Assert.fail("IllegalArgumentException expected");
-        } catch (IllegalArgumentException ex) {
-        }
-        try {
-            new HttpAsyncService(this.httpProcessor, this.reuseStrategy, null, null, null, this.params);
-            Assert.fail("IllegalArgumentException expected");
-        } catch (IllegalArgumentException ex) {
-        }
-        try {
-            new HttpAsyncService(this.httpProcessor, this.reuseStrategy, this.responseFactory, null, null, null);
-            Assert.fail("IllegalArgumentException expected");
-        } catch (IllegalArgumentException ex) {
-        }
+        new HttpAsyncService(null, this.reuseStrategy, this.responseFactory, this.handlerResolver, null);
     }
 
     @Test
     public void testConnected() throws Exception {
         this.protocolHandler.connected(this.conn);
 
-        State state = (State) this.connContext.getAttribute(
+        final State state = (State) this.connContext.getAttribute(
                 HttpAsyncService.HTTP_EXCHANGE_STATE);
         Assert.assertNotNull(state);
         Assert.assertEquals(MessageState.READY, state.getRequestState());
@@ -146,7 +122,7 @@ public class TestHttpAsyncService {
 
     @Test
     public void testClosed() throws Exception {
-        State state = new HttpAsyncService.State();
+        final State state = new HttpAsyncService.State();
         state.setRequestState(MessageState.COMPLETED);
         state.setResponseState(MessageState.COMPLETED);
         state.setRequestConsumer(this.requestConsumer);
@@ -165,14 +141,14 @@ public class TestHttpAsyncService {
 
     @Test
     public void testHttpExceptionHandling() throws Exception {
-        State state = new HttpAsyncService.State();
+        final State state = new HttpAsyncService.State();
         state.setRequestState(MessageState.READY);
         state.setResponseState(MessageState.READY);
         state.setRequestConsumer(this.requestConsumer);
         state.setCancellable(this.cancellable);
         this.connContext.setAttribute(HttpAsyncService.HTTP_EXCHANGE_STATE, state);
 
-        HttpException httpex = new HttpException();
+        final HttpException httpex = new HttpException();
         this.protocolHandler.exception(this.conn, httpex);
 
         Assert.assertEquals(MessageState.READY, state.getRequestState());
@@ -190,8 +166,8 @@ public class TestHttpAsyncService {
 
     @Test
     public void testHttpExceptionHandlingRuntimeException() throws Exception {
-        State state = new HttpAsyncService.State();
-        HttpContext exchangeContext = state.getContext();
+        final State state = new HttpAsyncService.State();
+        final HttpContext exchangeContext = state.getContext();
         state.setRequestState(MessageState.READY);
         state.setResponseState(MessageState.READY);
         state.setRequestConsumer(this.requestConsumer);
@@ -201,11 +177,11 @@ public class TestHttpAsyncService {
 
         Mockito.doThrow(new RuntimeException()).when(this.httpProcessor).process(
                 Mockito.any(HttpResponse.class), Mockito.eq(exchangeContext));
-        HttpException httpex = new HttpException();
+        final HttpException httpex = new HttpException();
         try {
             this.protocolHandler.exception(this.conn, httpex);
             Assert.fail("RuntimeException expected");
-        } catch (RuntimeException ex) {
+        } catch (final RuntimeException ex) {
             Mockito.verify(this.conn).shutdown();
             Mockito.verify(this.requestConsumer).failed(httpex);
             Mockito.verify(this.requestConsumer, Mockito.atLeastOnce()).close();
@@ -217,8 +193,8 @@ public class TestHttpAsyncService {
 
     @Test
     public void testHttpExceptionHandlingIOException() throws Exception {
-        State state = new HttpAsyncService.State();
-        HttpContext exchangeContext = state.getContext();
+        final State state = new HttpAsyncService.State();
+        final HttpContext exchangeContext = state.getContext();
         state.setRequestState(MessageState.READY);
         state.setResponseState(MessageState.READY);
         state.setRequestConsumer(this.requestConsumer);
@@ -228,7 +204,7 @@ public class TestHttpAsyncService {
 
         Mockito.doThrow(new IOException()).when(this.httpProcessor).process(
                 Mockito.any(HttpResponse.class), Mockito.eq(exchangeContext));
-        HttpException httpex = new HttpException();
+        final HttpException httpex = new HttpException();
 
         this.protocolHandler.exception(this.conn, httpex);
 
@@ -242,15 +218,15 @@ public class TestHttpAsyncService {
 
     @Test
     public void testHttpExceptionHandlingResponseSubmitted() throws Exception {
-        State state = new HttpAsyncService.State();
+        final State state = new HttpAsyncService.State();
         state.setRequestState(MessageState.READY);
         state.setResponseState(MessageState.READY);
         state.setRequestConsumer(this.requestConsumer);
         state.setResponseProducer(this.responseProducer);
         this.connContext.setAttribute(HttpAsyncService.HTTP_EXCHANGE_STATE, state);
-        Mockito.when(this.conn.isResponseSubmitted()).thenReturn(true);
+        Mockito.when(this.conn.isResponseSubmitted()).thenReturn(Boolean.TRUE);
 
-        HttpException httpex = new HttpException();
+        final HttpException httpex = new HttpException();
         this.protocolHandler.exception(this.conn, httpex);
 
         Assert.assertEquals(MessageState.READY, state.getRequestState());
@@ -264,14 +240,14 @@ public class TestHttpAsyncService {
 
     @Test
     public void testIOExceptionHandling() throws Exception {
-        State state = new HttpAsyncService.State();
+        final State state = new HttpAsyncService.State();
         state.setRequestState(MessageState.READY);
         state.setResponseState(MessageState.READY);
         state.setRequestConsumer(this.requestConsumer);
         state.setResponseProducer(this.responseProducer);
         this.connContext.setAttribute(HttpAsyncService.HTTP_EXCHANGE_STATE, state);
 
-        IOException httpex = new IOException();
+        final IOException httpex = new IOException();
         this.protocolHandler.exception(this.conn, httpex);
 
         Assert.assertEquals(MessageState.READY, state.getRequestState());
@@ -285,16 +261,16 @@ public class TestHttpAsyncService {
 
     @Test
     public void testBasicRequest() throws Exception {
-        State state = new HttpAsyncService.State();
-        HttpContext exchangeContext = state.getContext();
+        final State state = new HttpAsyncService.State();
+        final HttpContext exchangeContext = state.getContext();
         this.connContext.setAttribute(HttpAsyncService.HTTP_EXCHANGE_STATE, state);
 
-        BasicHttpRequest request = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1);
+        final BasicHttpRequest request = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1);
         Mockito.when(this.conn.getHttpRequest()).thenReturn(request);
         Mockito.when(this.requestHandler.processRequest(
                 request, exchangeContext)).thenReturn(this.requestConsumer);
         Mockito.when(this.requestConsumer.getException()).thenReturn(null);
-        Object data = new Object();
+        final Object data = new Object();
         Mockito.when(this.requestConsumer.getResult()).thenReturn(data);
 
         this.protocolHandler.requestReceived(this.conn);
@@ -305,8 +281,8 @@ public class TestHttpAsyncService {
         Assert.assertSame(request, state.getRequest());
         Assert.assertSame(this.requestHandler, state.getRequestHandler());
         Assert.assertSame(this.requestConsumer, state.getRequestConsumer());
-        Assert.assertSame(request, exchangeContext.getAttribute(ExecutionContext.HTTP_REQUEST));
-        Assert.assertSame(this.conn, exchangeContext.getAttribute(ExecutionContext.HTTP_CONNECTION));
+        Assert.assertSame(request, exchangeContext.getAttribute(HttpCoreContext.HTTP_REQUEST));
+        Assert.assertSame(this.conn, exchangeContext.getAttribute(HttpCoreContext.HTTP_CONNECTION));
 
         Mockito.verify(this.httpProcessor).process(request, exchangeContext);
         Mockito.verify(this.requestConsumer).requestReceived(request);
@@ -319,11 +295,11 @@ public class TestHttpAsyncService {
 
     @Test
     public void testRequestNoMatchingHandler() throws Exception {
-        State state = new HttpAsyncService.State();
-        HttpContext exchangeContext = state.getContext();
+        final State state = new HttpAsyncService.State();
+        final HttpContext exchangeContext = state.getContext();
         this.connContext.setAttribute(HttpAsyncService.HTTP_EXCHANGE_STATE, state);
 
-        BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST",
+        final BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST",
                 "/stuff", HttpVersion.HTTP_1_1);
         request.setEntity(new NStringEntity("stuff"));
         Mockito.when(this.conn.getHttpRequest()).thenReturn(request);
@@ -341,11 +317,11 @@ public class TestHttpAsyncService {
 
     @Test
     public void testEntityEnclosingRequest() throws Exception {
-        State state = new HttpAsyncService.State();
-        HttpContext exchangeContext = state.getContext();
+        final State state = new HttpAsyncService.State();
+        final HttpContext exchangeContext = state.getContext();
         this.connContext.setAttribute(HttpAsyncService.HTTP_EXCHANGE_STATE, state);
 
-        BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/",
+        final BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/",
                 HttpVersion.HTTP_1_1);
         Mockito.when(this.conn.getHttpRequest()).thenReturn(request);
         Mockito.when(this.requestHandler.processRequest(
@@ -359,8 +335,8 @@ public class TestHttpAsyncService {
         Assert.assertSame(request, state.getRequest());
         Assert.assertSame(this.requestHandler, state.getRequestHandler());
         Assert.assertSame(this.requestConsumer, state.getRequestConsumer());
-        Assert.assertSame(request, exchangeContext.getAttribute(ExecutionContext.HTTP_REQUEST));
-        Assert.assertSame(this.conn, exchangeContext.getAttribute(ExecutionContext.HTTP_CONNECTION));
+        Assert.assertSame(request, exchangeContext.getAttribute(HttpCoreContext.HTTP_REQUEST));
+        Assert.assertSame(this.conn, exchangeContext.getAttribute(HttpCoreContext.HTTP_CONNECTION));
 
         Mockito.verify(this.httpProcessor).process(request, exchangeContext);
         Mockito.verify(this.requestConsumer).requestReceived(request);
@@ -369,11 +345,11 @@ public class TestHttpAsyncService {
 
     @Test
     public void testEntityEnclosingRequestContinueWithoutVerification() throws Exception {
-        State state = new HttpAsyncService.State();
-        HttpContext exchangeContext = state.getContext();
+        final State state = new HttpAsyncService.State();
+        final HttpContext exchangeContext = state.getContext();
         this.connContext.setAttribute(HttpAsyncService.HTTP_EXCHANGE_STATE, state);
 
-        BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/",
+        final BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/",
                 HttpVersion.HTTP_1_1);
         request.addHeader(HTTP.EXPECT_DIRECTIVE, HTTP.EXPECT_CONTINUE);
         Mockito.when(this.conn.getHttpRequest()).thenReturn(request);
@@ -388,8 +364,8 @@ public class TestHttpAsyncService {
         Assert.assertSame(request, state.getRequest());
         Assert.assertSame(this.requestHandler, state.getRequestHandler());
         Assert.assertSame(this.requestConsumer, state.getRequestConsumer());
-        Assert.assertSame(request, exchangeContext.getAttribute(ExecutionContext.HTTP_REQUEST));
-        Assert.assertSame(this.conn, exchangeContext.getAttribute(ExecutionContext.HTTP_CONNECTION));
+        Assert.assertSame(request, exchangeContext.getAttribute(HttpCoreContext.HTTP_REQUEST));
+        Assert.assertSame(this.conn, exchangeContext.getAttribute(HttpCoreContext.HTTP_CONNECTION));
 
         Mockito.verify(this.httpProcessor).process(request, exchangeContext);
         Mockito.verify(this.requestConsumer).requestReceived(request);
@@ -398,7 +374,7 @@ public class TestHttpAsyncService {
 
             @Override
             public boolean matches(final Object argument) {
-                int status = ((HttpResponse) argument).getStatusLine().getStatusCode();
+                final int status = ((HttpResponse) argument).getStatusLine().getStatusCode();
                 return status == 100;
             }
 
@@ -407,16 +383,16 @@ public class TestHttpAsyncService {
 
     @Test
     public void testEntityEnclosingRequestExpectationVerification() throws Exception {
-        HttpAsyncExpectationVerifier expectationVerifier = Mockito.mock(HttpAsyncExpectationVerifier.class);
+        final HttpAsyncExpectationVerifier expectationVerifier = Mockito.mock(HttpAsyncExpectationVerifier.class);
         this.protocolHandler = new HttpAsyncService(
                 this.httpProcessor, this.reuseStrategy, this.responseFactory,
-                this.handlerResolver, expectationVerifier,  this.params);
+                this.handlerResolver, expectationVerifier);
 
-        State state = new HttpAsyncService.State();
-        HttpContext exchangeContext = state.getContext();
+        final State state = new HttpAsyncService.State();
+        final HttpContext exchangeContext = state.getContext();
         this.connContext.setAttribute(HttpAsyncService.HTTP_EXCHANGE_STATE, state);
 
-        BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/",
+        final BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/",
                 HttpVersion.HTTP_1_1);
         request.addHeader(HTTP.EXPECT_DIRECTIVE, HTTP.EXPECT_CONTINUE);
         Mockito.when(this.conn.getHttpRequest()).thenReturn(request);
@@ -431,8 +407,8 @@ public class TestHttpAsyncService {
         Assert.assertSame(request, state.getRequest());
         Assert.assertSame(this.requestHandler, state.getRequestHandler());
         Assert.assertSame(this.requestConsumer, state.getRequestConsumer());
-        Assert.assertSame(request, exchangeContext.getAttribute(ExecutionContext.HTTP_REQUEST));
-        Assert.assertSame(this.conn, exchangeContext.getAttribute(ExecutionContext.HTTP_CONNECTION));
+        Assert.assertSame(request, exchangeContext.getAttribute(HttpCoreContext.HTTP_REQUEST));
+        Assert.assertSame(this.conn, exchangeContext.getAttribute(HttpCoreContext.HTTP_CONNECTION));
 
         Mockito.verify(this.httpProcessor).process(request, exchangeContext);
         Mockito.verify(this.requestConsumer).requestReceived(request);
@@ -444,11 +420,11 @@ public class TestHttpAsyncService {
 
     @Test
     public void testRequestExpectationFailed() throws Exception {
-        State state = new HttpAsyncService.State();
+        final State state = new HttpAsyncService.State();
         state.setRequestState(MessageState.ACK_EXPECTED);
         this.connContext.setAttribute(HttpAsyncService.HTTP_EXCHANGE_STATE, state);
 
-        HttpAsyncExchange httpexchanage = new HttpAsyncService.Exchange(
+        final HttpAsyncExchange httpexchanage = new HttpAsyncService.Exchange(
                 new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1),
                 new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK"),
                 state, this.conn);
@@ -465,17 +441,17 @@ public class TestHttpAsyncService {
         try {
             httpexchanage.submitResponse();
             Assert.fail("IllegalStateException expected");
-        } catch (IllegalStateException ex) {
+        } catch (final IllegalStateException ex) {
         }
     }
 
     @Test(expected=IllegalArgumentException.class)
     public void testRequestExpectationFailedInvalidResponseProducer() throws Exception {
-        State state = new HttpAsyncService.State();
+        final State state = new HttpAsyncService.State();
         state.setRequestState(MessageState.ACK_EXPECTED);
         this.connContext.setAttribute(HttpAsyncService.HTTP_EXCHANGE_STATE, state);
 
-        HttpAsyncExchange httpexchanage = new HttpAsyncService.Exchange(
+        final HttpAsyncExchange httpexchanage = new HttpAsyncService.Exchange(
                 new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1),
                 new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK"),
                 state, this.conn);
@@ -484,11 +460,11 @@ public class TestHttpAsyncService {
 
     @Test
     public void testRequestContinue() throws Exception {
-        State state = new HttpAsyncService.State();
+        final State state = new HttpAsyncService.State();
         state.setRequestState(MessageState.ACK_EXPECTED);
         this.connContext.setAttribute(HttpAsyncService.HTTP_EXCHANGE_STATE, state);
 
-        HttpAsyncExchange httpexchanage = new HttpAsyncService.Exchange(
+        final HttpAsyncExchange httpexchanage = new HttpAsyncService.Exchange(
                 new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1),
                 new BasicHttpResponse(HttpVersion.HTTP_1_1, 100, "Continue"),
                 state, this.conn);
@@ -496,11 +472,11 @@ public class TestHttpAsyncService {
         httpexchanage.submitResponse();
         Assert.assertTrue(httpexchanage.isCompleted());
 
-        HttpAsyncResponseProducer responseProducer = state.getResponseProducer();
+        final HttpAsyncResponseProducer responseProducer = state.getResponseProducer();
         Assert.assertNotNull(responseProducer);
         Assert.assertEquals(MessageState.ACK_EXPECTED, state.getRequestState());
         Assert.assertEquals(MessageState.READY, state.getResponseState());
-        HttpResponse response = responseProducer.generateResponse();
+        final HttpResponse response = responseProducer.generateResponse();
         Assert.assertEquals(HttpStatus.SC_CONTINUE, response.getStatusLine().getStatusCode());
 
         Mockito.verify(this.conn).requestOutput();
@@ -508,20 +484,20 @@ public class TestHttpAsyncService {
         try {
             httpexchanage.submitResponse(this.responseProducer);
             Assert.fail("IllegalStateException expected");
-        } catch (IllegalStateException ex) {
+        } catch (final IllegalStateException ex) {
         }
     }
 
     @Test
     public void testRequestContent() throws Exception {
-        State state = new HttpAsyncService.State();
-        BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/",
+        final State state = new HttpAsyncService.State();
+        final BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/",
                 HttpVersion.HTTP_1_1);
         state.setRequestState(MessageState.BODY_STREAM);
         state.setRequest(request);
         state.setRequestConsumer(this.requestConsumer);
         this.connContext.setAttribute(HttpAsyncService.HTTP_EXCHANGE_STATE, state);
-        Mockito.when(this.decoder.isCompleted()).thenReturn(false);
+        Mockito.when(this.decoder.isCompleted()).thenReturn(Boolean.FALSE);
 
         this.protocolHandler.inputReady(conn, this.decoder);
 
@@ -534,18 +510,18 @@ public class TestHttpAsyncService {
 
     @Test
     public void testRequestContentCompleted() throws Exception {
-        State state = new HttpAsyncService.State();
-        HttpContext exchangeContext = state.getContext();
-        BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/",
+        final State state = new HttpAsyncService.State();
+        final HttpContext exchangeContext = state.getContext();
+        final BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/",
                 HttpVersion.HTTP_1_1);
         state.setRequestState(MessageState.BODY_STREAM);
         state.setRequest(request);
         state.setRequestConsumer(this.requestConsumer);
         state.setRequestHandler(this.requestHandler);
         this.connContext.setAttribute(HttpAsyncService.HTTP_EXCHANGE_STATE, state);
-        Mockito.when(this.decoder.isCompleted()).thenReturn(true);
+        Mockito.when(this.decoder.isCompleted()).thenReturn(Boolean.TRUE);
         Mockito.when(this.requestConsumer.getException()).thenReturn(null);
-        Object data = new Object();
+        final Object data = new Object();
         Mockito.when(this.requestConsumer.getResult()).thenReturn(data);
 
         this.protocolHandler.inputReady(conn, this.decoder);
@@ -563,16 +539,16 @@ public class TestHttpAsyncService {
 
     @Test
     public void testRequestCompletedWithException() throws Exception {
-        State state = new HttpAsyncService.State();
-        HttpContext exchangeContext = state.getContext();
-        BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/",
+        final State state = new HttpAsyncService.State();
+        final HttpContext exchangeContext = state.getContext();
+        final BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/",
                 HttpVersion.HTTP_1_1);
         state.setRequestState(MessageState.BODY_STREAM);
         state.setRequest(request);
         state.setRequestConsumer(this.requestConsumer);
         state.setRequestHandler(this.requestHandler);
         this.connContext.setAttribute(HttpAsyncService.HTTP_EXCHANGE_STATE, state);
-        Mockito.when(this.decoder.isCompleted()).thenReturn(true);
+        Mockito.when(this.decoder.isCompleted()).thenReturn(Boolean.TRUE);
         Mockito.when(this.requestConsumer.getException()).thenReturn(new HttpException());
         Mockito.when(this.requestConsumer.getResult()).thenReturn(null);
 
@@ -593,18 +569,18 @@ public class TestHttpAsyncService {
 
     @Test
     public void testRequestHandlingHttpException() throws Exception {
-        State state = new HttpAsyncService.State();
-        HttpContext exchangeContext = state.getContext();
-        BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/",
+        final State state = new HttpAsyncService.State();
+        final HttpContext exchangeContext = state.getContext();
+        final BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/",
                 HttpVersion.HTTP_1_1);
         state.setRequestState(MessageState.BODY_STREAM);
         state.setRequest(request);
         state.setRequestConsumer(this.requestConsumer);
         state.setRequestHandler(this.requestHandler);
         this.connContext.setAttribute(HttpAsyncService.HTTP_EXCHANGE_STATE, state);
-        Mockito.when(this.decoder.isCompleted()).thenReturn(true);
+        Mockito.when(this.decoder.isCompleted()).thenReturn(Boolean.TRUE);
         Mockito.when(this.requestConsumer.getException()).thenReturn(null);
-        Object data = new Object();
+        final Object data = new Object();
         Mockito.when(this.requestConsumer.getResult()).thenReturn(data);
         Mockito.doThrow(new UnsupportedHttpVersionException()).when(
                 this.requestHandler).handle(
@@ -625,17 +601,17 @@ public class TestHttpAsyncService {
 
     @Test
     public void testBasicResponse() throws Exception {
-        State state = new HttpAsyncService.State();
-        HttpContext exchangeContext = state.getContext();
-        BasicHttpRequest request = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1);
+        final State state = new HttpAsyncService.State();
+        final HttpContext exchangeContext = state.getContext();
+        final BasicHttpRequest request = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1);
         state.setRequest(request);
         state.setRequestState(MessageState.COMPLETED);
         state.setResponseProducer(this.responseProducer);
         this.connContext.setAttribute(HttpAsyncService.HTTP_EXCHANGE_STATE, state);
 
-        BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
+        final BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
         Mockito.when(this.responseProducer.generateResponse()).thenReturn(response);
-        Mockito.when(this.reuseStrategy.keepAlive(response, exchangeContext)).thenReturn(true);
+        Mockito.when(this.reuseStrategy.keepAlive(response, exchangeContext)).thenReturn(Boolean.TRUE);
 
         this.protocolHandler.responseReady(this.conn);
 
@@ -651,17 +627,17 @@ public class TestHttpAsyncService {
 
     @Test
     public void testBasicResponseNoKeepAlive() throws Exception {
-        State state = new HttpAsyncService.State();
-        HttpContext exchangeContext = state.getContext();
-        BasicHttpRequest request = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1);
+        final State state = new HttpAsyncService.State();
+        final HttpContext exchangeContext = state.getContext();
+        final BasicHttpRequest request = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1);
         state.setRequest(request);
         state.setRequestState(MessageState.COMPLETED);
         state.setResponseProducer(this.responseProducer);
         this.connContext.setAttribute(HttpAsyncService.HTTP_EXCHANGE_STATE, state);
 
-        BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
+        final BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
         Mockito.when(this.responseProducer.generateResponse()).thenReturn(response);
-        Mockito.when(this.reuseStrategy.keepAlive(response, exchangeContext)).thenReturn(false);
+        Mockito.when(this.reuseStrategy.keepAlive(response, exchangeContext)).thenReturn(Boolean.FALSE);
 
         this.protocolHandler.responseReady(this.conn);
 
@@ -676,15 +652,15 @@ public class TestHttpAsyncService {
 
     @Test
     public void testEntityEnclosingResponse() throws Exception {
-        State state = new HttpAsyncService.State();
-        HttpContext exchangeContext = state.getContext();
-        BasicHttpRequest request = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1);
+        final State state = new HttpAsyncService.State();
+        final HttpContext exchangeContext = state.getContext();
+        final BasicHttpRequest request = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1);
         state.setRequest(request);
         state.setRequestState(MessageState.COMPLETED);
         state.setResponseProducer(this.responseProducer);
         this.connContext.setAttribute(HttpAsyncService.HTTP_EXCHANGE_STATE, state);
 
-        BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
+        final BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
         response.setEntity(new NStringEntity("stuff"));
         Mockito.when(this.responseProducer.generateResponse()).thenReturn(response);
 
@@ -702,18 +678,18 @@ public class TestHttpAsyncService {
 
     @Test
     public void testResponseToHead() throws Exception {
-        State state = new HttpAsyncService.State();
-        HttpContext exchangeContext = state.getContext();
-        BasicHttpRequest request = new BasicHttpRequest("HEAD", "/", HttpVersion.HTTP_1_1);
+        final State state = new HttpAsyncService.State();
+        final HttpContext exchangeContext = state.getContext();
+        final BasicHttpRequest request = new BasicHttpRequest("HEAD", "/", HttpVersion.HTTP_1_1);
         state.setRequest(request);
         state.setRequestState(MessageState.COMPLETED);
         state.setResponseProducer(this.responseProducer);
         this.connContext.setAttribute(HttpAsyncService.HTTP_EXCHANGE_STATE, state);
 
-        BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
+        final BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
         response.setEntity(new NStringEntity("stuff"));
         Mockito.when(this.responseProducer.generateResponse()).thenReturn(response);
-        Mockito.when(this.reuseStrategy.keepAlive(response, exchangeContext)).thenReturn(true);
+        Mockito.when(this.reuseStrategy.keepAlive(response, exchangeContext)).thenReturn(Boolean.TRUE);
 
         this.protocolHandler.responseReady(this.conn);
 
@@ -729,19 +705,19 @@ public class TestHttpAsyncService {
 
     @Test
     public void testResponseNotModified() throws Exception {
-        State state = new HttpAsyncService.State();
-        HttpContext exchangeContext = state.getContext();
-        BasicHttpRequest request = new BasicHttpRequest("HEAD", "/", HttpVersion.HTTP_1_1);
+        final State state = new HttpAsyncService.State();
+        final HttpContext exchangeContext = state.getContext();
+        final BasicHttpRequest request = new BasicHttpRequest("HEAD", "/", HttpVersion.HTTP_1_1);
         state.setRequest(request);
         state.setRequestState(MessageState.COMPLETED);
         state.setResponseProducer(this.responseProducer);
         this.connContext.setAttribute(HttpAsyncService.HTTP_EXCHANGE_STATE, state);
 
-        BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1,
+        final BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1,
                 HttpStatus.SC_NOT_MODIFIED, "Not modified");
         response.setEntity(new NStringEntity("stuff"));
         Mockito.when(this.responseProducer.generateResponse()).thenReturn(response);
-        Mockito.when(this.reuseStrategy.keepAlive(response, exchangeContext)).thenReturn(true);
+        Mockito.when(this.reuseStrategy.keepAlive(response, exchangeContext)).thenReturn(Boolean.TRUE);
 
         this.protocolHandler.responseReady(this.conn);
 
@@ -757,15 +733,15 @@ public class TestHttpAsyncService {
 
     @Test
     public void testResponseContinue() throws Exception {
-        State state = new HttpAsyncService.State();
-        BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/",
+        final State state = new HttpAsyncService.State();
+        final BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/",
                 HttpVersion.HTTP_1_1);
         state.setRequest(request);
         state.setRequestState(MessageState.ACK_EXPECTED);
         state.setResponseProducer(this.responseProducer);
         this.connContext.setAttribute(HttpAsyncService.HTTP_EXCHANGE_STATE, state);
 
-        BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1,
+        final BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1,
                 HttpStatus.SC_CONTINUE, "Continue");
         Mockito.when(this.responseProducer.generateResponse()).thenReturn(response);
 
@@ -779,7 +755,7 @@ public class TestHttpAsyncService {
 
             @Override
             public boolean matches(final Object argument) {
-                int status = ((HttpResponse) argument).getStatusLine().getStatusCode();
+                final int status = ((HttpResponse) argument).getStatusLine().getStatusCode();
                 return status == 100;
             }
 
@@ -788,16 +764,16 @@ public class TestHttpAsyncService {
 
     @Test
     public void testResponseFailedExpectation() throws Exception {
-        State state = new HttpAsyncService.State();
-        HttpContext exchangeContext = state.getContext();
-        BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/",
+        final State state = new HttpAsyncService.State();
+        final HttpContext exchangeContext = state.getContext();
+        final BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/",
                 HttpVersion.HTTP_1_1);
         state.setRequest(request);
         state.setRequestState(MessageState.ACK_EXPECTED);
         state.setResponseProducer(this.responseProducer);
         this.connContext.setAttribute(HttpAsyncService.HTTP_EXCHANGE_STATE, state);
 
-        BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 417, "Expectation failed");
+        final BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 417, "Expectation failed");
         response.setEntity(new NStringEntity("stuff"));
         Mockito.when(this.responseProducer.generateResponse()).thenReturn(response);
 
@@ -814,8 +790,8 @@ public class TestHttpAsyncService {
 
     @Test(expected=HttpException.class)
     public void testInvalidResponseStatus() throws Exception {
-        State state = new HttpAsyncService.State();
-        BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/",
+        final State state = new HttpAsyncService.State();
+        final BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/",
                 HttpVersion.HTTP_1_1);
         state.setRequest(request);
         state.setRequestState(MessageState.COMPLETED);
@@ -823,17 +799,17 @@ public class TestHttpAsyncService {
         state.setResponseProducer(this.responseProducer);
         this.connContext.setAttribute(HttpAsyncService.HTTP_EXCHANGE_STATE, state);
 
-        BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 112, "Something stupid");
+        final BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 112, "Something stupid");
         Mockito.when(this.responseProducer.generateResponse()).thenReturn(response);
-        Mockito.when(this.conn.isResponseSubmitted()).thenReturn(false);
+        Mockito.when(this.conn.isResponseSubmitted()).thenReturn(Boolean.FALSE);
 
         this.protocolHandler.responseReady(this.conn);
     }
 
     @Test(expected=HttpException.class)
     public void testInvalidResponseStatusToExpection() throws Exception {
-        State state = new HttpAsyncService.State();
-        BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/",
+        final State state = new HttpAsyncService.State();
+        final BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/",
                 HttpVersion.HTTP_1_1);
         state.setRequest(request);
         state.setRequestState(MessageState.ACK_EXPECTED);
@@ -841,22 +817,22 @@ public class TestHttpAsyncService {
         state.setResponseProducer(this.responseProducer);
         this.connContext.setAttribute(HttpAsyncService.HTTP_EXCHANGE_STATE, state);
 
-        BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
+        final BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
         response.setEntity(new NStringEntity("stuff"));
         Mockito.when(this.responseProducer.generateResponse()).thenReturn(response);
-        Mockito.when(this.conn.isResponseSubmitted()).thenReturn(false);
+        Mockito.when(this.conn.isResponseSubmitted()).thenReturn(Boolean.FALSE);
 
         this.protocolHandler.responseReady(this.conn);
     }
 
     @Test
     public void testResponseTrigger() throws Exception {
-        State state = new HttpAsyncService.State();
+        final State state = new HttpAsyncService.State();
         state.setRequestState(MessageState.COMPLETED);
         state.setResponseState(MessageState.READY);
         this.connContext.setAttribute(HttpAsyncService.HTTP_EXCHANGE_STATE, state);
 
-        HttpAsyncExchange httpexchanage = new HttpAsyncService.Exchange(
+        final HttpAsyncExchange httpexchanage = new HttpAsyncService.Exchange(
                 new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1),
                 new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK"),
                 state, this.conn);
@@ -873,17 +849,17 @@ public class TestHttpAsyncService {
         try {
             httpexchanage.submitResponse(Mockito.mock(HttpAsyncResponseProducer.class));
             Assert.fail("IllegalStateException expected");
-        } catch (IllegalStateException ex) {
+        } catch (final IllegalStateException ex) {
         }
     }
 
     @Test(expected=IllegalArgumentException.class)
     public void testResponseTriggerInvalidResponseProducer() throws Exception {
-        State state = new HttpAsyncService.State();
+        final State state = new HttpAsyncService.State();
         state.setRequestState(MessageState.ACK_EXPECTED);
         this.connContext.setAttribute(HttpAsyncService.HTTP_EXCHANGE_STATE, state);
 
-        HttpAsyncExchange httpexchanage = new HttpAsyncService.Exchange(
+        final HttpAsyncExchange httpexchanage = new HttpAsyncService.Exchange(
                 new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1),
                 new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK"),
                 state, this.conn);
@@ -892,15 +868,15 @@ public class TestHttpAsyncService {
 
     @Test
     public void testResponseContent() throws Exception {
-        State state = new HttpAsyncService.State();
-        BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
+        final State state = new HttpAsyncService.State();
+        final BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
         response.setEntity(new NStringEntity("stuff"));
         state.setRequestState(MessageState.COMPLETED);
         state.setResponseState(MessageState.BODY_STREAM);
         state.setResponse(response);
         state.setResponseProducer(this.responseProducer);
         this.connContext.setAttribute(HttpAsyncService.HTTP_EXCHANGE_STATE, state);
-        Mockito.when(this.encoder.isCompleted()).thenReturn(false);
+        Mockito.when(this.encoder.isCompleted()).thenReturn(Boolean.FALSE);
 
         this.protocolHandler.outputReady(conn, this.encoder);
 
@@ -914,9 +890,9 @@ public class TestHttpAsyncService {
 
     @Test
     public void testResponseContentCompleted() throws Exception {
-        State state = new HttpAsyncService.State();
-        HttpContext exchangeContext = state.getContext();
-        BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
+        final State state = new HttpAsyncService.State();
+        final HttpContext exchangeContext = state.getContext();
+        final BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
         response.setEntity(new NStringEntity("stuff"));
         state.setRequestState(MessageState.COMPLETED);
         state.setResponseState(MessageState.BODY_STREAM);
@@ -924,7 +900,7 @@ public class TestHttpAsyncService {
         state.setResponseProducer(this.responseProducer);
         this.connContext.setAttribute(HttpAsyncService.HTTP_EXCHANGE_STATE, state);
         Mockito.when(this.encoder.isCompleted()).thenReturn(true);
-        Mockito.when(this.reuseStrategy.keepAlive(response, exchangeContext)).thenReturn(true);
+        Mockito.when(this.reuseStrategy.keepAlive(response, exchangeContext)).thenReturn(Boolean.TRUE);
 
         this.protocolHandler.outputReady(conn, this.encoder);
 
@@ -939,9 +915,9 @@ public class TestHttpAsyncService {
 
     @Test
     public void testResponseContentCompletedNoKeepAlive() throws Exception {
-        State state = new HttpAsyncService.State();
-        HttpContext exchangeContext = state.getContext();
-        BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
+        final State state = new HttpAsyncService.State();
+        final HttpContext exchangeContext = state.getContext();
+        final BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
         response.setEntity(new NStringEntity("stuff"));
         state.setRequestState(MessageState.COMPLETED);
         state.setResponseState(MessageState.BODY_STREAM);
@@ -949,7 +925,7 @@ public class TestHttpAsyncService {
         state.setResponseProducer(this.responseProducer);
         this.connContext.setAttribute(HttpAsyncService.HTTP_EXCHANGE_STATE, state);
         Mockito.when(this.encoder.isCompleted()).thenReturn(true);
-        Mockito.when(this.reuseStrategy.keepAlive(response, exchangeContext)).thenReturn(false);
+        Mockito.when(this.reuseStrategy.keepAlive(response, exchangeContext)).thenReturn(Boolean.FALSE);
 
         this.protocolHandler.outputReady(conn, this.encoder);
 
@@ -964,7 +940,7 @@ public class TestHttpAsyncService {
 
     @Test
     public void testTimeoutActiveConnection() throws Exception {
-        State state = new HttpAsyncService.State();
+        final State state = new HttpAsyncService.State();
         this.connContext.setAttribute(HttpAsyncService.HTTP_EXCHANGE_STATE, state);
         Mockito.when(this.conn.getStatus()).thenReturn(NHttpClientConnection.ACTIVE, NHttpClientConnection.CLOSED);
 
@@ -976,7 +952,7 @@ public class TestHttpAsyncService {
 
     @Test
     public void testTimeoutActiveConnectionBufferedData() throws Exception {
-        State state = new HttpAsyncService.State();
+        final State state = new HttpAsyncService.State();
         this.connContext.setAttribute(HttpAsyncService.HTTP_EXCHANGE_STATE, state);
         Mockito.when(this.conn.getStatus()).thenReturn(NHttpClientConnection.ACTIVE, NHttpClientConnection.CLOSING);
 
@@ -988,7 +964,7 @@ public class TestHttpAsyncService {
 
     @Test
     public void testTimeoutClosingConnection() throws Exception {
-        State state = new HttpAsyncService.State();
+        final State state = new HttpAsyncService.State();
         state.setRequestConsumer(this.requestConsumer);
         state.setResponseProducer(this.responseProducer);
         this.connContext.setAttribute(HttpAsyncService.HTTP_EXCHANGE_STATE, state);
diff --git a/httpcore-nio/src/test/java/org/apache/http/nio/protocol/TestUriHttpAsyncRequestHandlerMapper.java b/httpcore-nio/src/test/java/org/apache/http/nio/protocol/TestUriHttpAsyncRequestHandlerMapper.java
new file mode 100644
index 0000000..5e4ee15
--- /dev/null
+++ b/httpcore-nio/src/test/java/org/apache/http/nio/protocol/TestUriHttpAsyncRequestHandlerMapper.java
@@ -0,0 +1,107 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+
+package org.apache.http.nio.protocol;
+
+import org.apache.http.HttpRequest;
+import org.apache.http.message.BasicHttpRequest;
+import org.apache.http.protocol.UriPatternMatcher;
+import org.junit.Assert;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+public class TestUriHttpAsyncRequestHandlerMapper {
+
+    @Test
+    public void testRegisterUnregister() throws Exception {
+        final HttpAsyncRequestHandler<?> h = Mockito.mock(HttpAsyncRequestHandler.class);
+
+        final UriPatternMatcher<HttpAsyncRequestHandler<?>> matcher = Mockito.spy(
+                new UriPatternMatcher<HttpAsyncRequestHandler<?>>());
+        final UriHttpAsyncRequestHandlerMapper registry = new UriHttpAsyncRequestHandlerMapper(matcher);
+
+        registry.register("/h1", h);
+        registry.unregister("/h1");
+
+        Mockito.verify(matcher).register("/h1", h);
+        Mockito.verify(matcher).unregister("/h1");
+    }
+
+    @Test
+    public void testLookup() throws Exception {
+        final UriPatternMatcher<HttpAsyncRequestHandler<?>> matcher = Mockito.spy(
+                new UriPatternMatcher<HttpAsyncRequestHandler<?>>());
+        final UriHttpAsyncRequestHandlerMapper registry = new UriHttpAsyncRequestHandlerMapper(matcher);
+
+        final HttpRequest request = new BasicHttpRequest("GET", "/");
+        registry.lookup(request);
+        registry.unregister("/h1");
+
+        Mockito.verify(matcher).lookup("/");
+    }
+
+    @Test(expected=IllegalArgumentException.class)
+    public void testRegisterNull() throws Exception {
+        final UriHttpAsyncRequestHandlerMapper registry = new UriHttpAsyncRequestHandlerMapper();
+        registry.register(null, null);
+    }
+
+    @Test(expected=IllegalArgumentException.class)
+    public void testLookupNull() throws Exception {
+        final UriHttpAsyncRequestHandlerMapper registry = new UriHttpAsyncRequestHandlerMapper();
+        registry.register(null, null);
+    }
+
+    @Test
+    public void testWildCardMatchingWithQuery() throws Exception {
+        final HttpAsyncRequestHandler<?> h1 = Mockito.mock(HttpAsyncRequestHandler.class);
+        final HttpAsyncRequestHandler<?> h2 = Mockito.mock(HttpAsyncRequestHandler.class);
+        final HttpAsyncRequestHandler<?> def = Mockito.mock(HttpAsyncRequestHandler.class);
+
+        final UriPatternMatcher<HttpAsyncRequestHandler<?>> matcher = Mockito.spy(
+                new UriPatternMatcher<HttpAsyncRequestHandler<?>>());
+        final UriHttpAsyncRequestHandlerMapper registry = new UriHttpAsyncRequestHandlerMapper(matcher);
+        registry.register("*", def);
+        registry.register("*.view", h1);
+        registry.register("*.form", h2);
+
+        HttpAsyncRequestHandler<?> h;
+
+        h = registry.lookup(new BasicHttpRequest("GET", "/that.view?param=value"));
+        Assert.assertNotNull(h);
+        Assert.assertTrue(h1 == h);
+
+        h = registry.lookup(new BasicHttpRequest("GET", "/that.form?whatever"));
+        Assert.assertNotNull(h);
+        Assert.assertTrue(h2 == h);
+
+        h = registry.lookup(new BasicHttpRequest("GET", "/whatever"));
+        Assert.assertNotNull(h);
+        Assert.assertTrue(def == h);
+    }
+
+}
diff --git a/httpcore-nio/src/test/java/org/apache/http/nio/testserver/HttpClientNio.java b/httpcore-nio/src/test/java/org/apache/http/nio/testserver/HttpClientNio.java
new file mode 100644
index 0000000..2217010
--- /dev/null
+++ b/httpcore-nio/src/test/java/org/apache/http/nio/testserver/HttpClientNio.java
@@ -0,0 +1,312 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+
+package org.apache.http.nio.testserver;
+
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.util.List;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.http.HttpHost;
+import org.apache.http.HttpRequest;
+import org.apache.http.HttpRequestInterceptor;
+import org.apache.http.HttpResponse;
+import org.apache.http.concurrent.BasicFuture;
+import org.apache.http.concurrent.FutureCallback;
+import org.apache.http.config.ConnectionConfig;
+import org.apache.http.impl.nio.DefaultHttpClientIODispatch;
+import org.apache.http.impl.nio.DefaultNHttpClientConnection;
+import org.apache.http.impl.nio.DefaultNHttpClientConnectionFactory;
+import org.apache.http.impl.nio.pool.BasicNIOConnPool;
+import org.apache.http.impl.nio.pool.BasicNIOPoolEntry;
+import org.apache.http.impl.nio.reactor.DefaultConnectingIOReactor;
+import org.apache.http.impl.nio.reactor.ExceptionEvent;
+import org.apache.http.nio.NHttpClientConnection;
+import org.apache.http.nio.NHttpClientEventHandler;
+import org.apache.http.nio.pool.NIOConnFactory;
+import org.apache.http.nio.protocol.BasicAsyncRequestProducer;
+import org.apache.http.nio.protocol.BasicAsyncResponseConsumer;
+import org.apache.http.nio.protocol.HttpAsyncRequestExecutor;
+import org.apache.http.nio.protocol.HttpAsyncRequestProducer;
+import org.apache.http.nio.protocol.HttpAsyncRequester;
+import org.apache.http.nio.protocol.HttpAsyncResponseConsumer;
+import org.apache.http.nio.reactor.ConnectingIOReactor;
+import org.apache.http.nio.reactor.IOEventDispatch;
+import org.apache.http.nio.reactor.IOReactorExceptionHandler;
+import org.apache.http.nio.reactor.IOReactorStatus;
+import org.apache.http.nio.reactor.IOSession;
+import org.apache.http.nio.reactor.SessionRequest;
+import org.apache.http.protocol.BasicHttpContext;
+import org.apache.http.protocol.HttpContext;
+import org.apache.http.protocol.HttpProcessor;
+import org.apache.http.protocol.ImmutableHttpProcessor;
+import org.apache.http.protocol.RequestConnControl;
+import org.apache.http.protocol.RequestContent;
+import org.apache.http.protocol.RequestExpectContinue;
+import org.apache.http.protocol.RequestTargetHost;
+import org.apache.http.protocol.RequestUserAgent;
+
+ at SuppressWarnings("deprecation")
+public class HttpClientNio {
+
+    public static final HttpProcessor DEFAULT_HTTP_PROC = new ImmutableHttpProcessor(
+            new HttpRequestInterceptor[] {
+                    new RequestContent(),
+                    new RequestTargetHost(),
+                    new RequestConnControl(),
+                    new RequestUserAgent("TEST-CLIENT/1.1"),
+                    new RequestExpectContinue(true)});
+
+    private final DefaultConnectingIOReactor ioReactor;
+    private final BasicNIOConnPool connpool;
+
+    private volatile  HttpAsyncRequester executor;
+    private volatile IOReactorThread thread;
+    private volatile int timeout;
+
+    public HttpClientNio(
+            final NIOConnFactory<HttpHost, NHttpClientConnection> connFactory) throws IOException {
+        super();
+        this.ioReactor = new DefaultConnectingIOReactor();
+        this.connpool = new BasicNIOConnPool(this.ioReactor, new NIOConnFactory<HttpHost, NHttpClientConnection>() {
+
+            public NHttpClientConnection create(
+                final HttpHost route, final IOSession session) throws IOException {
+                final NHttpClientConnection conn = connFactory.create(route, session);
+                conn.setSocketTimeout(timeout);
+                return conn;
+            }
+
+        }, 0);
+    }
+
+    public int getTimeout() {
+        return this.timeout;
+    }
+
+    public void setTimeout(final int timeout) {
+        this.timeout = timeout;
+    }
+
+    public void setMaxTotal(final int max) {
+        this.connpool.setMaxTotal(max);
+    }
+
+    public void setMaxPerRoute(final int max) {
+        this.connpool.setDefaultMaxPerRoute(max);
+    }
+
+    public Future<BasicNIOPoolEntry> lease(
+            final HttpHost host,
+            final FutureCallback<BasicNIOPoolEntry> callback) {
+        return this.connpool.lease(host, null, this.timeout, TimeUnit.MILLISECONDS, callback);
+    }
+
+    public void release(final BasicNIOPoolEntry poolEntry, final boolean reusable) {
+        this.connpool.release(poolEntry, reusable);
+    }
+
+    public <T> Future<T> execute(
+            final HttpAsyncRequestProducer requestProducer,
+            final HttpAsyncResponseConsumer<T> responseConsumer,
+            final HttpContext context,
+            final FutureCallback<T> callback) {
+        final HttpHost target = requestProducer.getTarget();
+        final BasicFuture<T> future = new BasicFuture<T>(callback);
+        this.connpool.lease(target, null, this.timeout, TimeUnit.MILLISECONDS,
+            new FutureCallback<BasicNIOPoolEntry>() {
+
+                public void completed(final BasicNIOPoolEntry result) {
+                    executor.execute(
+                            requestProducer, responseConsumer,
+                            result, connpool,
+                            context != null ? context : new BasicHttpContext(),
+                            new FutureCallback<T>() {
+
+                                public void completed(final T result) {
+                                    future.completed(result);
+                                }
+
+                                public void failed(final Exception ex) {
+                                    future.failed(ex);
+                                }
+
+                                public void cancelled() {
+                                    future.cancel();
+                                }
+
+                            });
+                }
+
+                public void failed(final Exception ex) {
+                    future.failed(ex);
+                }
+
+                public void cancelled() {
+                    future.cancel();
+                }
+
+            });
+        return future;
+    }
+
+    public Future<HttpResponse> execute(
+            final HttpHost target,
+            final HttpRequest request,
+            final HttpContext context,
+            final FutureCallback<HttpResponse> callback) {
+        return execute(
+                new BasicAsyncRequestProducer(target, request),
+                new BasicAsyncResponseConsumer(),
+                context != null ? context : new BasicHttpContext(),
+                callback);
+    }
+
+    public Future<HttpResponse> execute(
+            final HttpHost target,
+            final HttpRequest request,
+            final HttpContext context) {
+        return execute(target, request, context, null);
+    }
+
+    public Future<HttpResponse> execute(
+            final HttpHost target,
+            final HttpRequest request) {
+        return execute(target, request, null, null);
+    }
+
+    public void setExceptionHandler(final IOReactorExceptionHandler exceptionHandler) {
+        this.ioReactor.setExceptionHandler(exceptionHandler);
+    }
+
+    private void execute(final NHttpClientEventHandler clientHandler) throws IOException {
+        final IOEventDispatch ioEventDispatch = new DefaultHttpClientIODispatch(clientHandler,
+            new DefaultNHttpClientConnectionFactory(ConnectionConfig.DEFAULT)) {
+
+            @Override
+            protected DefaultNHttpClientConnection createConnection(final IOSession session) {
+                final DefaultNHttpClientConnection conn = super.createConnection(session);
+                conn.setSocketTimeout(timeout);
+                return conn;
+            }
+
+        };
+        this.ioReactor.execute(ioEventDispatch);
+    }
+
+    public SessionRequest openConnection(final InetSocketAddress address, final Object attachment) {
+        final SessionRequest sessionRequest = this.ioReactor.connect(address, null, attachment, null);
+        sessionRequest.setConnectTimeout(this.timeout);
+        return sessionRequest;
+    }
+
+    public void start(
+            final HttpProcessor protocolProcessor,
+            final NHttpClientEventHandler clientHandler) {
+        this.executor = new HttpAsyncRequester(protocolProcessor != null ? protocolProcessor :
+            DEFAULT_HTTP_PROC);
+        this.thread = new IOReactorThread(clientHandler);
+        this.thread.start();
+    }
+
+    public void start(
+            final HttpProcessor protocolProcessor) {
+        start(protocolProcessor, new HttpAsyncRequestExecutor());
+    }
+
+    public void start(
+            final NHttpClientEventHandler clientHandler) {
+        start(null, clientHandler);
+    }
+
+    public void start() {
+        start(null, new HttpAsyncRequestExecutor());
+    }
+
+    public ConnectingIOReactor getIoReactor() {
+        return this.ioReactor;
+    }
+
+    public IOReactorStatus getStatus() {
+        return this.ioReactor.getStatus();
+    }
+
+    public List<ExceptionEvent> getAuditLog() {
+        return this.ioReactor.getAuditLog();
+    }
+
+    public void join(final long timeout) throws InterruptedException {
+        if (this.thread != null) {
+            this.thread.join(timeout);
+        }
+    }
+
+    public Exception getException() {
+        if (this.thread != null) {
+            return this.thread.getException();
+        } else {
+            return null;
+        }
+    }
+
+    public void shutdown() throws IOException {
+        this.connpool.shutdown(2000);
+        try {
+            join(500);
+        } catch (final InterruptedException ignore) {
+        }
+    }
+
+    private class IOReactorThread extends Thread {
+
+        private final NHttpClientEventHandler clientHandler;
+
+        private volatile Exception ex;
+
+        public IOReactorThread(final NHttpClientEventHandler clientHandler) {
+            super();
+            this.clientHandler = clientHandler;
+        }
+
+        @Override
+        public void run() {
+            try {
+                execute(this.clientHandler);
+            } catch (final Exception ex) {
+                this.ex = ex;
+            }
+        }
+
+        public Exception getException() {
+            return this.ex;
+        }
+
+    }
+
+}
diff --git a/httpcore-nio/src/test/java/org/apache/http/nio/testserver/HttpCoreNIOTestBase.java b/httpcore-nio/src/test/java/org/apache/http/nio/testserver/HttpCoreNIOTestBase.java
new file mode 100644
index 0000000..6cb6aa7
--- /dev/null
+++ b/httpcore-nio/src/test/java/org/apache/http/nio/testserver/HttpCoreNIOTestBase.java
@@ -0,0 +1,87 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+
+package org.apache.http.nio.testserver;
+
+import org.apache.http.HttpHost;
+import org.apache.http.impl.nio.DefaultNHttpClientConnection;
+import org.apache.http.impl.nio.DefaultNHttpServerConnection;
+import org.apache.http.impl.nio.pool.BasicNIOConnFactory;
+import org.apache.http.nio.NHttpClientConnection;
+import org.apache.http.nio.NHttpConnectionFactory;
+import org.apache.http.nio.pool.NIOConnFactory;
+import org.junit.After;
+
+/**
+ * Base class for all HttpCore NIO tests
+ *
+ */
+public abstract class HttpCoreNIOTestBase {
+
+    protected HttpServerNio server;
+    protected HttpClientNio client;
+
+    protected abstract NHttpConnectionFactory<DefaultNHttpServerConnection>
+        createServerConnectionFactory() throws Exception;
+
+    protected abstract NHttpConnectionFactory<DefaultNHttpClientConnection>
+        createClientConnectionFactory() throws Exception;
+
+    protected NIOConnFactory<HttpHost, NHttpClientConnection> createPoolConnectionFactory()
+        throws Exception {
+        return new BasicNIOConnFactory(createClientConnectionFactory(), null);
+    }
+
+    public void initServer() throws Exception {
+        this.server = new HttpServerNio(createServerConnectionFactory());
+        this.server.setExceptionHandler(new SimpleIOReactorExceptionHandler());
+        this.server.setTimeout(5000);
+    }
+
+    public void initClient() throws Exception {
+        this.client = new HttpClientNio(createPoolConnectionFactory());
+        this.client.setExceptionHandler(new SimpleIOReactorExceptionHandler());
+        this.client.setTimeout(5000);
+    }
+
+    @After
+    public void shutDownClient() throws Exception {
+        if (this.client != null) {
+            this.client.shutdown();
+            this.client = null;
+        }
+    }
+
+    @After
+    public void shutDownServer() throws Exception {
+        if (this.server != null) {
+            this.server.shutdown();
+            this.server = null;
+        }
+    }
+
+}
diff --git a/httpcore-nio/src/test/java/org/apache/http/testserver/HttpServerNio.java b/httpcore-nio/src/test/java/org/apache/http/nio/testserver/HttpServerNio.java
similarity index 62%
rename from httpcore-nio/src/test/java/org/apache/http/testserver/HttpServerNio.java
rename to httpcore-nio/src/test/java/org/apache/http/nio/testserver/HttpServerNio.java
index b42981d..0c43958 100644
--- a/httpcore-nio/src/test/java/org/apache/http/testserver/HttpServerNio.java
+++ b/httpcore-nio/src/test/java/org/apache/http/nio/testserver/HttpServerNio.java
@@ -25,33 +25,50 @@
  *
  */
 
-package org.apache.http.testserver;
+package org.apache.http.nio.testserver;
 
 import java.io.IOException;
 import java.net.InetSocketAddress;
 import java.util.List;
 
-import org.apache.http.impl.nio.DefaultNHttpServerConnection;
+import org.apache.http.HttpResponseInterceptor;
 import org.apache.http.impl.nio.DefaultHttpServerIODispatch;
+import org.apache.http.impl.nio.DefaultNHttpServerConnection;
 import org.apache.http.impl.nio.reactor.DefaultListeningIOReactor;
 import org.apache.http.impl.nio.reactor.ExceptionEvent;
 import org.apache.http.nio.NHttpConnectionFactory;
 import org.apache.http.nio.NHttpServerEventHandler;
-import org.apache.http.nio.NHttpServiceHandler;
+import org.apache.http.nio.protocol.HttpAsyncExpectationVerifier;
+import org.apache.http.nio.protocol.HttpAsyncRequestHandlerMapper;
+import org.apache.http.nio.protocol.HttpAsyncService;
 import org.apache.http.nio.reactor.IOEventDispatch;
 import org.apache.http.nio.reactor.IOReactorExceptionHandler;
 import org.apache.http.nio.reactor.IOReactorStatus;
+import org.apache.http.nio.reactor.IOSession;
 import org.apache.http.nio.reactor.ListenerEndpoint;
 import org.apache.http.nio.reactor.ListeningIOReactor;
+import org.apache.http.protocol.HttpProcessor;
+import org.apache.http.protocol.ImmutableHttpProcessor;
+import org.apache.http.protocol.ResponseConnControl;
+import org.apache.http.protocol.ResponseContent;
+import org.apache.http.protocol.ResponseDate;
+import org.apache.http.protocol.ResponseServer;
 
- at SuppressWarnings("deprecation")
 public class HttpServerNio {
 
+    public static final HttpProcessor DEFAULT_HTTP_PROC = new ImmutableHttpProcessor(
+            new HttpResponseInterceptor[] {
+                    new ResponseDate(),
+                    new ResponseServer("TEST-SERVER/1.1"),
+                    new ResponseContent(),
+                    new ResponseConnControl()});
+
     private final DefaultListeningIOReactor ioReactor;
     private final NHttpConnectionFactory<DefaultNHttpServerConnection> connFactory;
 
     private volatile IOReactorThread thread;
-    private ListenerEndpoint endpoint;
+    private volatile ListenerEndpoint endpoint;
+    private volatile int timeout;
 
     public HttpServerNio(
             final NHttpConnectionFactory<DefaultNHttpServerConnection> connFactory) throws IOException {
@@ -60,12 +77,29 @@ public class HttpServerNio {
         this.connFactory = connFactory;
     }
 
+    public int getTimeout() {
+        return this.timeout;
+    }
+
+    public void setTimeout(final int timeout) {
+        this.timeout = timeout;
+    }
+
     public void setExceptionHandler(final IOReactorExceptionHandler exceptionHandler) {
         this.ioReactor.setExceptionHandler(exceptionHandler);
     }
 
     private void execute(final NHttpServerEventHandler serviceHandler) throws IOException {
-        IOEventDispatch ioEventDispatch = new DefaultHttpServerIODispatch(serviceHandler, this.connFactory);
+        final IOEventDispatch ioEventDispatch = new DefaultHttpServerIODispatch(serviceHandler, this.connFactory) {
+
+            @Override
+            protected DefaultNHttpServerConnection createConnection(final IOSession session) {
+                final DefaultNHttpServerConnection conn = super.createConnection(session);
+                conn.setSocketTimeout(timeout);
+                return conn;
+            }
+
+        };
         this.ioReactor.execute(ioEventDispatch);
     }
 
@@ -73,7 +107,7 @@ public class HttpServerNio {
         return this.endpoint;
     }
 
-    public void setEndpoint(ListenerEndpoint endpoint) {
+    public void setEndpoint(final ListenerEndpoint endpoint) {
         this.endpoint = endpoint;
     }
 
@@ -83,10 +117,22 @@ public class HttpServerNio {
         this.thread.start();
     }
 
-    public void start(final NHttpServiceHandler handler) {
-        this.endpoint = this.ioReactor.listen(new InetSocketAddress(0));
-        this.thread = new IOReactorThread(new NHttpServerEventHandlerAdaptor(handler));
-        this.thread.start();
+    public void start(
+            final HttpProcessor protocolProcessor,
+            final HttpAsyncRequestHandlerMapper handlerMapper,
+            final HttpAsyncExpectationVerifier expectationVerifier) {
+        start(new HttpAsyncService(protocolProcessor != null ? protocolProcessor :
+            DEFAULT_HTTP_PROC, null, null, handlerMapper, expectationVerifier));
+    }
+
+    public void start(
+            final HttpAsyncRequestHandlerMapper handlerMapper,
+            final HttpAsyncExpectationVerifier expectationVerifier) {
+        start(null, handlerMapper, expectationVerifier);
+    }
+
+    public void start(final HttpAsyncRequestHandlerMapper handlerMapper) {
+        start(null, handlerMapper, null);
     }
 
     public ListeningIOReactor getIoReactor() {
@@ -101,7 +147,7 @@ public class HttpServerNio {
         return this.ioReactor.getAuditLog();
     }
 
-    public void join(long timeout) throws InterruptedException {
+    public void join(final long timeout) throws InterruptedException {
         if (this.thread != null) {
             this.thread.join(timeout);
         }
@@ -119,7 +165,7 @@ public class HttpServerNio {
         this.ioReactor.shutdown();
         try {
             join(500);
-        } catch (InterruptedException ignore) {
+        } catch (final InterruptedException ignore) {
         }
     }
 
@@ -138,7 +184,7 @@ public class HttpServerNio {
         public void run() {
             try {
                 execute(this.serviceHandler);
-            } catch (Exception ex) {
+            } catch (final Exception ex) {
                 this.ex = ex;
             }
         }
diff --git a/httpcore-nio/src/test/java/org/apache/http/testserver/SimpleHttpRequestHandlerResolver.java b/httpcore-nio/src/test/java/org/apache/http/nio/testserver/LoggingClientConnectionFactory.java
similarity index 71%
rename from httpcore-nio/src/test/java/org/apache/http/testserver/SimpleHttpRequestHandlerResolver.java
rename to httpcore-nio/src/test/java/org/apache/http/nio/testserver/LoggingClientConnectionFactory.java
index 0d18b54..2273c85 100644
--- a/httpcore-nio/src/test/java/org/apache/http/testserver/SimpleHttpRequestHandlerResolver.java
+++ b/httpcore-nio/src/test/java/org/apache/http/nio/testserver/LoggingClientConnectionFactory.java
@@ -24,23 +24,20 @@
  * <http://www.apache.org/>.
  *
  */
-package org.apache.http.testserver;
+package org.apache.http.nio.testserver;
 
-import org.apache.http.protocol.HttpRequestHandler;
-import org.apache.http.protocol.HttpRequestHandlerResolver;
+import org.apache.http.impl.nio.DefaultNHttpClientConnection;
+import org.apache.http.nio.NHttpConnectionFactory;
+import org.apache.http.nio.reactor.IOSession;
 
- at Deprecated
-public class SimpleHttpRequestHandlerResolver implements HttpRequestHandlerResolver {
+public class LoggingClientConnectionFactory implements NHttpConnectionFactory<DefaultNHttpClientConnection> {
 
-    private final HttpRequestHandler handler;
-
-    public SimpleHttpRequestHandlerResolver(final HttpRequestHandler handler) {
+    public LoggingClientConnectionFactory() {
         super();
-        this.handler = handler;
     }
 
-    public HttpRequestHandler lookup(final String requestURI) {
-        return this.handler;
+    public DefaultNHttpClientConnection createConnection(final IOSession session) {
+        return new LoggingNHttpClientConnection(session);
     }
 
 }
diff --git a/httpcore-nio/src/test/java/org/apache/http/LoggingIOSession.java b/httpcore-nio/src/test/java/org/apache/http/nio/testserver/LoggingIOSession.java
similarity index 90%
rename from httpcore-nio/src/test/java/org/apache/http/LoggingIOSession.java
rename to httpcore-nio/src/test/java/org/apache/http/nio/testserver/LoggingIOSession.java
index dfba166..de6d769 100644
--- a/httpcore-nio/src/test/java/org/apache/http/LoggingIOSession.java
+++ b/httpcore-nio/src/test/java/org/apache/http/nio/testserver/LoggingIOSession.java
@@ -25,7 +25,7 @@
  *
  */
 
-package org.apache.http;
+package org.apache.http.nio.testserver;
 
 import java.io.IOException;
 import java.net.SocketAddress;
@@ -52,9 +52,6 @@ public class LoggingIOSession implements IOSession {
 
     public LoggingIOSession(final IOSession session, final String id, final Log log, final Log wirelog) {
         super();
-        if (session == null) {
-            throw new IllegalArgumentException("I/O session may not be null");
-        }
         this.session = session;
         this.channel = new LoggingByteChannel();
         this.id = id;
@@ -78,8 +75,8 @@ public class LoggingIOSession implements IOSession {
         return this.session.getEventMask();
     }
 
-    private static String formatOps(int ops) {
-        StringBuilder buffer = new StringBuilder(6);
+    private static String formatOps(final int ops) {
+        final StringBuilder buffer = new StringBuilder(6);
         buffer.append('[');
         if ((ops & SelectionKey.OP_READ) > 0) {
             buffer.append('r');
@@ -97,21 +94,21 @@ public class LoggingIOSession implements IOSession {
         return buffer.toString();
     }
 
-    public void setEventMask(int ops) {
+    public void setEventMask(final int ops) {
         this.session.setEventMask(ops);
         if (this.log.isDebugEnabled()) {
             this.log.debug(this.id + " " + this.session + ": Event mask set " + formatOps(ops));
         }
     }
 
-    public void setEvent(int op) {
+    public void setEvent(final int op) {
         this.session.setEvent(op);
         if (this.log.isDebugEnabled()) {
             this.log.debug(this.id + " " + this.session + ": Event set " + formatOps(op));
         }
     }
 
-    public void clearEvent(int op) {
+    public void clearEvent(final int op) {
         this.session.clearEvent(op);
         if (this.log.isDebugEnabled()) {
             this.log.debug(this.id + " " + this.session + ": Event cleared " + formatOps(op));
@@ -144,7 +141,7 @@ public class LoggingIOSession implements IOSession {
         return this.session.getSocketTimeout();
     }
 
-    public void setSocketTimeout(int timeout) {
+    public void setSocketTimeout(final int timeout) {
         if (this.log.isDebugEnabled()) {
             this.log.debug(this.id + " " + this.session + ": Set timeout " + timeout);
         }
@@ -189,13 +186,13 @@ public class LoggingIOSession implements IOSession {
     class LoggingByteChannel implements ByteChannel {
 
         public int read(final ByteBuffer dst) throws IOException {
-            int bytesRead = session.channel().read(dst);
+            final int bytesRead = session.channel().read(dst);
             if (log.isDebugEnabled()) {
                 log.debug(id + " " + session + ": " + bytesRead + " bytes read");
             }
             if (bytesRead > 0 && wirelog.isEnabled()) {
-                ByteBuffer b = dst.duplicate();
-                int p = b.position();
+                final ByteBuffer b = dst.duplicate();
+                final int p = b.position();
                 b.limit(p);
                 b.position(p - bytesRead);
                 wirelog.input(b);
@@ -204,13 +201,13 @@ public class LoggingIOSession implements IOSession {
         }
 
         public int write(final ByteBuffer src) throws IOException {
-            int byteWritten = session.channel().write(src);
+            final int byteWritten = session.channel().write(src);
             if (log.isDebugEnabled()) {
                 log.debug(id + " " + session + ": " + byteWritten + " bytes written");
             }
             if (byteWritten > 0 && wirelog.isEnabled()) {
-                ByteBuffer b = src.duplicate();
-                int p = b.position();
+                final ByteBuffer b = src.duplicate();
+                final int p = b.position();
                 b.limit(p);
                 b.position(p - byteWritten);
                 wirelog.output(b);
diff --git a/httpcore-nio/src/test/java/org/apache/http/LoggingNHttpClientConnection.java b/httpcore-nio/src/test/java/org/apache/http/nio/testserver/LoggingNHttpClientConnection.java
similarity index 83%
rename from httpcore-nio/src/test/java/org/apache/http/LoggingNHttpClientConnection.java
rename to httpcore-nio/src/test/java/org/apache/http/nio/testserver/LoggingNHttpClientConnection.java
index 54d453f..60dbb57 100644
--- a/httpcore-nio/src/test/java/org/apache/http/LoggingNHttpClientConnection.java
+++ b/httpcore-nio/src/test/java/org/apache/http/nio/testserver/LoggingNHttpClientConnection.java
@@ -25,18 +25,20 @@
  *
  */
 
-package org.apache.http;
+package org.apache.http.nio.testserver;
 
 import java.io.IOException;
 import java.util.concurrent.atomic.AtomicLong;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
+import org.apache.http.Header;
+import org.apache.http.HttpException;
+import org.apache.http.HttpRequest;
+import org.apache.http.HttpResponse;
 import org.apache.http.impl.nio.DefaultNHttpClientConnection;
 import org.apache.http.nio.NHttpClientEventHandler;
 import org.apache.http.nio.reactor.IOSession;
-import org.apache.http.nio.util.ByteBufferAllocator;
-import org.apache.http.params.HttpParams;
 
 public class LoggingNHttpClientConnection extends DefaultNHttpClientConnection {
 
@@ -48,12 +50,8 @@ public class LoggingNHttpClientConnection extends DefaultNHttpClientConnection {
     private final Log wirelog;
     private final String id;
 
-    public LoggingNHttpClientConnection(
-            final IOSession session,
-            final HttpResponseFactory responseFactory,
-            final ByteBufferAllocator allocator,
-            final HttpParams params) {
-        super(session, responseFactory, allocator, params);
+    public LoggingNHttpClientConnection(final IOSession session) {
+        super(session, 8 * 1024);
         this.log = LogFactory.getLog(getClass());
         this.iolog = LogFactory.getLog(session.getClass());
         this.headerlog = LogFactory.getLog("org.apache.http.headers");
@@ -108,9 +106,9 @@ public class LoggingNHttpClientConnection extends DefaultNHttpClientConnection {
     protected void onResponseReceived(final HttpResponse response) {
         if (response != null && this.headerlog.isDebugEnabled()) {
             this.headerlog.debug(this.id + " << " + response.getStatusLine().toString());
-            Header[] headers = response.getAllHeaders();
-            for (int i = 0; i < headers.length; i++) {
-                this.headerlog.debug(this.id + " << " + headers[i].toString());
+            final Header[] headers = response.getAllHeaders();
+            for (final Header header : headers) {
+                this.headerlog.debug(this.id + " << " + header.toString());
             }
         }
     }
@@ -119,9 +117,9 @@ public class LoggingNHttpClientConnection extends DefaultNHttpClientConnection {
     protected void onRequestSubmitted(final HttpRequest request) {
         if (request != null && this.headerlog.isDebugEnabled()) {
             this.headerlog.debug(id + " >> " + request.getRequestLine().toString());
-            Header[] headers = request.getAllHeaders();
-            for (int i = 0; i < headers.length; i++) {
-                this.headerlog.debug(this.id + " >> " + headers[i].toString());
+            final Header[] headers = request.getAllHeaders();
+            for (final Header header : headers) {
+                this.headerlog.debug(this.id + " >> " + header.toString());
             }
         }
     }
diff --git a/httpcore-nio/src/test/java/org/apache/http/LoggingNHttpServerConnection.java b/httpcore-nio/src/test/java/org/apache/http/nio/testserver/LoggingNHttpServerConnection.java
similarity index 83%
rename from httpcore-nio/src/test/java/org/apache/http/LoggingNHttpServerConnection.java
rename to httpcore-nio/src/test/java/org/apache/http/nio/testserver/LoggingNHttpServerConnection.java
index 83f860a..6004ef1 100644
--- a/httpcore-nio/src/test/java/org/apache/http/LoggingNHttpServerConnection.java
+++ b/httpcore-nio/src/test/java/org/apache/http/nio/testserver/LoggingNHttpServerConnection.java
@@ -25,18 +25,20 @@
  *
  */
 
-package org.apache.http;
+package org.apache.http.nio.testserver;
 
 import java.io.IOException;
 import java.util.concurrent.atomic.AtomicLong;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
+import org.apache.http.Header;
+import org.apache.http.HttpException;
+import org.apache.http.HttpRequest;
+import org.apache.http.HttpResponse;
 import org.apache.http.impl.nio.DefaultNHttpServerConnection;
 import org.apache.http.nio.NHttpServerEventHandler;
 import org.apache.http.nio.reactor.IOSession;
-import org.apache.http.nio.util.ByteBufferAllocator;
-import org.apache.http.params.HttpParams;
 
 public class LoggingNHttpServerConnection extends DefaultNHttpServerConnection {
 
@@ -48,12 +50,8 @@ public class LoggingNHttpServerConnection extends DefaultNHttpServerConnection {
     private final Log wirelog;
     private final String id;
 
-    public LoggingNHttpServerConnection(
-            final IOSession session,
-            final HttpRequestFactory requestFactory,
-            final ByteBufferAllocator allocator,
-            final HttpParams params) {
-        super(session, requestFactory, allocator, params);
+    public LoggingNHttpServerConnection(final IOSession session) {
+        super(session, 8 * 1024);
         this.log = LogFactory.getLog(getClass());
         this.iolog = LogFactory.getLog(session.getClass());
         this.headerlog = LogFactory.getLog("org.apache.http.headers");
@@ -108,9 +106,9 @@ public class LoggingNHttpServerConnection extends DefaultNHttpServerConnection {
     protected void onRequestReceived(final HttpRequest request) {
         if (request != null && this.headerlog.isDebugEnabled()) {
             this.headerlog.debug(this.id + " >> " + request.getRequestLine().toString());
-            Header[] headers = request.getAllHeaders();
-            for (int i = 0; i < headers.length; i++) {
-                this.headerlog.debug(this.id + " >> " + headers[i].toString());
+            final Header[] headers = request.getAllHeaders();
+            for (final Header header : headers) {
+                this.headerlog.debug(this.id + " >> " + header.toString());
             }
         }
     }
@@ -119,9 +117,9 @@ public class LoggingNHttpServerConnection extends DefaultNHttpServerConnection {
     protected void onResponseSubmitted(final HttpResponse response) {
         if (response != null && this.headerlog.isDebugEnabled()) {
             this.headerlog.debug(this.id + " << " + response.getStatusLine().toString());
-            Header[] headers = response.getAllHeaders();
-            for (int i = 0; i < headers.length; i++) {
-                this.headerlog.debug(this.id + " << " + headers[i].toString());
+            final Header[] headers = response.getAllHeaders();
+            for (final Header header : headers) {
+                this.headerlog.debug(this.id + " << " + header.toString());
             }
         }
     }
diff --git a/httpcore-nio/src/test/java/org/apache/http/LoggingSSLClientConnectionFactory.java b/httpcore-nio/src/test/java/org/apache/http/nio/testserver/LoggingSSLClientConnectionFactory.java
similarity index 55%
rename from httpcore-nio/src/test/java/org/apache/http/LoggingSSLClientConnectionFactory.java
rename to httpcore-nio/src/test/java/org/apache/http/nio/testserver/LoggingSSLClientConnectionFactory.java
index e46f204..32d5233 100644
--- a/httpcore-nio/src/test/java/org/apache/http/LoggingSSLClientConnectionFactory.java
+++ b/httpcore-nio/src/test/java/org/apache/http/nio/testserver/LoggingSSLClientConnectionFactory.java
@@ -24,33 +24,38 @@
  * <http://www.apache.org/>.
  *
  */
-package org.apache.http;
+package org.apache.http.nio.testserver;
 
 import javax.net.ssl.SSLContext;
 
-import org.apache.http.impl.DefaultHttpResponseFactory;
 import org.apache.http.impl.nio.DefaultNHttpClientConnection;
-import org.apache.http.impl.nio.SSLNHttpClientConnectionFactory;
+import org.apache.http.nio.NHttpConnectionFactory;
 import org.apache.http.nio.reactor.IOSession;
-import org.apache.http.nio.util.ByteBufferAllocator;
-import org.apache.http.nio.util.HeapByteBufferAllocator;
-import org.apache.http.params.HttpParams;
+import org.apache.http.nio.reactor.ssl.SSLIOSession;
+import org.apache.http.nio.reactor.ssl.SSLMode;
+import org.apache.http.nio.reactor.ssl.SSLSetupHandler;
 
-public class LoggingSSLClientConnectionFactory extends SSLNHttpClientConnectionFactory {
+public class LoggingSSLClientConnectionFactory implements NHttpConnectionFactory<DefaultNHttpClientConnection> {
+
+    private final SSLContext sslcontext;
+    private final SSLSetupHandler setupHandler;
 
     public LoggingSSLClientConnectionFactory(
-            final SSLContext sslcontext,
-            final HttpParams params) {
-        super(sslcontext, null, new DefaultHttpResponseFactory(), new HeapByteBufferAllocator(), params);
+            final SSLContext sslcontext, final SSLSetupHandler setupHandler) {
+        super();
+        this.sslcontext = sslcontext;
+        this.setupHandler = setupHandler;
+    }
+
+    public LoggingSSLClientConnectionFactory(final SSLContext sslcontext) {
+        this(sslcontext, null);
     }
 
-    @Override
-    protected DefaultNHttpClientConnection createConnection(
-            final IOSession session,
-            final HttpResponseFactory responseFactory,
-            final ByteBufferAllocator allocator,
-            final HttpParams params) {
-        return new LoggingNHttpClientConnection(session, responseFactory, allocator, params);
+    public DefaultNHttpClientConnection createConnection(final IOSession iosession) {
+        final SSLIOSession ssliosession = new SSLIOSession(
+                iosession, SSLMode.CLIENT, this.sslcontext, this.setupHandler);
+        iosession.setAttribute(SSLIOSession.SESSION_KEY, ssliosession);
+        return new LoggingNHttpClientConnection(ssliosession);
     }
 
 }
diff --git a/httpcore-nio/src/test/java/org/apache/http/LoggingSSLServerConnectionFactory.java b/httpcore-nio/src/test/java/org/apache/http/nio/testserver/LoggingSSLServerConnectionFactory.java
similarity index 55%
rename from httpcore-nio/src/test/java/org/apache/http/LoggingSSLServerConnectionFactory.java
rename to httpcore-nio/src/test/java/org/apache/http/nio/testserver/LoggingSSLServerConnectionFactory.java
index 7fc54f8..316d03b 100644
--- a/httpcore-nio/src/test/java/org/apache/http/LoggingSSLServerConnectionFactory.java
+++ b/httpcore-nio/src/test/java/org/apache/http/nio/testserver/LoggingSSLServerConnectionFactory.java
@@ -24,33 +24,38 @@
  * <http://www.apache.org/>.
  *
  */
-package org.apache.http;
+package org.apache.http.nio.testserver;
 
 import javax.net.ssl.SSLContext;
 
-import org.apache.http.impl.DefaultHttpRequestFactory;
 import org.apache.http.impl.nio.DefaultNHttpServerConnection;
-import org.apache.http.impl.nio.SSLNHttpServerConnectionFactory;
+import org.apache.http.nio.NHttpConnectionFactory;
 import org.apache.http.nio.reactor.IOSession;
-import org.apache.http.nio.util.ByteBufferAllocator;
-import org.apache.http.nio.util.HeapByteBufferAllocator;
-import org.apache.http.params.HttpParams;
+import org.apache.http.nio.reactor.ssl.SSLIOSession;
+import org.apache.http.nio.reactor.ssl.SSLMode;
+import org.apache.http.nio.reactor.ssl.SSLSetupHandler;
 
-public class LoggingSSLServerConnectionFactory extends SSLNHttpServerConnectionFactory {
+public class LoggingSSLServerConnectionFactory implements NHttpConnectionFactory<DefaultNHttpServerConnection> {
+
+    private final SSLContext sslcontext;
+    private final SSLSetupHandler setupHandler;
 
     public LoggingSSLServerConnectionFactory(
-            final SSLContext sslcontext,
-            final HttpParams params) {
-        super(sslcontext, null, new DefaultHttpRequestFactory(), new HeapByteBufferAllocator(), params);
+            final SSLContext sslcontext, final SSLSetupHandler setupHandler) {
+        super();
+        this.sslcontext = sslcontext;
+        this.setupHandler = setupHandler;
+    }
+
+    public LoggingSSLServerConnectionFactory(final SSLContext sslcontext) {
+        this(sslcontext, null);
     }
 
-    @Override
-    protected DefaultNHttpServerConnection createConnection(
-            final IOSession session,
-            final HttpRequestFactory requestFactory,
-            final ByteBufferAllocator allocator,
-            final HttpParams params) {
-        return new LoggingNHttpServerConnection(session, requestFactory, allocator, params);
+    public DefaultNHttpServerConnection createConnection(final IOSession iosession) {
+        final SSLIOSession ssliosession = new SSLIOSession(
+                iosession, SSLMode.SERVER, this.sslcontext, this.setupHandler);
+        iosession.setAttribute(SSLIOSession.SESSION_KEY, ssliosession);
+        return new LoggingNHttpServerConnection(ssliosession);
     }
 
 }
diff --git a/httpcore-nio/src/test/java/org/apache/http/testserver/SimpleNHttpRequestHandlerResolver.java b/httpcore-nio/src/test/java/org/apache/http/nio/testserver/LoggingServerConnectionFactory.java
similarity index 70%
rename from httpcore-nio/src/test/java/org/apache/http/testserver/SimpleNHttpRequestHandlerResolver.java
rename to httpcore-nio/src/test/java/org/apache/http/nio/testserver/LoggingServerConnectionFactory.java
index 7c095eb..5c4ccba 100644
--- a/httpcore-nio/src/test/java/org/apache/http/testserver/SimpleNHttpRequestHandlerResolver.java
+++ b/httpcore-nio/src/test/java/org/apache/http/nio/testserver/LoggingServerConnectionFactory.java
@@ -24,22 +24,20 @@
  * <http://www.apache.org/>.
  *
  */
-package org.apache.http.testserver;
+package org.apache.http.nio.testserver;
 
-import org.apache.http.nio.protocol.NHttpRequestHandler;
-import org.apache.http.nio.protocol.NHttpRequestHandlerResolver;
+import org.apache.http.impl.nio.DefaultNHttpServerConnection;
+import org.apache.http.nio.NHttpConnectionFactory;
+import org.apache.http.nio.reactor.IOSession;
 
- at Deprecated
-public class SimpleNHttpRequestHandlerResolver implements NHttpRequestHandlerResolver {
+public class LoggingServerConnectionFactory implements NHttpConnectionFactory<DefaultNHttpServerConnection> {
 
-    private final NHttpRequestHandler handler;
-
-    public SimpleNHttpRequestHandlerResolver(final NHttpRequestHandler handler) {
-        this.handler = handler;
+    public LoggingServerConnectionFactory() {
+        super();
     }
 
-    public NHttpRequestHandler lookup(final String requestURI) {
-        return this.handler;
+    public DefaultNHttpServerConnection createConnection(final IOSession session) {
+        return new LoggingNHttpServerConnection(session);
     }
 
 }
diff --git a/httpcore-nio/src/test/java/org/apache/http/SSLTestContexts.java b/httpcore-nio/src/test/java/org/apache/http/nio/testserver/SSLTestContexts.java
similarity index 70%
rename from httpcore-nio/src/test/java/org/apache/http/SSLTestContexts.java
rename to httpcore-nio/src/test/java/org/apache/http/nio/testserver/SSLTestContexts.java
index fbab208..505509a 100644
--- a/httpcore-nio/src/test/java/org/apache/http/SSLTestContexts.java
+++ b/httpcore-nio/src/test/java/org/apache/http/nio/testserver/SSLTestContexts.java
@@ -25,7 +25,7 @@
  *
  */
 
-package org.apache.http;
+package org.apache.http.nio.testserver;
 
 import java.net.URL;
 import java.security.KeyStore;
@@ -37,51 +37,51 @@ import javax.net.ssl.SSLContext;
 import javax.net.ssl.TrustManager;
 import javax.net.ssl.TrustManagerFactory;
 
-import junit.framework.Assert;
+import org.junit.Assert;
 
 public class SSLTestContexts {
 
     private static KeyManagerFactory createKeyManagerFactory() throws NoSuchAlgorithmException {
-        String algo = KeyManagerFactory.getDefaultAlgorithm();
+        final String algo = KeyManagerFactory.getDefaultAlgorithm();
         try {
             return KeyManagerFactory.getInstance(algo);
-        } catch (NoSuchAlgorithmException ex) {
+        } catch (final NoSuchAlgorithmException ex) {
             return KeyManagerFactory.getInstance("SunX509");
         }
     }
 
     public static SSLContext createServerSSLContext() throws Exception {
-        ClassLoader cl = SSLTestContexts.class.getClassLoader();
-        URL url = cl.getResource("test.keystore");
+        final ClassLoader cl = SSLTestContexts.class.getClassLoader();
+        final URL url = cl.getResource("test.keystore");
         Assert.assertNotNull("Keystore URL should not be null", url);
-        KeyStore keystore  = KeyStore.getInstance("jks");
+        final KeyStore keystore  = KeyStore.getInstance("jks");
         keystore.load(url.openStream(), "nopassword".toCharArray());
-        KeyManagerFactory kmfactory = createKeyManagerFactory();
+        final KeyManagerFactory kmfactory = createKeyManagerFactory();
         kmfactory.init(keystore, "nopassword".toCharArray());
-        KeyManager[] keymanagers = kmfactory.getKeyManagers();
-        SSLContext sslcontext = SSLContext.getInstance("TLS");
+        final KeyManager[] keymanagers = kmfactory.getKeyManagers();
+        final SSLContext sslcontext = SSLContext.getInstance("TLS");
         sslcontext.init(keymanagers, null, null);
         return sslcontext;
     }
 
     private static TrustManagerFactory createTrustManagerFactory() throws NoSuchAlgorithmException {
-        String algo = TrustManagerFactory.getDefaultAlgorithm();
+        final String algo = TrustManagerFactory.getDefaultAlgorithm();
         try {
             return TrustManagerFactory.getInstance(algo);
-        } catch (NoSuchAlgorithmException ex) {
+        } catch (final NoSuchAlgorithmException ex) {
             return TrustManagerFactory.getInstance("SunX509");
         }
     }
 
     public static SSLContext createClientSSLContext() throws Exception {
-        ClassLoader cl = SSLTestContexts.class.getClassLoader();
-        URL url = cl.getResource("test.keystore");
-        KeyStore keystore  = KeyStore.getInstance("jks");
+        final ClassLoader cl = SSLTestContexts.class.getClassLoader();
+        final URL url = cl.getResource("test.keystore");
+        final KeyStore keystore  = KeyStore.getInstance("jks");
         keystore.load(url.openStream(), "nopassword".toCharArray());
-        TrustManagerFactory tmfactory = createTrustManagerFactory();
+        final TrustManagerFactory tmfactory = createTrustManagerFactory();
         tmfactory.init(keystore);
-        TrustManager[] trustmanagers = tmfactory.getTrustManagers();
-        SSLContext sslcontext = SSLContext.getInstance("TLS");
+        final TrustManager[] trustmanagers = tmfactory.getTrustManagers();
+        final SSLContext sslcontext = SSLContext.getInstance("TLS");
         sslcontext.init(null, trustmanagers, null);
         return sslcontext;
     }
diff --git a/httpcore-nio/src/test/java/org/apache/http/SimpleIOReactorExceptionHandler.java b/httpcore-nio/src/test/java/org/apache/http/nio/testserver/SimpleIOReactorExceptionHandler.java
similarity index 90%
copy from httpcore-nio/src/test/java/org/apache/http/SimpleIOReactorExceptionHandler.java
copy to httpcore-nio/src/test/java/org/apache/http/nio/testserver/SimpleIOReactorExceptionHandler.java
index e349be5..2f66488 100644
--- a/httpcore-nio/src/test/java/org/apache/http/SimpleIOReactorExceptionHandler.java
+++ b/httpcore-nio/src/test/java/org/apache/http/nio/testserver/SimpleIOReactorExceptionHandler.java
@@ -24,13 +24,14 @@
  * <http://www.apache.org/>.
  *
  */
-package org.apache.http;
+package org.apache.http.nio.testserver;
 
 import java.io.IOException;
 
+import org.apache.http.OoopsieRuntimeException;
 import org.apache.http.nio.reactor.IOReactorExceptionHandler;
 
-class SimpleIOReactorExceptionHandler implements IOReactorExceptionHandler {
+public class SimpleIOReactorExceptionHandler implements IOReactorExceptionHandler {
 
     public boolean handle(final RuntimeException ex) {
         if (!(ex instanceof OoopsieRuntimeException)) {
diff --git a/httpcore-nio/src/test/java/org/apache/http/Wire.java b/httpcore-nio/src/test/java/org/apache/http/nio/testserver/Wire.java
similarity index 83%
rename from httpcore-nio/src/test/java/org/apache/http/Wire.java
rename to httpcore-nio/src/test/java/org/apache/http/nio/testserver/Wire.java
index 50db15b..e6454b9 100644
--- a/httpcore-nio/src/test/java/org/apache/http/Wire.java
+++ b/httpcore-nio/src/test/java/org/apache/http/nio/testserver/Wire.java
@@ -25,7 +25,7 @@
  *
  */
 
-package org.apache.http;
+package org.apache.http.nio.testserver;
 
 import java.nio.ByteBuffer;
 
@@ -42,10 +42,10 @@ class Wire {
         this.id = id;
     }
 
-    private void wire(final String header, final byte[] b, int pos, int off) {
-        StringBuilder buffer = new StringBuilder();
+    private void wire(final String header, final byte[] b, final int pos, final int off) {
+        final StringBuilder buffer = new StringBuilder();
         for (int i = 0; i < off; i++) {
-            int ch = b[pos + i];
+            final int ch = b[pos + i];
             if (ch == 13) {
                 buffer.append("[\\r]");
             } else if (ch == 10) {
@@ -75,27 +75,27 @@ class Wire {
         return this.log.isDebugEnabled();
     }
 
-    public void output(final byte[] b, int pos, int off) {
+    public void output(final byte[] b, final int pos, final int off) {
         wire("<< ", b, pos, off);
     }
 
-    public void input(final byte[] b, int pos, int off) {
+    public void input(final byte[] b, final int pos, final int off) {
         wire(">> ", b, pos, off);
     }
 
-    public void output(byte[] b) {
+    public void output(final byte[] b) {
         output(b, 0, b.length);
     }
 
-    public void input(byte[] b) {
+    public void input(final byte[] b) {
         input(b, 0, b.length);
     }
 
-    public void output(int b) {
+    public void output(final int b) {
         output(new byte[] {(byte) b});
     }
 
-    public void input(int b) {
+    public void input(final int b) {
         input(new byte[] {(byte) b});
     }
 
@@ -103,7 +103,7 @@ class Wire {
         if (b.hasArray()) {
             output(b.array(), b.arrayOffset() + b.position(), b.remaining());
         } else {
-            byte[] tmp = new byte[b.remaining()];
+            final byte[] tmp = new byte[b.remaining()];
             b.get(tmp);
             output(tmp);
         }
@@ -113,7 +113,7 @@ class Wire {
         if (b.hasArray()) {
             input(b.array(), b.arrayOffset() + b.position(), b.remaining());
         } else {
-            byte[] tmp = new byte[b.remaining()];
+            final byte[] tmp = new byte[b.remaining()];
             b.get(tmp);
             input(tmp);
         }
diff --git a/httpcore-nio/src/test/java/org/apache/http/nio/util/ContentDecoderMock.java b/httpcore-nio/src/test/java/org/apache/http/nio/util/ContentDecoderMock.java
index e0400f2..d6d2f36 100644
--- a/httpcore-nio/src/test/java/org/apache/http/nio/util/ContentDecoderMock.java
+++ b/httpcore-nio/src/test/java/org/apache/http/nio/util/ContentDecoderMock.java
@@ -44,13 +44,10 @@ public class ContentDecoderMock implements ContentDecoder {
     }
 
     public int read(final ByteBuffer dst) throws IOException {
-        if (dst == null) {
-            throw new IllegalArgumentException("Byte buffer may not be null");
-        }
         if (this.completed) {
             return -1;
         }
-        int bytesRead = this.channel.read(dst);
+        final int bytesRead = this.channel.read(dst);
         if (bytesRead == -1) {
             this.completed = true;
         }
diff --git a/httpcore-nio/src/test/java/org/apache/http/nio/util/ContentEncoderMock.java b/httpcore-nio/src/test/java/org/apache/http/nio/util/ContentEncoderMock.java
index a2d3bac..9594bee 100644
--- a/httpcore-nio/src/test/java/org/apache/http/nio/util/ContentEncoderMock.java
+++ b/httpcore-nio/src/test/java/org/apache/http/nio/util/ContentEncoderMock.java
@@ -34,12 +34,10 @@ import java.nio.channels.WritableByteChannel;
 import org.apache.http.impl.io.HttpTransportMetricsImpl;
 import org.apache.http.impl.nio.codecs.AbstractContentEncoder;
 import org.apache.http.nio.reactor.SessionOutputBuffer;
+import org.apache.http.util.Asserts;
 
 public class ContentEncoderMock extends AbstractContentEncoder {
 
-    // TODO? remove this field and the complete() and isCompleted() methods
-    private boolean completed;
-
     public ContentEncoderMock(
             final WritableByteChannel channel,
             final SessionOutputBuffer buffer,
@@ -47,23 +45,11 @@ public class ContentEncoderMock extends AbstractContentEncoder {
         super(channel, buffer, metrics);
     }
 
-    @Override
-    public boolean isCompleted() {
-        return this.completed;
-    }
-
-    @Override
-    public void complete() throws IOException {
-        this.completed = true;
-    }
-
     public int write(final ByteBuffer src) throws IOException {
         if (src == null) {
             return 0;
         }
-        if (this.completed) {
-            throw new IllegalStateException("Decoding process already completed");
-        }
+        Asserts.check(!isCompleted(), "Decoding process already completed");
         return this.channel.write(src);
     }
 
diff --git a/httpcore-nio/src/test/java/org/apache/http/nio/util/TestBuffers.java b/httpcore-nio/src/test/java/org/apache/http/nio/util/TestBuffers.java
index ed2fbde..e33effa 100644
--- a/httpcore-nio/src/test/java/org/apache/http/nio/util/TestBuffers.java
+++ b/httpcore-nio/src/test/java/org/apache/http/nio/util/TestBuffers.java
@@ -34,15 +34,13 @@ import java.nio.channels.Channels;
 import java.nio.channels.ReadableByteChannel;
 import java.nio.channels.WritableByteChannel;
 
+import org.apache.http.Consts;
 import org.apache.http.ReadableByteChannelMock;
 import org.apache.http.impl.io.HttpTransportMetricsImpl;
 import org.apache.http.impl.nio.reactor.SessionOutputBufferImpl;
-import org.apache.http.io.BufferInfo;
 import org.apache.http.nio.ContentDecoder;
 import org.apache.http.nio.ContentEncoder;
 import org.apache.http.nio.reactor.SessionOutputBuffer;
-import org.apache.http.params.BasicHttpParams;
-import org.apache.http.params.HttpParams;
 import org.apache.http.util.EncodingUtils;
 import org.junit.Assert;
 import org.junit.Test;
@@ -54,25 +52,25 @@ public class TestBuffers {
 
     @Test
     public void testInputBufferOperations() throws IOException {
-        ReadableByteChannel channel = new ReadableByteChannelMock(
-                new String[] {"stuff;", "more stuff"}, "US-ASCII");
+        final ReadableByteChannel channel = new ReadableByteChannelMock(
+                new String[] {"stuff;", "more stuff"}, Consts.ASCII);
 
-        ContentDecoder decoder = new ContentDecoderMock(channel);
+        final ContentDecoder decoder = new ContentDecoderMock(channel);
 
-        SimpleInputBuffer buffer = new SimpleInputBuffer(4, new DirectByteBufferAllocator());
-        int count = buffer.consumeContent(decoder);
+        final SimpleInputBuffer buffer = new SimpleInputBuffer(4, DirectByteBufferAllocator.INSTANCE);
+        final int count = buffer.consumeContent(decoder);
         Assert.assertEquals(16, count);
         Assert.assertTrue(decoder.isCompleted());
 
-        byte[] b1 = new byte[5];
+        final byte[] b1 = new byte[5];
 
         int len = buffer.read(b1);
         Assert.assertEquals("stuff", EncodingUtils.getAsciiString(b1, 0, len));
 
-        int c = buffer.read();
+        final int c = buffer.read();
         Assert.assertEquals(';', c);
 
-        byte[] b2 = new byte[1024];
+        final byte[] b2 = new byte[1024];
 
         len = buffer.read(b2);
         Assert.assertEquals("more stuff", EncodingUtils.getAsciiString(b2, 0, len));
@@ -88,15 +86,14 @@ public class TestBuffers {
 
     @Test
     public void testOutputBufferOperations() throws IOException {
-        ByteArrayOutputStream outstream = new ByteArrayOutputStream();
-        WritableByteChannel channel = Channels.newChannel(outstream);
-        HttpParams params = new BasicHttpParams();
-        SessionOutputBuffer outbuf = new SessionOutputBufferImpl(1024, 128, params);
-        HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
+        final ByteArrayOutputStream outstream = new ByteArrayOutputStream();
+        final WritableByteChannel channel = Channels.newChannel(outstream);
+        final SessionOutputBuffer outbuf = new SessionOutputBufferImpl(1024, 128, Consts.ASCII);
+        final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
 
-        ContentEncoder encoder = new ContentEncoderMock(channel, outbuf, metrics);
+        final ContentEncoder encoder = new ContentEncoderMock(channel, outbuf, metrics);
 
-        SimpleOutputBuffer buffer = new SimpleOutputBuffer(4, new DirectByteBufferAllocator());
+        final SimpleOutputBuffer buffer = new SimpleOutputBuffer(4, DirectByteBufferAllocator.INSTANCE);
 
         buffer.write(EncodingUtils.getAsciiBytes("stuff"));
         buffer.write(';');
@@ -106,35 +103,34 @@ public class TestBuffers {
         buffer.write(EncodingUtils.getAsciiBytes("stuff"));
         buffer.produceContent(encoder);
 
-        byte[] content = outstream.toByteArray();
+        final byte[] content = outstream.toByteArray();
         Assert.assertEquals("stuff;more stuff", EncodingUtils.getAsciiString(content));
     }
 
     @Test
     public void testBufferInfo() throws Exception {
-        SimpleOutputBuffer buffer = new SimpleOutputBuffer(8, new DirectByteBufferAllocator());
-        BufferInfo bufferinfo = buffer;
+        final SimpleOutputBuffer buffer = new SimpleOutputBuffer(8, DirectByteBufferAllocator.INSTANCE);
 
-        Assert.assertEquals(0, bufferinfo.length());
-        Assert.assertEquals(8, bufferinfo.available());
+        Assert.assertEquals(0, buffer.length());
+        Assert.assertEquals(8, buffer.available());
         buffer.write(new byte[] {'1', '2', '3', '4'});
-        Assert.assertEquals(4, bufferinfo.length());
-        Assert.assertEquals(4, bufferinfo.available());
+        Assert.assertEquals(4, buffer.length());
+        Assert.assertEquals(4, buffer.available());
         buffer.write(new byte[] {'1', '2', '3', '4', '5', '6', '7', '8'});
-        Assert.assertEquals(12, bufferinfo.length());
-        Assert.assertEquals(0, bufferinfo.available());
+        Assert.assertEquals(12, buffer.length());
+        Assert.assertEquals(0, buffer.available());
     }
 
     @Test
     public void testInputBufferNullInput() throws IOException {
-        SimpleInputBuffer buffer = new SimpleInputBuffer(4, new DirectByteBufferAllocator());
+        final SimpleInputBuffer buffer = new SimpleInputBuffer(4, DirectByteBufferAllocator.INSTANCE);
         Assert.assertEquals(0, buffer.read(null));
         Assert.assertEquals(0, buffer.read(null, 0, 0));
     }
 
     @Test
     public void testOutputBufferNullInput() throws IOException {
-        SimpleOutputBuffer buffer = new SimpleOutputBuffer(4, new DirectByteBufferAllocator());
+        final SimpleOutputBuffer buffer = new SimpleOutputBuffer(4, DirectByteBufferAllocator.INSTANCE);
         buffer.write(null);
         buffer.write(null, 0, 10);
         Assert.assertFalse(buffer.hasData());
@@ -142,7 +138,7 @@ public class TestBuffers {
 
     @Test
     public void testDirectByteBufferAllocator() {
-        DirectByteBufferAllocator allocator = new DirectByteBufferAllocator();
+        final DirectByteBufferAllocator allocator = new DirectByteBufferAllocator();
         ByteBuffer buffer = allocator.allocate(1);
         Assert.assertNotNull(buffer);
         Assert.assertTrue(buffer.isDirect());
@@ -165,7 +161,7 @@ public class TestBuffers {
 
     @Test
     public void testHeapByteBufferAllocator() {
-        HeapByteBufferAllocator allocator = new HeapByteBufferAllocator();
+        final HeapByteBufferAllocator allocator = new HeapByteBufferAllocator();
         ByteBuffer buffer = allocator.allocate(1);
         Assert.assertNotNull(buffer);
         Assert.assertFalse(buffer.isDirect());
diff --git a/httpcore-nio/src/test/java/org/apache/http/testserver/HttpClientNio.java b/httpcore-nio/src/test/java/org/apache/http/testserver/HttpClientNio.java
deleted file mode 100644
index a29e5cb..0000000
--- a/httpcore-nio/src/test/java/org/apache/http/testserver/HttpClientNio.java
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * ====================================================================
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- *
- */
-
-package org.apache.http.testserver;
-
-import java.io.IOException;
-import java.net.InetSocketAddress;
-import java.util.List;
-
-import org.apache.http.impl.nio.DefaultHttpClientIODispatch;
-import org.apache.http.impl.nio.DefaultNHttpClientConnection;
-import org.apache.http.impl.nio.reactor.DefaultConnectingIOReactor;
-import org.apache.http.impl.nio.reactor.ExceptionEvent;
-import org.apache.http.nio.NHttpClientHandler;
-import org.apache.http.nio.NHttpClientEventHandler;
-import org.apache.http.nio.NHttpConnectionFactory;
-import org.apache.http.nio.reactor.ConnectingIOReactor;
-import org.apache.http.nio.reactor.IOEventDispatch;
-import org.apache.http.nio.reactor.IOReactorExceptionHandler;
-import org.apache.http.nio.reactor.IOReactorStatus;
-import org.apache.http.nio.reactor.SessionRequest;
-
- at SuppressWarnings("deprecation")
-public class HttpClientNio {
-
-    private final DefaultConnectingIOReactor ioReactor;
-    private final NHttpConnectionFactory<DefaultNHttpClientConnection> connFactory;
-
-    private volatile IOReactorThread thread;
-
-    public HttpClientNio(
-            final NHttpConnectionFactory<DefaultNHttpClientConnection> connFactory) throws IOException {
-        super();
-        this.ioReactor = new DefaultConnectingIOReactor();
-        this.connFactory = connFactory;
-    }
-
-    public void setExceptionHandler(final IOReactorExceptionHandler exceptionHandler) {
-        this.ioReactor.setExceptionHandler(exceptionHandler);
-    }
-
-    private void execute(final NHttpClientEventHandler clientHandler) throws IOException {
-        IOEventDispatch ioEventDispatch = new DefaultHttpClientIODispatch(clientHandler, this.connFactory);
-        this.ioReactor.execute(ioEventDispatch);
-    }
-
-    public SessionRequest openConnection(final InetSocketAddress address, final Object attachment) {
-        return this.ioReactor.connect(address, null, attachment, null);
-    }
-
-    public void start(final NHttpClientEventHandler clientHandler) {
-        this.thread = new IOReactorThread(clientHandler);
-        this.thread.start();
-    }
-
-    public void start(final NHttpClientHandler handler) {
-        this.thread = new IOReactorThread(new NHttpClientEventHandlerAdaptor(handler));
-        this.thread.start();
-    }
-
-    public ConnectingIOReactor getIoReactor() {
-        return this.ioReactor;
-    }
-
-    public IOReactorStatus getStatus() {
-        return this.ioReactor.getStatus();
-    }
-
-    public List<ExceptionEvent> getAuditLog() {
-        return this.ioReactor.getAuditLog();
-    }
-
-    public void join(long timeout) throws InterruptedException {
-        if (this.thread != null) {
-            this.thread.join(timeout);
-        }
-    }
-
-    public Exception getException() {
-        if (this.thread != null) {
-            return this.thread.getException();
-        } else {
-            return null;
-        }
-    }
-
-    public void shutdown() throws IOException {
-        this.ioReactor.shutdown();
-        try {
-            join(500);
-        } catch (InterruptedException ignore) {
-        }
-    }
-
-    private class IOReactorThread extends Thread {
-
-        private final NHttpClientEventHandler clientHandler;
-
-        private volatile Exception ex;
-
-        public IOReactorThread(final NHttpClientEventHandler clientHandler) {
-            super();
-            this.clientHandler = clientHandler;
-        }
-
-        @Override
-        public void run() {
-            try {
-                execute(this.clientHandler);
-            } catch (Exception ex) {
-                this.ex = ex;
-            }
-        }
-
-        public Exception getException() {
-            return this.ex;
-        }
-
-    }
-
-}
diff --git a/httpcore-nio/src/test/java/org/apache/http/testserver/NHttpClientEventHandlerAdaptor.java b/httpcore-nio/src/test/java/org/apache/http/testserver/NHttpClientEventHandlerAdaptor.java
deleted file mode 100644
index 33c9436..0000000
--- a/httpcore-nio/src/test/java/org/apache/http/testserver/NHttpClientEventHandlerAdaptor.java
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * ====================================================================
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- *
- */
-
-package org.apache.http.testserver;
-
-import java.io.IOException;
-
-import org.apache.http.HttpException;
-import org.apache.http.nio.ContentDecoder;
-import org.apache.http.nio.ContentEncoder;
-import org.apache.http.nio.NHttpClientConnection;
-import org.apache.http.nio.NHttpClientHandler;
-import org.apache.http.nio.NHttpClientEventHandler;
-
- at Deprecated
-class NHttpClientEventHandlerAdaptor implements NHttpClientEventHandler {
-
-    private final NHttpClientHandler handler;
-
-    public NHttpClientEventHandlerAdaptor(final NHttpClientHandler handler) {
-        super();
-        this.handler = handler;
-    }
-
-    public void connected(final NHttpClientConnection conn, final Object attachment) {
-        this.handler.connected(conn, attachment);
-    }
-
-    public void requestReady(
-            final NHttpClientConnection conn) throws IOException, HttpException {
-        this.handler.requestReady(conn);
-    }
-
-    public void responseReceived(
-            final NHttpClientConnection conn) throws IOException, HttpException {
-        this.handler.responseReceived(conn);
-    }
-
-    public void inputReady(
-            final NHttpClientConnection conn,
-            final ContentDecoder decoder) throws IOException, HttpException {
-        this.handler.inputReady(conn, decoder);
-    }
-
-    public void outputReady(
-            final NHttpClientConnection conn,
-            final ContentEncoder encoder) throws IOException, HttpException {
-        this.handler.outputReady(conn, encoder);
-    }
-
-    public void exception(final NHttpClientConnection conn, final Exception ex) {
-        if (ex instanceof HttpException) {
-            this.handler.exception(conn, (HttpException) ex);
-        } else if (ex instanceof IOException) {
-            this.handler.exception(conn, (IOException) ex);
-        } else {
-            if (ex instanceof RuntimeException) {
-                throw (RuntimeException) ex;
-            } else {
-                throw new Error("Unexpected exception: ", ex);
-            }
-        }
-    }
-
-    public void endOfInput(final NHttpClientConnection conn) throws IOException {
-        conn.close();
-    }
-
-    public void timeout(final NHttpClientConnection conn) {
-        this.handler.timeout(conn);
-    }
-
-    public void closed(final NHttpClientConnection conn) {
-        this.handler.closed(conn);
-    }
-
-}
diff --git a/httpcore-nio/src/test/java/org/apache/http/testserver/NHttpServerEventHandlerAdaptor.java b/httpcore-nio/src/test/java/org/apache/http/testserver/NHttpServerEventHandlerAdaptor.java
deleted file mode 100644
index 4ae87d0..0000000
--- a/httpcore-nio/src/test/java/org/apache/http/testserver/NHttpServerEventHandlerAdaptor.java
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * ====================================================================
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- *
- */
-
-package org.apache.http.testserver;
-
-import java.io.IOException;
-
-import org.apache.http.HttpException;
-import org.apache.http.nio.ContentDecoder;
-import org.apache.http.nio.ContentEncoder;
-import org.apache.http.nio.NHttpServerConnection;
-import org.apache.http.nio.NHttpServerEventHandler;
-import org.apache.http.nio.NHttpServiceHandler;
-
- at Deprecated
-class NHttpServerEventHandlerAdaptor implements NHttpServerEventHandler {
-
-    private final NHttpServiceHandler handler;
-
-    public NHttpServerEventHandlerAdaptor(final NHttpServiceHandler handler) {
-        super();
-        this.handler = handler;
-    }
-
-    public void connected(final NHttpServerConnection conn) {
-        this.handler.connected(conn);
-    }
-
-    public void responseReady(
-            final NHttpServerConnection conn) throws IOException, HttpException {
-        this.handler.responseReady(conn);
-    }
-
-    public void requestReceived(
-            final NHttpServerConnection conn) throws IOException, HttpException {
-        this.handler.requestReceived(conn);
-    }
-
-    public void inputReady(
-            final NHttpServerConnection conn,
-            final ContentDecoder decoder) throws IOException, HttpException {
-        this.handler.inputReady(conn, decoder);
-    }
-
-    public void outputReady(
-            final NHttpServerConnection conn,
-            final ContentEncoder encoder) throws IOException, HttpException {
-        this.handler.outputReady(conn, encoder);
-    }
-
-    public void exception(final NHttpServerConnection conn, final Exception ex) {
-        if (ex instanceof HttpException) {
-            this.handler.exception(conn, (HttpException) ex);
-        } else if (ex instanceof IOException) {
-            this.handler.exception(conn, (IOException) ex);
-        } else {
-            if (ex instanceof RuntimeException) {
-                throw (RuntimeException) ex;
-            } else {
-                throw new Error("Unexpected exception: ", ex);
-            }
-        }
-    }
-
-    public void endOfInput(final NHttpServerConnection conn) throws IOException {
-        conn.close();
-    }
-
-    public void timeout(final NHttpServerConnection conn) {
-        this.handler.timeout(conn);
-    }
-
-    public void closed(final NHttpServerConnection conn) {
-        this.handler.closed(conn);
-    }
-
-}
diff --git a/httpcore-osgi/pom.xml b/httpcore-osgi/pom.xml
index 2ab2d05..3fe0663 100644
--- a/httpcore-osgi/pom.xml
+++ b/httpcore-osgi/pom.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<!-- 
+<!--
    ====================================================================
    Licensed to the Apache Software Foundation (ASF) under one
    or more contributor license agreements.  See the NOTICE file
@@ -30,16 +30,16 @@
   <parent>
     <groupId>org.apache.httpcomponents</groupId>
     <artifactId>httpcomponents-core</artifactId>
-    <version>4.2.4</version>
+    <version>4.3</version>
   </parent>
   <artifactId>httpcore-osgi</artifactId>
-  <name>HttpCore OSGi bundle</name>
+  <name>Apache HttpCore OSGi bundle</name>
   <inceptionYear>2005</inceptionYear>
   <description>
    HttpComponents Core (OSGi bundle)
   </description>
   <url>http://hc.apache.org/httpcomponents-core-ga</url>
-  <packaging>bundle</packaging>  
+  <packaging>bundle</packaging>
 
   <dependencies>
     <dependency>
@@ -54,13 +54,6 @@
     </dependency>
   </dependencies>
 
-  <properties>
-    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
-    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
-    <maven.compile.source>1.5</maven.compile.source>
-    <maven.compile.target>1.5</maven.compile.target>
-  </properties>
-
   <build>
     <plugins>
       <plugin>
@@ -76,8 +69,27 @@
           </instructions>
         </configuration>
       </plugin>
+      <plugin>
+        <groupId>org.codehaus.mojo</groupId>
+        <artifactId>clirr-maven-plugin</artifactId>
+        <configuration>
+          <skip>true</skip>
+        </configuration>
+      </plugin>
     </plugins>
     <finalName>org.apache.httpcomponents.httpcore_${project.version}</finalName>
   </build>
 
+  <reporting>
+    <plugins>
+      <plugin>
+        <groupId>org.codehaus.mojo</groupId>
+        <artifactId>clirr-maven-plugin</artifactId>
+        <version>${hc.clirr.version}</version>
+        <configuration>
+          <skip>true</skip>
+        </configuration>
+      </plugin>
+    </plugins>
+  </reporting>
 </project>
diff --git a/LICENSE.txt b/httpcore-osgi/src/main/appended-resources/META-INF/LICENSE
similarity index 53%
copy from LICENSE.txt
copy to httpcore-osgi/src/main/appended-resources/META-INF/LICENSE
index 879d3fd..6285545 100644
--- a/LICENSE.txt
+++ b/httpcore-osgi/src/main/appended-resources/META-INF/LICENSE
@@ -1,186 +1,10 @@
-                                 Apache License
-                           Version 2.0, January 2004
-                        http://www.apache.org/licenses/
-
-   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-   1. Definitions.
-
-      "License" shall mean the terms and conditions for use, reproduction,
-      and distribution as defined by Sections 1 through 9 of this document.
-
-      "Licensor" shall mean the copyright owner or entity authorized by
-      the copyright owner that is granting the License.
-
-      "Legal Entity" shall mean the union of the acting entity and all
-      other entities that control, are controlled by, or are under common
-      control with that entity. For the purposes of this definition,
-      "control" means (i) the power, direct or indirect, to cause the
-      direction or management of such entity, whether by contract or
-      otherwise, or (ii) ownership of fifty percent (50%) or more of the
-      outstanding shares, or (iii) beneficial ownership of such entity.
-
-      "You" (or "Your") shall mean an individual or Legal Entity
-      exercising permissions granted by this License.
-
-      "Source" form shall mean the preferred form for making modifications,
-      including but not limited to software source code, documentation
-      source, and configuration files.
-
-      "Object" form shall mean any form resulting from mechanical
-      transformation or translation of a Source form, including but
-      not limited to compiled object code, generated documentation,
-      and conversions to other media types.
-
-      "Work" shall mean the work of authorship, whether in Source or
-      Object form, made available under the License, as indicated by a
-      copyright notice that is included in or attached to the work
-      (an example is provided in the Appendix below).
-
-      "Derivative Works" shall mean any work, whether in Source or Object
-      form, that is based on (or derived from) the Work and for which the
-      editorial revisions, annotations, elaborations, or other modifications
-      represent, as a whole, an original work of authorship. For the purposes
-      of this License, Derivative Works shall not include works that remain
-      separable from, or merely link (or bind by name) to the interfaces of,
-      the Work and Derivative Works thereof.
-
-      "Contribution" shall mean any work of authorship, including
-      the original version of the Work and any modifications or additions
-      to that Work or Derivative Works thereof, that is intentionally
-      submitted to Licensor for inclusion in the Work by the copyright owner
-      or by an individual or Legal Entity authorized to submit on behalf of
-      the copyright owner. For the purposes of this definition, "submitted"
-      means any form of electronic, verbal, or written communication sent
-      to the Licensor or its representatives, including but not limited to
-      communication on electronic mailing lists, source code control systems,
-      and issue tracking systems that are managed by, or on behalf of, the
-      Licensor for the purpose of discussing and improving the Work, but
-      excluding communication that is conspicuously marked or otherwise
-      designated in writing by the copyright owner as "Not a Contribution."
-
-      "Contributor" shall mean Licensor and any individual or Legal Entity
-      on behalf of whom a Contribution has been received by Licensor and
-      subsequently incorporated within the Work.
-
-   2. Grant of Copyright License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      copyright license to reproduce, prepare Derivative Works of,
-      publicly display, publicly perform, sublicense, and distribute the
-      Work and such Derivative Works in Source or Object form.
-
-   3. Grant of Patent License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      (except as stated in this section) patent license to make, have made,
-      use, offer to sell, sell, import, and otherwise transfer the Work,
-      where such license applies only to those patent claims licensable
-      by such Contributor that are necessarily infringed by their
-      Contribution(s) alone or by combination of their Contribution(s)
-      with the Work to which such Contribution(s) was submitted. If You
-      institute patent litigation against any entity (including a
-      cross-claim or counterclaim in a lawsuit) alleging that the Work
-      or a Contribution incorporated within the Work constitutes direct
-      or contributory patent infringement, then any patent licenses
-      granted to You under this License for that Work shall terminate
-      as of the date such litigation is filed.
-
-   4. Redistribution. You may reproduce and distribute copies of the
-      Work or Derivative Works thereof in any medium, with or without
-      modifications, and in Source or Object form, provided that You
-      meet the following conditions:
-
-      (a) You must give any other recipients of the Work or
-          Derivative Works a copy of this License; and
-
-      (b) You must cause any modified files to carry prominent notices
-          stating that You changed the files; and
-
-      (c) You must retain, in the Source form of any Derivative Works
-          that You distribute, all copyright, patent, trademark, and
-          attribution notices from the Source form of the Work,
-          excluding those notices that do not pertain to any part of
-          the Derivative Works; and
-
-      (d) If the Work includes a "NOTICE" text file as part of its
-          distribution, then any Derivative Works that You distribute must
-          include a readable copy of the attribution notices contained
-          within such NOTICE file, excluding those notices that do not
-          pertain to any part of the Derivative Works, in at least one
-          of the following places: within a NOTICE text file distributed
-          as part of the Derivative Works; within the Source form or
-          documentation, if provided along with the Derivative Works; or,
-          within a display generated by the Derivative Works, if and
-          wherever such third-party notices normally appear. The contents
-          of the NOTICE file are for informational purposes only and
-          do not modify the License. You may add Your own attribution
-          notices within Derivative Works that You distribute, alongside
-          or as an addendum to the NOTICE text from the Work, provided
-          that such additional attribution notices cannot be construed
-          as modifying the License.
-
-      You may add Your own copyright statement to Your modifications and
-      may provide additional or different license terms and conditions
-      for use, reproduction, or distribution of Your modifications, or
-      for any such Derivative Works as a whole, provided Your use,
-      reproduction, and distribution of the Work otherwise complies with
-      the conditions stated in this License.
-
-   5. Submission of Contributions. Unless You explicitly state otherwise,
-      any Contribution intentionally submitted for inclusion in the Work
-      by You to the Licensor shall be under the terms and conditions of
-      this License, without any additional terms or conditions.
-      Notwithstanding the above, nothing herein shall supersede or modify
-      the terms of any separate license agreement you may have executed
-      with Licensor regarding such Contributions.
-
-   6. Trademarks. This License does not grant permission to use the trade
-      names, trademarks, service marks, or product names of the Licensor,
-      except as required for reasonable and customary use in describing the
-      origin of the Work and reproducing the content of the NOTICE file.
-
-   7. Disclaimer of Warranty. Unless required by applicable law or
-      agreed to in writing, Licensor provides the Work (and each
-      Contributor provides its Contributions) on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-      implied, including, without limitation, any warranties or conditions
-      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-      PARTICULAR PURPOSE. You are solely responsible for determining the
-      appropriateness of using or redistributing the Work and assume any
-      risks associated with Your exercise of permissions under this License.
-
-   8. Limitation of Liability. In no event and under no legal theory,
-      whether in tort (including negligence), contract, or otherwise,
-      unless required by applicable law (such as deliberate and grossly
-      negligent acts) or agreed to in writing, shall any Contributor be
-      liable to You for damages, including any direct, indirect, special,
-      incidental, or consequential damages of any character arising as a
-      result of this License or out of the use or inability to use the
-      Work (including but not limited to damages for loss of goodwill,
-      work stoppage, computer failure or malfunction, or any and all
-      other commercial damages or losses), even if such Contributor
-      has been advised of the possibility of such damages.
-
-   9. Accepting Warranty or Additional Liability. While redistributing
-      the Work or Derivative Works thereof, You may choose to offer,
-      and charge a fee for, acceptance of support, warranty, indemnity,
-      or other liability obligations and/or rights consistent with this
-      License. However, in accepting such obligations, You may act only
-      on Your own behalf and on Your sole responsibility, not on behalf
-      of any other Contributor, and only if You agree to indemnify,
-      defend, and hold each Contributor harmless for any liability
-      incurred by, or claims asserted against, such Contributor by reason
-      of your accepting any such warranty or additional liability.
-
-   END OF TERMS AND CONDITIONS
 
 =========================================================================
 
 This project contains annotations in the package org.apache.http.annotation
-which are derived from JCIP-ANNOTATIONS 
+which are derived from JCIP-ANNOTATIONS
 Copyright (c) 2005 Brian Goetz and Tim Peierls.
-See http://www.jcip.net and the Creative Commons Attribution License 
+See http://www.jcip.net and the Creative Commons Attribution License
 (http://creativecommons.org/licenses/by/2.5)
 Full text: http://creativecommons.org/licenses/by/2.5/legalcode
 
diff --git a/httpcore-osgi/src/main/appended-resources/META-INF/NOTICE b/httpcore-osgi/src/main/appended-resources/META-INF/NOTICE
new file mode 100644
index 0000000..b2660ff
--- /dev/null
+++ b/httpcore-osgi/src/main/appended-resources/META-INF/NOTICE
@@ -0,0 +1,2 @@
+This project contains annotations derived from JCIP-ANNOTATIONS
+Copyright (c) 2005 Brian Goetz and Tim Peierls. See http://www.jcip.net
diff --git a/httpcore/pom.xml b/httpcore/pom.xml
index 9b601f5..1c9c5be 100644
--- a/httpcore/pom.xml
+++ b/httpcore/pom.xml
@@ -30,10 +30,10 @@
   <parent>
     <groupId>org.apache.httpcomponents</groupId>
     <artifactId>httpcomponents-core</artifactId>
-    <version>4.2.4</version>
+    <version>4.3</version>
   </parent>
   <artifactId>httpcore</artifactId>
-  <name>HttpCore</name>
+  <name>Apache HttpCore</name>
   <inceptionYear>2005</inceptionYear>
   <description>
    HttpComponents Core (blocking I/O)
@@ -41,20 +41,6 @@
   <url>http://hc.apache.org/httpcomponents-core-ga</url>
   <packaging>jar</packaging>
 
-  <properties>
-    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
-    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
-    <maven.compile.source>1.5</maven.compile.source>
-    <maven.compile.target>1.5</maven.compile.target>
-    <maven.compile.optimize>true</maven.compile.optimize>
-    <maven.compile.deprecation>true</maven.compile.deprecation>
-    <!-- default compiler and surefire plugin settings for "java" profiles -->
-    <httpcore.compiler.fork>false</httpcore.compiler.fork>
-    <httpcore.compiler.compilerVersion />
-    <httpcore.compiler.javac />
-    <httpcore.surefire.java />
-  </properties>
-
   <dependencies>
     <dependency>
       <groupId>junit</groupId>
@@ -66,6 +52,11 @@
       <artifactId>mockito-core</artifactId>
       <scope>test</scope>
     </dependency>
+    <dependency>
+      <groupId>commons-logging</groupId>
+      <artifactId>commons-logging</artifactId>
+      <scope>test</scope>
+    </dependency>
   </dependencies>
 
   <build>
@@ -80,39 +71,21 @@
     </resources>
     <plugins>
       <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-compiler-plugin</artifactId>
-        <configuration>
-          <source>${maven.compile.source}</source>
-          <target>${maven.compile.target}</target>
-          <optimize>${maven.compile.optimize}</optimize>
-          <showDeprecations>${maven.compile.deprecation}</showDeprecations>
-          <fork>${httpcore.compiler.fork}</fork>
-          <compilerVersion>${httpcore.compiler.compilerVersion}</compilerVersion>
-          <executable>${httpcore.compiler.javac}</executable>
-        </configuration>
-      </plugin>
-      <plugin>
-        <artifactId>maven-surefire-plugin</artifactId>
-        <configuration>
-          <jvm>${httpcore.surefire.java}</jvm>
-        </configuration>
-      </plugin>
-      <plugin>
-        <groupId>com.atlassian.maven.plugins</groupId>
-        <artifactId>maven-clover2-plugin</artifactId>
-        <configuration>
-          <flushPolicy>threaded</flushPolicy>
-          <flushInterval>100</flushInterval>
-          <targetPercentage>50%</targetPercentage>
-        </configuration>
+        <groupId>org.codehaus.mojo</groupId>
+        <artifactId>build-helper-maven-plugin</artifactId>
+        <version>1.8</version>
         <executions>
           <execution>
-            <id>site</id>
-            <phase>pre-site</phase>
-            <goals>
-              <goal>instrument</goal>
-            </goals>
+          <id>add-source</id>
+          <phase>generate-sources</phase>
+          <goals>
+            <goal>add-source</goal>
+          </goals>
+          <configuration>
+            <sources>
+              <source>src/main/java-deprecated</source>
+            </sources>
+            </configuration>
           </execution>
         </executions>
       </plugin>
@@ -128,7 +101,7 @@
         <configuration>
           <!-- reduce console output. Can override with -Dquiet=false -->
           <quiet>true</quiet>
-          <source>1.5</source>
+          <source>${maven.compiler.source}</source>
           <links>
             <link>http://download.oracle.com/javase/1.5.0/docs/api/</link>
           </links>
@@ -143,15 +116,6 @@
       </plugin>
 
       <plugin>
-        <groupId>com.atlassian.maven.plugins</groupId>
-        <artifactId>maven-clover2-plugin</artifactId>
-        <version>${clover.version}</version>
-        <configuration>
-          <jdk>1.5</jdk>
-        </configuration>
-      </plugin>
-
-      <plugin>
         <artifactId>maven-jxr-plugin</artifactId>
         <version>${hc.jxr.version}</version>
       </plugin>
diff --git a/httpcore/src/examples/org/apache/http/examples/ElementalHttpGet.java b/httpcore/src/examples/org/apache/http/examples/ElementalHttpGet.java
index f1b2e42..af89f3d 100644
--- a/httpcore/src/examples/org/apache/http/examples/ElementalHttpGet.java
+++ b/httpcore/src/examples/org/apache/http/examples/ElementalHttpGet.java
@@ -31,21 +31,14 @@ import java.net.Socket;
 
 import org.apache.http.ConnectionReuseStrategy;
 import org.apache.http.HttpHost;
-import org.apache.http.HttpRequestInterceptor;
 import org.apache.http.HttpResponse;
-import org.apache.http.HttpVersion;
+import org.apache.http.impl.DefaultBHttpClientConnection;
 import org.apache.http.impl.DefaultConnectionReuseStrategy;
-import org.apache.http.impl.DefaultHttpClientConnection;
 import org.apache.http.message.BasicHttpRequest;
-import org.apache.http.params.HttpParams;
-import org.apache.http.params.HttpProtocolParams;
-import org.apache.http.params.SyncBasicHttpParams;
-import org.apache.http.protocol.HttpContext;
-import org.apache.http.protocol.BasicHttpContext;
-import org.apache.http.protocol.ExecutionContext;
+import org.apache.http.protocol.HttpCoreContext;
 import org.apache.http.protocol.HttpProcessor;
+import org.apache.http.protocol.HttpProcessorBuilder;
 import org.apache.http.protocol.HttpRequestExecutor;
-import org.apache.http.protocol.ImmutableHttpProcessor;
 import org.apache.http.protocol.RequestConnControl;
 import org.apache.http.protocol.RequestContent;
 import org.apache.http.protocol.RequestExpectContinue;
@@ -55,39 +48,25 @@ import org.apache.http.util.EntityUtils;
 
 /**
  * Elemental example for executing multiple GET requests sequentially.
- * <p>
- * Please note the purpose of this application is demonstrate the usage of HttpCore APIs.
- * It is NOT intended to demonstrate the most efficient way of building an HTTP client.
  */
 public class ElementalHttpGet {
 
     public static void main(String[] args) throws Exception {
-
-        HttpParams params = new SyncBasicHttpParams();
-        HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
-        HttpProtocolParams.setContentCharset(params, "UTF-8");
-        HttpProtocolParams.setUserAgent(params, "HttpComponents/1.1");
-        HttpProtocolParams.setUseExpectContinue(params, true);
-
-        HttpProcessor httpproc = new ImmutableHttpProcessor(new HttpRequestInterceptor[] {
-                // Required protocol interceptors
-                new RequestContent(),
-                new RequestTargetHost(),
-                // Recommended protocol interceptors
-                new RequestConnControl(),
-                new RequestUserAgent(),
-                new RequestExpectContinue()});
+        HttpProcessor httpproc = HttpProcessorBuilder.create()
+            .add(new RequestContent())
+            .add(new RequestTargetHost())
+            .add(new RequestConnControl())
+            .add(new RequestUserAgent("Test/1.1"))
+            .add(new RequestExpectContinue(true)).build();
 
         HttpRequestExecutor httpexecutor = new HttpRequestExecutor();
 
-        HttpContext context = new BasicHttpContext(null);
+        HttpCoreContext coreContext = HttpCoreContext.create();
         HttpHost host = new HttpHost("localhost", 8080);
+        coreContext.setTargetHost(host);
 
-        DefaultHttpClientConnection conn = new DefaultHttpClientConnection();
-        ConnectionReuseStrategy connStrategy = new DefaultConnectionReuseStrategy();
-
-        context.setAttribute(ExecutionContext.HTTP_CONNECTION, conn);
-        context.setAttribute(ExecutionContext.HTTP_TARGET_HOST, host);
+        DefaultBHttpClientConnection conn = new DefaultBHttpClientConnection(8 * 1024);
+        ConnectionReuseStrategy connStrategy = DefaultConnectionReuseStrategy.INSTANCE;
 
         try {
 
@@ -99,21 +78,19 @@ public class ElementalHttpGet {
             for (int i = 0; i < targets.length; i++) {
                 if (!conn.isOpen()) {
                     Socket socket = new Socket(host.getHostName(), host.getPort());
-                    conn.bind(socket, params);
+                    conn.bind(socket);
                 }
                 BasicHttpRequest request = new BasicHttpRequest("GET", targets[i]);
                 System.out.println(">> Request URI: " + request.getRequestLine().getUri());
 
-                request.setParams(params);
-                httpexecutor.preProcess(request, httpproc, context);
-                HttpResponse response = httpexecutor.execute(request, conn, context);
-                response.setParams(params);
-                httpexecutor.postProcess(response, httpproc, context);
+                httpexecutor.preProcess(request, httpproc, coreContext);
+                HttpResponse response = httpexecutor.execute(request, conn, coreContext);
+                httpexecutor.postProcess(response, httpproc, coreContext);
 
                 System.out.println("<< Response: " + response.getStatusLine());
                 System.out.println(EntityUtils.toString(response.getEntity()));
                 System.out.println("==============");
-                if (!connStrategy.keepAlive(response, context)) {
+                if (!connStrategy.keepAlive(response, coreContext)) {
                     conn.close();
                 } else {
                     System.out.println("Connection kept alive...");
diff --git a/httpcore/src/examples/org/apache/http/examples/ElementalHttpPost.java b/httpcore/src/examples/org/apache/http/examples/ElementalHttpPost.java
index 09aca7b..e6201fb 100644
--- a/httpcore/src/examples/org/apache/http/examples/ElementalHttpPost.java
+++ b/httpcore/src/examples/org/apache/http/examples/ElementalHttpPost.java
@@ -31,26 +31,21 @@ import java.io.ByteArrayInputStream;
 import java.net.Socket;
 
 import org.apache.http.ConnectionReuseStrategy;
+import org.apache.http.Consts;
 import org.apache.http.HttpEntity;
 import org.apache.http.HttpHost;
-import org.apache.http.HttpRequestInterceptor;
 import org.apache.http.HttpResponse;
-import org.apache.http.HttpVersion;
 import org.apache.http.entity.ByteArrayEntity;
+import org.apache.http.entity.ContentType;
 import org.apache.http.entity.InputStreamEntity;
 import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.DefaultBHttpClientConnection;
 import org.apache.http.impl.DefaultConnectionReuseStrategy;
-import org.apache.http.impl.DefaultHttpClientConnection;
 import org.apache.http.message.BasicHttpEntityEnclosingRequest;
-import org.apache.http.params.HttpParams;
-import org.apache.http.params.HttpProtocolParams;
-import org.apache.http.params.SyncBasicHttpParams;
-import org.apache.http.protocol.HttpContext;
-import org.apache.http.protocol.BasicHttpContext;
-import org.apache.http.protocol.ExecutionContext;
+import org.apache.http.protocol.HttpCoreContext;
 import org.apache.http.protocol.HttpProcessor;
+import org.apache.http.protocol.HttpProcessorBuilder;
 import org.apache.http.protocol.HttpRequestExecutor;
-import org.apache.http.protocol.ImmutableHttpProcessor;
 import org.apache.http.protocol.RequestConnControl;
 import org.apache.http.protocol.RequestContent;
 import org.apache.http.protocol.RequestExpectContinue;
@@ -60,74 +55,60 @@ import org.apache.http.util.EntityUtils;
 
 /**
  * Elemental example for executing multiple POST requests sequentially.
- * <p>
- * Please note the purpose of this application is demonstrate the usage of HttpCore APIs.
- * It is NOT intended to demonstrate the most efficient way of building an HTTP client.
  */
 public class ElementalHttpPost {
 
     public static void main(String[] args) throws Exception {
-
-        HttpParams params = new SyncBasicHttpParams();
-        HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
-        HttpProtocolParams.setContentCharset(params, "UTF-8");
-        HttpProtocolParams.setUserAgent(params, "Test/1.1");
-        HttpProtocolParams.setUseExpectContinue(params, true);
-
-        HttpProcessor httpproc = new ImmutableHttpProcessor(new HttpRequestInterceptor[] {
-                // Required protocol interceptors
-                new RequestContent(),
-                new RequestTargetHost(),
-                // Recommended protocol interceptors
-                new RequestConnControl(),
-                new RequestUserAgent(),
-                new RequestExpectContinue()});
+        HttpProcessor httpproc = HttpProcessorBuilder.create()
+            .add(new RequestContent())
+            .add(new RequestTargetHost())
+            .add(new RequestConnControl())
+            .add(new RequestUserAgent("Test/1.1"))
+            .add(new RequestExpectContinue(true)).build();
 
         HttpRequestExecutor httpexecutor = new HttpRequestExecutor();
 
-        HttpContext context = new BasicHttpContext(null);
-
+        HttpCoreContext coreContext = HttpCoreContext.create();
         HttpHost host = new HttpHost("localhost", 8080);
+        coreContext.setTargetHost(host);
 
-        DefaultHttpClientConnection conn = new DefaultHttpClientConnection();
-        ConnectionReuseStrategy connStrategy = new DefaultConnectionReuseStrategy();
-
-        context.setAttribute(ExecutionContext.HTTP_CONNECTION, conn);
-        context.setAttribute(ExecutionContext.HTTP_TARGET_HOST, host);
+        DefaultBHttpClientConnection conn = new DefaultBHttpClientConnection(8 * 1024);
+        ConnectionReuseStrategy connStrategy = DefaultConnectionReuseStrategy.INSTANCE;
 
         try {
 
             HttpEntity[] requestBodies = {
                     new StringEntity(
-                            "This is the first test request", "UTF-8"),
+                            "This is the first test request",
+                            ContentType.create("text/plain", Consts.UTF_8)),
                     new ByteArrayEntity(
-                            "This is the second test request".getBytes("UTF-8")),
+                            "This is the second test request".getBytes("UTF-8"),
+                            ContentType.APPLICATION_OCTET_STREAM),
                     new InputStreamEntity(
                             new ByteArrayInputStream(
                                     "This is the third test request (will be chunked)"
-                                    .getBytes("UTF-8")), -1)
+                                    .getBytes("UTF-8")),
+                            ContentType.APPLICATION_OCTET_STREAM)
             };
 
             for (int i = 0; i < requestBodies.length; i++) {
                 if (!conn.isOpen()) {
                     Socket socket = new Socket(host.getHostName(), host.getPort());
-                    conn.bind(socket, params);
+                    conn.bind(socket);
                 }
                 BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST",
                         "/servlets-examples/servlet/RequestInfoExample");
                 request.setEntity(requestBodies[i]);
                 System.out.println(">> Request URI: " + request.getRequestLine().getUri());
 
-                request.setParams(params);
-                httpexecutor.preProcess(request, httpproc, context);
-                HttpResponse response = httpexecutor.execute(request, conn, context);
-                response.setParams(params);
-                httpexecutor.postProcess(response, httpproc, context);
+                httpexecutor.preProcess(request, httpproc, coreContext);
+                HttpResponse response = httpexecutor.execute(request, conn, coreContext);
+                httpexecutor.postProcess(response, httpproc, coreContext);
 
                 System.out.println("<< Response: " + response.getStatusLine());
                 System.out.println(EntityUtils.toString(response.getEntity()));
                 System.out.println("==============");
-                if (!connStrategy.keepAlive(response, context)) {
+                if (!connStrategy.keepAlive(response, coreContext)) {
                     conn.close();
                 } else {
                     System.out.println("Connection kept alive...");
diff --git a/httpcore/src/examples/org/apache/http/examples/ElementalHttpServer.java b/httpcore/src/examples/org/apache/http/examples/ElementalHttpServer.java
index 71531cc..0335bfb 100644
--- a/httpcore/src/examples/org/apache/http/examples/ElementalHttpServer.java
+++ b/httpcore/src/examples/org/apache/http/examples/ElementalHttpServer.java
@@ -32,50 +32,47 @@ import java.io.IOException;
 import java.io.InterruptedIOException;
 import java.net.ServerSocket;
 import java.net.Socket;
+import java.net.URL;
 import java.net.URLDecoder;
 import java.nio.charset.Charset;
+import java.security.KeyStore;
 import java.util.Locale;
 
 import org.apache.http.ConnectionClosedException;
+import org.apache.http.HttpConnectionFactory;
 import org.apache.http.HttpEntity;
 import org.apache.http.HttpEntityEnclosingRequest;
 import org.apache.http.HttpException;
 import org.apache.http.HttpRequest;
 import org.apache.http.HttpResponse;
-import org.apache.http.HttpResponseInterceptor;
 import org.apache.http.HttpServerConnection;
 import org.apache.http.HttpStatus;
 import org.apache.http.MethodNotSupportedException;
 import org.apache.http.entity.ContentType;
 import org.apache.http.entity.FileEntity;
 import org.apache.http.entity.StringEntity;
-import org.apache.http.impl.DefaultConnectionReuseStrategy;
-import org.apache.http.impl.DefaultHttpResponseFactory;
-import org.apache.http.impl.DefaultHttpServerConnection;
-import org.apache.http.params.CoreConnectionPNames;
-import org.apache.http.params.HttpParams;
-import org.apache.http.params.CoreProtocolPNames;
-import org.apache.http.params.SyncBasicHttpParams;
-import org.apache.http.protocol.HttpContext;
+import org.apache.http.impl.DefaultBHttpServerConnection;
+import org.apache.http.impl.DefaultBHttpServerConnectionFactory;
 import org.apache.http.protocol.BasicHttpContext;
+import org.apache.http.protocol.HttpContext;
 import org.apache.http.protocol.HttpProcessor;
+import org.apache.http.protocol.HttpProcessorBuilder;
 import org.apache.http.protocol.HttpRequestHandler;
-import org.apache.http.protocol.HttpRequestHandlerRegistry;
 import org.apache.http.protocol.HttpService;
-import org.apache.http.protocol.ImmutableHttpProcessor;
 import org.apache.http.protocol.ResponseConnControl;
 import org.apache.http.protocol.ResponseContent;
 import org.apache.http.protocol.ResponseDate;
 import org.apache.http.protocol.ResponseServer;
+import org.apache.http.protocol.UriHttpRequestHandlerMapper;
 import org.apache.http.util.EntityUtils;
 
+import javax.net.ssl.KeyManager;
+import javax.net.ssl.KeyManagerFactory;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLServerSocketFactory;
+
 /**
  * Basic, yet fully functional and spec compliant, HTTP/1.1 file server.
- * <p>
- * Please note the purpose of this application is demonstrate the usage of HttpCore APIs.
- * It is NOT intended to demonstrate the most efficient way of building an HTTP file server.
- *
- *
  */
 public class ElementalHttpServer {
 
@@ -84,7 +81,48 @@ public class ElementalHttpServer {
             System.err.println("Please specify document root directory");
             System.exit(1);
         }
-        Thread t = new RequestListenerThread(8080, args[0]);
+        // Document root directory
+        String docRoot = args[0];
+        int port = 8080;
+        if (args.length >= 2) {
+            port = Integer.parseInt(args[1]);
+        }
+
+        // Set up the HTTP protocol processor
+        HttpProcessor httpproc = HttpProcessorBuilder.create()
+                .add(new ResponseDate())
+                .add(new ResponseServer("Test/1.1"))
+                .add(new ResponseContent())
+                .add(new ResponseConnControl()).build();
+
+        // Set up request handlers
+        UriHttpRequestHandlerMapper reqistry = new UriHttpRequestHandlerMapper();
+        reqistry.register("*", new HttpFileHandler(docRoot));
+
+        // Set up the HTTP service
+        HttpService httpService = new HttpService(httpproc, reqistry);
+
+        SSLServerSocketFactory sf = null;
+        if (port == 8443) {
+            // Initialize SSL context
+            ClassLoader cl = ElementalHttpServer.class.getClassLoader();
+            URL url = cl.getResource("my.keystore");
+            if (url == null) {
+                System.out.println("Keystore not found");
+                System.exit(1);
+            }
+            KeyStore keystore  = KeyStore.getInstance("jks");
+            keystore.load(url.openStream(), "secret".toCharArray());
+            KeyManagerFactory kmfactory = KeyManagerFactory.getInstance(
+                    KeyManagerFactory.getDefaultAlgorithm());
+            kmfactory.init(keystore, "secret".toCharArray());
+            KeyManager[] keymanagers = kmfactory.getKeyManagers();
+            SSLContext sslcontext = SSLContext.getInstance("TLS");
+            sslcontext.init(keymanagers, null, null);
+            sf = sslcontext.getServerSocketFactory();
+        }
+
+        Thread t = new RequestListenerThread(port, httpService, sf);
         t.setDaemon(false);
         t.start();
     }
@@ -148,39 +186,17 @@ public class ElementalHttpServer {
 
     static class RequestListenerThread extends Thread {
 
+        private final HttpConnectionFactory<DefaultBHttpServerConnection> connFactory;
         private final ServerSocket serversocket;
-        private final HttpParams params;
         private final HttpService httpService;
 
-        public RequestListenerThread(int port, final String docroot) throws IOException {
-            this.serversocket = new ServerSocket(port);
-            this.params = new SyncBasicHttpParams();
-            this.params
-                .setIntParameter(CoreConnectionPNames.SO_TIMEOUT, 5000)
-                .setIntParameter(CoreConnectionPNames.SOCKET_BUFFER_SIZE, 8 * 1024)
-                .setBooleanParameter(CoreConnectionPNames.STALE_CONNECTION_CHECK, false)
-                .setBooleanParameter(CoreConnectionPNames.TCP_NODELAY, true)
-                .setParameter(CoreProtocolPNames.ORIGIN_SERVER, "HttpComponents/1.1");
-
-            // Set up the HTTP protocol processor
-            HttpProcessor httpproc = new ImmutableHttpProcessor(new HttpResponseInterceptor[] {
-                    new ResponseDate(),
-                    new ResponseServer(),
-                    new ResponseContent(),
-                    new ResponseConnControl()
-            });
-
-            // Set up request handlers
-            HttpRequestHandlerRegistry reqistry = new HttpRequestHandlerRegistry();
-            reqistry.register("*", new HttpFileHandler(docroot));
-
-            // Set up the HTTP service
-            this.httpService = new HttpService(
-                    httpproc,
-                    new DefaultConnectionReuseStrategy(),
-                    new DefaultHttpResponseFactory(),
-                    reqistry,
-                    this.params);
+        public RequestListenerThread(
+                final int port,
+                final HttpService httpService,
+                final SSLServerSocketFactory sf) throws IOException {
+            this.connFactory = DefaultBHttpServerConnectionFactory.INSTANCE;
+            this.serversocket = sf != null ? sf.createServerSocket(port) : new ServerSocket(port);
+            this.httpService = httpService;
         }
 
         @Override
@@ -190,9 +206,8 @@ public class ElementalHttpServer {
                 try {
                     // Set up HTTP connection
                     Socket socket = this.serversocket.accept();
-                    DefaultHttpServerConnection conn = new DefaultHttpServerConnection();
                     System.out.println("Incoming connection from " + socket.getInetAddress());
-                    conn.bind(socket, this.params);
+                    HttpServerConnection conn = this.connFactory.createConnection(socket);
 
                     // Start worker thread
                     Thread t = new WorkerThread(this.httpService, conn);
diff --git a/httpcore/src/examples/org/apache/http/examples/ElementalPoolingHttpGet.java b/httpcore/src/examples/org/apache/http/examples/ElementalPoolingHttpGet.java
index 33871e0..4668ff6 100644
--- a/httpcore/src/examples/org/apache/http/examples/ElementalPoolingHttpGet.java
+++ b/httpcore/src/examples/org/apache/http/examples/ElementalPoolingHttpGet.java
@@ -34,23 +34,16 @@ import org.apache.http.ConnectionReuseStrategy;
 import org.apache.http.HttpClientConnection;
 import org.apache.http.HttpException;
 import org.apache.http.HttpHost;
-import org.apache.http.HttpRequestInterceptor;
 import org.apache.http.HttpResponse;
-import org.apache.http.HttpVersion;
 import org.apache.http.impl.DefaultConnectionReuseStrategy;
 import org.apache.http.impl.pool.BasicConnFactory;
 import org.apache.http.impl.pool.BasicConnPool;
 import org.apache.http.impl.pool.BasicPoolEntry;
 import org.apache.http.message.BasicHttpRequest;
-import org.apache.http.params.HttpParams;
-import org.apache.http.params.HttpProtocolParams;
-import org.apache.http.params.SyncBasicHttpParams;
-import org.apache.http.protocol.BasicHttpContext;
-import org.apache.http.protocol.ExecutionContext;
-import org.apache.http.protocol.HttpContext;
+import org.apache.http.protocol.HttpCoreContext;
 import org.apache.http.protocol.HttpProcessor;
+import org.apache.http.protocol.HttpProcessorBuilder;
 import org.apache.http.protocol.HttpRequestExecutor;
-import org.apache.http.protocol.ImmutableHttpProcessor;
 import org.apache.http.protocol.RequestConnControl;
 import org.apache.http.protocol.RequestContent;
 import org.apache.http.protocol.RequestExpectContinue;
@@ -61,32 +54,20 @@ import org.apache.http.util.EntityUtils;
 /**
  * Elemental example for executing multiple GET requests from different threads using a connection
  * pool.
- * <p>
- * Please note the purpose of this application is demonstrate the usage of HttpCore APIs.
- * It is NOT intended to demonstrate the most efficient way of building an HTTP client.
  */
 public class ElementalPoolingHttpGet {
 
     public static void main(String[] args) throws Exception {
-
-        final HttpParams params = new SyncBasicHttpParams();
-        HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
-        HttpProtocolParams.setContentCharset(params, "UTF-8");
-        HttpProtocolParams.setUserAgent(params, "Test/1.1");
-        HttpProtocolParams.setUseExpectContinue(params, true);
-
-        final HttpProcessor httpproc = new ImmutableHttpProcessor(new HttpRequestInterceptor[] {
-                // Required protocol interceptors
-                new RequestContent(),
-                new RequestTargetHost(),
-                // Recommended protocol interceptors
-                new RequestConnControl(),
-                new RequestUserAgent(),
-                new RequestExpectContinue()});
+        final HttpProcessor httpproc = HttpProcessorBuilder.create()
+            .add(new RequestContent())
+            .add(new RequestTargetHost())
+            .add(new RequestConnControl())
+            .add(new RequestUserAgent("Test/1.1"))
+            .add(new RequestExpectContinue(true)).build();
 
         final HttpRequestExecutor httpexecutor = new HttpRequestExecutor();
 
-        final BasicConnPool pool = new BasicConnPool(new BasicConnFactory(params));
+        final BasicConnPool pool = new BasicConnPool(new BasicConnFactory());
         pool.setDefaultMaxPerRoute(2);
         pool.setMaxTotal(2);
 
@@ -107,6 +88,7 @@ public class ElementalPoolingHttpGet {
 
             @Override
             public void run() {
+                ConnectionReuseStrategy connStrategy = DefaultConnectionReuseStrategy.INSTANCE;
                 try {
                     Future<BasicPoolEntry> future = pool.lease(this.target, null);
 
@@ -114,24 +96,20 @@ public class ElementalPoolingHttpGet {
                     BasicPoolEntry entry = future.get();
                     try {
                         HttpClientConnection conn = entry.getConnection();
-                        HttpContext context = new BasicHttpContext(null);
-                        context.setAttribute(ExecutionContext.HTTP_CONNECTION, conn);
-                        context.setAttribute(ExecutionContext.HTTP_TARGET_HOST, this.target);
+                        HttpCoreContext coreContext = HttpCoreContext.create();
+                        coreContext.setTargetHost(this.target);
 
                         BasicHttpRequest request = new BasicHttpRequest("GET", "/");
                         System.out.println(">> Request URI: " + request.getRequestLine().getUri());
 
-                        request.setParams(params);
-                        httpexecutor.preProcess(request, httpproc, context);
-                        HttpResponse response = httpexecutor.execute(request, conn, context);
-                        response.setParams(params);
-                        httpexecutor.postProcess(response, httpproc, context);
+                        httpexecutor.preProcess(request, httpproc, coreContext);
+                        HttpResponse response = httpexecutor.execute(request, conn, coreContext);
+                        httpexecutor.postProcess(response, httpproc, coreContext);
 
                         System.out.println("<< Response: " + response.getStatusLine());
                         System.out.println(EntityUtils.toString(response.getEntity()));
 
-                        ConnectionReuseStrategy connStrategy = new DefaultConnectionReuseStrategy();
-                        reusable = connStrategy.keepAlive(response, context);
+                        reusable = connStrategy.keepAlive(response, coreContext);
                     } catch (IOException ex) {
                         throw ex;
                     } catch (HttpException ex) {
diff --git a/httpcore/src/examples/org/apache/http/examples/ElementalReverseProxy.java b/httpcore/src/examples/org/apache/http/examples/ElementalReverseProxy.java
index 68f9ead..011fb42 100644
--- a/httpcore/src/examples/org/apache/http/examples/ElementalReverseProxy.java
+++ b/httpcore/src/examples/org/apache/http/examples/ElementalReverseProxy.java
@@ -42,22 +42,16 @@ import org.apache.http.HttpRequestInterceptor;
 import org.apache.http.HttpResponse;
 import org.apache.http.HttpResponseInterceptor;
 import org.apache.http.HttpServerConnection;
+import org.apache.http.impl.DefaultBHttpClientConnection;
+import org.apache.http.impl.DefaultBHttpServerConnection;
 import org.apache.http.impl.DefaultConnectionReuseStrategy;
-import org.apache.http.impl.DefaultHttpClientConnection;
-import org.apache.http.impl.DefaultHttpResponseFactory;
-import org.apache.http.impl.DefaultHttpServerConnection;
-import org.apache.http.params.CoreConnectionPNames;
-import org.apache.http.params.CoreProtocolPNames;
-import org.apache.http.params.HttpParams;
-import org.apache.http.params.SyncBasicHttpParams;
 import org.apache.http.protocol.BasicHttpContext;
-import org.apache.http.protocol.ExecutionContext;
 import org.apache.http.protocol.HTTP;
 import org.apache.http.protocol.HttpContext;
+import org.apache.http.protocol.HttpCoreContext;
 import org.apache.http.protocol.HttpProcessor;
 import org.apache.http.protocol.HttpRequestExecutor;
 import org.apache.http.protocol.HttpRequestHandler;
-import org.apache.http.protocol.HttpRequestHandlerRegistry;
 import org.apache.http.protocol.HttpService;
 import org.apache.http.protocol.ImmutableHttpProcessor;
 import org.apache.http.protocol.RequestConnControl;
@@ -69,14 +63,10 @@ import org.apache.http.protocol.ResponseConnControl;
 import org.apache.http.protocol.ResponseContent;
 import org.apache.http.protocol.ResponseDate;
 import org.apache.http.protocol.ResponseServer;
+import org.apache.http.protocol.UriHttpRequestHandlerMapper;
 
 /**
- * Rudimentary HTTP/1.1 reverse proxy.
- * <p>
- * Please note the purpose of this application is demonstrate the usage of HttpCore APIs.
- * It is NOT intended to demonstrate the most efficient way of building an HTTP reverse proxy.
- *
- *
+ * Elemental HTTP/1.1 reverse proxy.
  */
 public class ElementalReverseProxy {
 
@@ -84,19 +74,19 @@ public class ElementalReverseProxy {
     private static final String HTTP_OUT_CONN = "http.proxy.out-conn";
     private static final String HTTP_CONN_KEEPALIVE = "http.proxy.conn-keepalive";
 
-    public static void main(String[] args) throws Exception {
+    public static void main(final String[] args) throws Exception {
         if (args.length < 1) {
             System.err.println("Please specified target hostname and port");
             System.exit(1);
         }
-        String hostname = args[0];
+        final String hostname = args[0];
         int port = 80;
         if (args.length > 1) {
             port = Integer.parseInt(args[1]);
         }
-        HttpHost target = new HttpHost(hostname, port);
+        final HttpHost target = new HttpHost(hostname, port);
 
-        Thread t = new RequestListenerThread(8888, target);
+        final Thread t = new RequestListenerThread(8888, target);
         t.setDaemon(false);
         t.start();
     }
@@ -116,7 +106,7 @@ public class ElementalReverseProxy {
             this.target = target;
             this.httpproc = httpproc;
             this.httpexecutor = httpexecutor;
-            this.connStrategy = new DefaultConnectionReuseStrategy();
+            this.connStrategy = DefaultConnectionReuseStrategy.INSTANCE;
         }
 
         public void handle(
@@ -124,11 +114,11 @@ public class ElementalReverseProxy {
                 final HttpResponse response,
                 final HttpContext context) throws HttpException, IOException {
 
-            HttpClientConnection conn = (HttpClientConnection) context.getAttribute(
+            final HttpClientConnection conn = (HttpClientConnection) context.getAttribute(
                     HTTP_OUT_CONN);
 
-            context.setAttribute(ExecutionContext.HTTP_CONNECTION, conn);
-            context.setAttribute(ExecutionContext.HTTP_TARGET_HOST, this.target);
+            context.setAttribute(HttpCoreContext.HTTP_CONNECTION, conn);
+            context.setAttribute(HttpCoreContext.HTTP_TARGET_HOST, this.target);
 
             System.out.println(">> Request URI: " + request.getRequestLine().getUri());
 
@@ -143,7 +133,7 @@ public class ElementalReverseProxy {
             request.removeHeaders("Upgrade");
 
             this.httpexecutor.preProcess(request, this.httpproc, context);
-            HttpResponse targetResponse = this.httpexecutor.execute(request, conn, context);
+            final HttpResponse targetResponse = this.httpexecutor.execute(request, conn, context);
             this.httpexecutor.postProcess(response, this.httpproc, context);
 
             // Remove hop-by-hop headers
@@ -161,7 +151,7 @@ public class ElementalReverseProxy {
 
             System.out.println("<< Response: " + response.getStatusLine());
 
-            boolean keepalive = this.connStrategy.keepAlive(response, context);
+            final boolean keepalive = this.connStrategy.keepAlive(response, context);
             context.setAttribute(HTTP_CONN_KEEPALIVE, new Boolean(keepalive));
         }
 
@@ -171,56 +161,43 @@ public class ElementalReverseProxy {
 
         private final HttpHost target;
         private final ServerSocket serversocket;
-        private final HttpParams params;
         private final HttpService httpService;
 
-        public RequestListenerThread(int port, final HttpHost target) throws IOException {
+        public RequestListenerThread(final int port, final HttpHost target) throws IOException {
             this.target = target;
             this.serversocket = new ServerSocket(port);
-            this.params = new SyncBasicHttpParams();
-            this.params
-                .setIntParameter(CoreConnectionPNames.SO_TIMEOUT, 5000)
-                .setIntParameter(CoreConnectionPNames.SOCKET_BUFFER_SIZE, 8 * 1024)
-                .setBooleanParameter(CoreConnectionPNames.STALE_CONNECTION_CHECK, false)
-                .setBooleanParameter(CoreConnectionPNames.TCP_NODELAY, true)
-                .setParameter(CoreProtocolPNames.ORIGIN_SERVER, "HttpComponents/1.1");
 
             // Set up HTTP protocol processor for incoming connections
-            HttpProcessor inhttpproc = new ImmutableHttpProcessor(
+            final HttpProcessor inhttpproc = new ImmutableHttpProcessor(
                     new HttpRequestInterceptor[] {
                             new RequestContent(),
                             new RequestTargetHost(),
                             new RequestConnControl(),
-                            new RequestUserAgent(),
-                            new RequestExpectContinue()
+                            new RequestUserAgent("Test/1.1"),
+                            new RequestExpectContinue(true)
              });
 
             // Set up HTTP protocol processor for outgoing connections
-            HttpProcessor outhttpproc = new ImmutableHttpProcessor(
+            final HttpProcessor outhttpproc = new ImmutableHttpProcessor(
                     new HttpResponseInterceptor[] {
                             new ResponseDate(),
-                            new ResponseServer(),
+                            new ResponseServer("Test/1.1"),
                             new ResponseContent(),
                             new ResponseConnControl()
             });
 
             // Set up outgoing request executor
-            HttpRequestExecutor httpexecutor = new HttpRequestExecutor();
+            final HttpRequestExecutor httpexecutor = new HttpRequestExecutor();
 
             // Set up incoming request handler
-            HttpRequestHandlerRegistry reqistry = new HttpRequestHandlerRegistry();
+            final UriHttpRequestHandlerMapper reqistry = new UriHttpRequestHandlerMapper();
             reqistry.register("*", new ProxyHandler(
                     this.target,
                     outhttpproc,
                     httpexecutor));
 
             // Set up the HTTP service
-            this.httpService = new HttpService(
-                    inhttpproc,
-                    new DefaultConnectionReuseStrategy(),
-                    new DefaultHttpResponseFactory(),
-                    reqistry,
-                    this.params);
+            this.httpService = new HttpService(inhttpproc, reqistry);
         }
 
         @Override
@@ -228,25 +205,26 @@ public class ElementalReverseProxy {
             System.out.println("Listening on port " + this.serversocket.getLocalPort());
             while (!Thread.interrupted()) {
                 try {
+                    final int bufsize = 8 * 1024;
                     // Set up incoming HTTP connection
-                    Socket insocket = this.serversocket.accept();
-                    DefaultHttpServerConnection inconn = new DefaultHttpServerConnection();
+                    final Socket insocket = this.serversocket.accept();
+                    final DefaultBHttpServerConnection inconn = new DefaultBHttpServerConnection(bufsize);
                     System.out.println("Incoming connection from " + insocket.getInetAddress());
-                    inconn.bind(insocket, this.params);
+                    inconn.bind(insocket);
 
                     // Set up outgoing HTTP connection
-                    Socket outsocket = new Socket(this.target.getHostName(), this.target.getPort());
-                    DefaultHttpClientConnection outconn = new DefaultHttpClientConnection();
-                    outconn.bind(outsocket, this.params);
+                    final Socket outsocket = new Socket(this.target.getHostName(), this.target.getPort());
+                    final DefaultBHttpClientConnection outconn = new DefaultBHttpClientConnection(bufsize);
+                    outconn.bind(outsocket);
                     System.out.println("Outgoing connection to " + outsocket.getInetAddress());
 
                     // Start worker thread
-                    Thread t = new ProxyThread(this.httpService, inconn, outconn);
+                    final Thread t = new ProxyThread(this.httpService, inconn, outconn);
                     t.setDaemon(true);
                     t.start();
-                } catch (InterruptedIOException ex) {
+                } catch (final InterruptedIOException ex) {
                     break;
-                } catch (IOException e) {
+                } catch (final IOException e) {
                     System.err.println("I/O error initialising connection thread: "
                             + e.getMessage());
                     break;
@@ -274,7 +252,7 @@ public class ElementalReverseProxy {
         @Override
         public void run() {
             System.out.println("New connection thread");
-            HttpContext context = new BasicHttpContext(null);
+            final HttpContext context = new BasicHttpContext(null);
 
             // Bind connection objects to the execution context
             context.setAttribute(HTTP_IN_CONN, this.inconn);
@@ -289,26 +267,26 @@ public class ElementalReverseProxy {
 
                     this.httpservice.handleRequest(this.inconn, context);
 
-                    Boolean keepalive = (Boolean) context.getAttribute(HTTP_CONN_KEEPALIVE);
+                    final Boolean keepalive = (Boolean) context.getAttribute(HTTP_CONN_KEEPALIVE);
                     if (!Boolean.TRUE.equals(keepalive)) {
                         this.outconn.close();
                         this.inconn.close();
                         break;
                     }
                 }
-            } catch (ConnectionClosedException ex) {
+            } catch (final ConnectionClosedException ex) {
                 System.err.println("Client closed connection");
-            } catch (IOException ex) {
+            } catch (final IOException ex) {
                 System.err.println("I/O error: " + ex.getMessage());
-            } catch (HttpException ex) {
+            } catch (final HttpException ex) {
                 System.err.println("Unrecoverable HTTP protocol violation: " + ex.getMessage());
             } finally {
                 try {
                     this.inconn.shutdown();
-                } catch (IOException ignore) {}
+                } catch (final IOException ignore) {}
                 try {
                     this.outconn.shutdown();
-                } catch (IOException ignore) {}
+                } catch (final IOException ignore) {}
             }
         }
 
diff --git a/LICENSE.txt b/httpcore/src/main/appended-resources/META-INF/LICENSE
similarity index 53%
copy from LICENSE.txt
copy to httpcore/src/main/appended-resources/META-INF/LICENSE
index 879d3fd..6285545 100644
--- a/LICENSE.txt
+++ b/httpcore/src/main/appended-resources/META-INF/LICENSE
@@ -1,186 +1,10 @@
-                                 Apache License
-                           Version 2.0, January 2004
-                        http://www.apache.org/licenses/
-
-   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-   1. Definitions.
-
-      "License" shall mean the terms and conditions for use, reproduction,
-      and distribution as defined by Sections 1 through 9 of this document.
-
-      "Licensor" shall mean the copyright owner or entity authorized by
-      the copyright owner that is granting the License.
-
-      "Legal Entity" shall mean the union of the acting entity and all
-      other entities that control, are controlled by, or are under common
-      control with that entity. For the purposes of this definition,
-      "control" means (i) the power, direct or indirect, to cause the
-      direction or management of such entity, whether by contract or
-      otherwise, or (ii) ownership of fifty percent (50%) or more of the
-      outstanding shares, or (iii) beneficial ownership of such entity.
-
-      "You" (or "Your") shall mean an individual or Legal Entity
-      exercising permissions granted by this License.
-
-      "Source" form shall mean the preferred form for making modifications,
-      including but not limited to software source code, documentation
-      source, and configuration files.
-
-      "Object" form shall mean any form resulting from mechanical
-      transformation or translation of a Source form, including but
-      not limited to compiled object code, generated documentation,
-      and conversions to other media types.
-
-      "Work" shall mean the work of authorship, whether in Source or
-      Object form, made available under the License, as indicated by a
-      copyright notice that is included in or attached to the work
-      (an example is provided in the Appendix below).
-
-      "Derivative Works" shall mean any work, whether in Source or Object
-      form, that is based on (or derived from) the Work and for which the
-      editorial revisions, annotations, elaborations, or other modifications
-      represent, as a whole, an original work of authorship. For the purposes
-      of this License, Derivative Works shall not include works that remain
-      separable from, or merely link (or bind by name) to the interfaces of,
-      the Work and Derivative Works thereof.
-
-      "Contribution" shall mean any work of authorship, including
-      the original version of the Work and any modifications or additions
-      to that Work or Derivative Works thereof, that is intentionally
-      submitted to Licensor for inclusion in the Work by the copyright owner
-      or by an individual or Legal Entity authorized to submit on behalf of
-      the copyright owner. For the purposes of this definition, "submitted"
-      means any form of electronic, verbal, or written communication sent
-      to the Licensor or its representatives, including but not limited to
-      communication on electronic mailing lists, source code control systems,
-      and issue tracking systems that are managed by, or on behalf of, the
-      Licensor for the purpose of discussing and improving the Work, but
-      excluding communication that is conspicuously marked or otherwise
-      designated in writing by the copyright owner as "Not a Contribution."
-
-      "Contributor" shall mean Licensor and any individual or Legal Entity
-      on behalf of whom a Contribution has been received by Licensor and
-      subsequently incorporated within the Work.
-
-   2. Grant of Copyright License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      copyright license to reproduce, prepare Derivative Works of,
-      publicly display, publicly perform, sublicense, and distribute the
-      Work and such Derivative Works in Source or Object form.
-
-   3. Grant of Patent License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      (except as stated in this section) patent license to make, have made,
-      use, offer to sell, sell, import, and otherwise transfer the Work,
-      where such license applies only to those patent claims licensable
-      by such Contributor that are necessarily infringed by their
-      Contribution(s) alone or by combination of their Contribution(s)
-      with the Work to which such Contribution(s) was submitted. If You
-      institute patent litigation against any entity (including a
-      cross-claim or counterclaim in a lawsuit) alleging that the Work
-      or a Contribution incorporated within the Work constitutes direct
-      or contributory patent infringement, then any patent licenses
-      granted to You under this License for that Work shall terminate
-      as of the date such litigation is filed.
-
-   4. Redistribution. You may reproduce and distribute copies of the
-      Work or Derivative Works thereof in any medium, with or without
-      modifications, and in Source or Object form, provided that You
-      meet the following conditions:
-
-      (a) You must give any other recipients of the Work or
-          Derivative Works a copy of this License; and
-
-      (b) You must cause any modified files to carry prominent notices
-          stating that You changed the files; and
-
-      (c) You must retain, in the Source form of any Derivative Works
-          that You distribute, all copyright, patent, trademark, and
-          attribution notices from the Source form of the Work,
-          excluding those notices that do not pertain to any part of
-          the Derivative Works; and
-
-      (d) If the Work includes a "NOTICE" text file as part of its
-          distribution, then any Derivative Works that You distribute must
-          include a readable copy of the attribution notices contained
-          within such NOTICE file, excluding those notices that do not
-          pertain to any part of the Derivative Works, in at least one
-          of the following places: within a NOTICE text file distributed
-          as part of the Derivative Works; within the Source form or
-          documentation, if provided along with the Derivative Works; or,
-          within a display generated by the Derivative Works, if and
-          wherever such third-party notices normally appear. The contents
-          of the NOTICE file are for informational purposes only and
-          do not modify the License. You may add Your own attribution
-          notices within Derivative Works that You distribute, alongside
-          or as an addendum to the NOTICE text from the Work, provided
-          that such additional attribution notices cannot be construed
-          as modifying the License.
-
-      You may add Your own copyright statement to Your modifications and
-      may provide additional or different license terms and conditions
-      for use, reproduction, or distribution of Your modifications, or
-      for any such Derivative Works as a whole, provided Your use,
-      reproduction, and distribution of the Work otherwise complies with
-      the conditions stated in this License.
-
-   5. Submission of Contributions. Unless You explicitly state otherwise,
-      any Contribution intentionally submitted for inclusion in the Work
-      by You to the Licensor shall be under the terms and conditions of
-      this License, without any additional terms or conditions.
-      Notwithstanding the above, nothing herein shall supersede or modify
-      the terms of any separate license agreement you may have executed
-      with Licensor regarding such Contributions.
-
-   6. Trademarks. This License does not grant permission to use the trade
-      names, trademarks, service marks, or product names of the Licensor,
-      except as required for reasonable and customary use in describing the
-      origin of the Work and reproducing the content of the NOTICE file.
-
-   7. Disclaimer of Warranty. Unless required by applicable law or
-      agreed to in writing, Licensor provides the Work (and each
-      Contributor provides its Contributions) on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-      implied, including, without limitation, any warranties or conditions
-      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-      PARTICULAR PURPOSE. You are solely responsible for determining the
-      appropriateness of using or redistributing the Work and assume any
-      risks associated with Your exercise of permissions under this License.
-
-   8. Limitation of Liability. In no event and under no legal theory,
-      whether in tort (including negligence), contract, or otherwise,
-      unless required by applicable law (such as deliberate and grossly
-      negligent acts) or agreed to in writing, shall any Contributor be
-      liable to You for damages, including any direct, indirect, special,
-      incidental, or consequential damages of any character arising as a
-      result of this License or out of the use or inability to use the
-      Work (including but not limited to damages for loss of goodwill,
-      work stoppage, computer failure or malfunction, or any and all
-      other commercial damages or losses), even if such Contributor
-      has been advised of the possibility of such damages.
-
-   9. Accepting Warranty or Additional Liability. While redistributing
-      the Work or Derivative Works thereof, You may choose to offer,
-      and charge a fee for, acceptance of support, warranty, indemnity,
-      or other liability obligations and/or rights consistent with this
-      License. However, in accepting such obligations, You may act only
-      on Your own behalf and on Your sole responsibility, not on behalf
-      of any other Contributor, and only if You agree to indemnify,
-      defend, and hold each Contributor harmless for any liability
-      incurred by, or claims asserted against, such Contributor by reason
-      of your accepting any such warranty or additional liability.
-
-   END OF TERMS AND CONDITIONS
 
 =========================================================================
 
 This project contains annotations in the package org.apache.http.annotation
-which are derived from JCIP-ANNOTATIONS 
+which are derived from JCIP-ANNOTATIONS
 Copyright (c) 2005 Brian Goetz and Tim Peierls.
-See http://www.jcip.net and the Creative Commons Attribution License 
+See http://www.jcip.net and the Creative Commons Attribution License
 (http://creativecommons.org/licenses/by/2.5)
 Full text: http://creativecommons.org/licenses/by/2.5/legalcode
 
diff --git a/httpcore/src/main/appended-resources/META-INF/NOTICE b/httpcore/src/main/appended-resources/META-INF/NOTICE
new file mode 100644
index 0000000..b2660ff
--- /dev/null
+++ b/httpcore/src/main/appended-resources/META-INF/NOTICE
@@ -0,0 +1,2 @@
+This project contains annotations derived from JCIP-ANNOTATIONS
+Copyright (c) 2005 Brian Goetz and Tim Peierls. See http://www.jcip.net
diff --git a/httpcore/src/main/java/org/apache/http/impl/AbstractHttpClientConnection.java b/httpcore/src/main/java-deprecated/org/apache/http/impl/AbstractHttpClientConnection.java
similarity index 86%
rename from httpcore/src/main/java/org/apache/http/impl/AbstractHttpClientConnection.java
rename to httpcore/src/main/java-deprecated/org/apache/http/impl/AbstractHttpClientConnection.java
index 9d7f208..0616042 100644
--- a/httpcore/src/main/java/org/apache/http/impl/AbstractHttpClientConnection.java
+++ b/httpcore/src/main/java-deprecated/org/apache/http/impl/AbstractHttpClientConnection.java
@@ -38,8 +38,8 @@ import org.apache.http.HttpException;
 import org.apache.http.HttpRequest;
 import org.apache.http.HttpResponse;
 import org.apache.http.HttpResponseFactory;
+import org.apache.http.HttpStatus;
 import org.apache.http.annotation.NotThreadSafe;
-import org.apache.http.entity.ContentLengthStrategy;
 import org.apache.http.impl.entity.EntityDeserializer;
 import org.apache.http.impl.entity.EntitySerializer;
 import org.apache.http.impl.entity.LaxContentLengthStrategy;
@@ -52,9 +52,8 @@ import org.apache.http.io.HttpMessageWriter;
 import org.apache.http.io.HttpTransportMetrics;
 import org.apache.http.io.SessionInputBuffer;
 import org.apache.http.io.SessionOutputBuffer;
-import org.apache.http.message.LineFormatter;
-import org.apache.http.message.LineParser;
 import org.apache.http.params.HttpParams;
+import org.apache.http.util.Args;
 
 /**
  * Abstract client-side HTTP connection capable of transmitting and receiving
@@ -70,8 +69,11 @@ import org.apache.http.params.HttpParams;
  * </ul>
  *
  * @since 4.0
+ *
+ * @deprecated (4.3) use {@link DefaultBHttpClientConnection}
  */
 @NotThreadSafe
+ at Deprecated
 public abstract class AbstractHttpClientConnection implements HttpClientConnection {
 
     private final EntitySerializer entityserializer;
@@ -112,7 +114,7 @@ public abstract class AbstractHttpClientConnection implements HttpClientConnecti
      * <p>
      * This method can be overridden in a super class in order to create
      * instances of {@link EntityDeserializer} using a custom
-     * {@link ContentLengthStrategy}.
+     * {@link org.apache.http.entity.ContentLengthStrategy}.
      *
      * @return HTTP entity deserializer
      */
@@ -127,7 +129,7 @@ public abstract class AbstractHttpClientConnection implements HttpClientConnecti
      * <p>
      * This method can be overridden in a super class in order to create
      * instances of {@link EntitySerializer} using a custom
-     * {@link ContentLengthStrategy}.
+     * {@link org.apache.http.entity.ContentLengthStrategy}.
      *
      * @return HTTP entity serialzier.
      */
@@ -146,7 +148,7 @@ public abstract class AbstractHttpClientConnection implements HttpClientConnecti
      * @return HTTP response factory.
      */
     protected HttpResponseFactory createHttpResponseFactory() {
-        return new DefaultHttpResponseFactory();
+        return DefaultHttpResponseFactory.INSTANCE;
     }
 
     /**
@@ -155,8 +157,9 @@ public abstract class AbstractHttpClientConnection implements HttpClientConnecti
      * <p>
      * This method can be overridden in a super class in order to provide
      * a different implementation of the {@link HttpMessageParser} interface or
-     * to pass a different implementation of the {@link LineParser} to the
-     * the {@link DefaultHttpResponseParser} constructor.
+     * to pass a different implementation of the
+     * {@link org.apache.http.message.LineParser} to the the
+     * {@link DefaultHttpResponseParser} constructor.
      *
      * @param buffer the session input buffer.
      * @param responseFactory the HTTP response factory.
@@ -176,8 +179,9 @@ public abstract class AbstractHttpClientConnection implements HttpClientConnecti
      * <p>
      * This method can be overridden in a super class in order to provide
      * a different implementation of the {@link HttpMessageWriter} interface or
-     * to pass a different implementation of {@link LineFormatter} to the
-     * the default implementation {@link HttpRequestWriter}.
+     * to pass a different implementation of
+     * {@link org.apache.http.message.LineFormatter} to the the default implementation
+     * {@link HttpRequestWriter}.
      *
      * @param buffer the session output buffer
      * @param params HTTP parameters
@@ -218,14 +222,8 @@ public abstract class AbstractHttpClientConnection implements HttpClientConnecti
             final SessionInputBuffer inbuffer,
             final SessionOutputBuffer outbuffer,
             final HttpParams params) {
-        if (inbuffer == null) {
-            throw new IllegalArgumentException("Input session buffer may not be null");
-        }
-        if (outbuffer == null) {
-            throw new IllegalArgumentException("Output session buffer may not be null");
-        }
-        this.inbuffer = inbuffer;
-        this.outbuffer = outbuffer;
+        this.inbuffer = Args.notNull(inbuffer, "Input session buffer");
+        this.outbuffer = Args.notNull(outbuffer, "Output session buffer");
         if (inbuffer instanceof EofSensor) {
             this.eofSensor = (EofSensor) inbuffer;
         }
@@ -240,20 +238,18 @@ public abstract class AbstractHttpClientConnection implements HttpClientConnecti
                 outbuffer.getMetrics());
     }
 
-    public boolean isResponseAvailable(int timeout) throws IOException {
+    public boolean isResponseAvailable(final int timeout) throws IOException {
         assertOpen();
         try {
             return this.inbuffer.isDataAvailable(timeout);
-        } catch (SocketTimeoutException ex) {
+        } catch (final SocketTimeoutException ex) {
             return false;
         }
     }
 
     public void sendRequestHeader(final HttpRequest request)
             throws HttpException, IOException {
-        if (request == null) {
-            throw new IllegalArgumentException("HTTP request may not be null");
-        }
+        Args.notNull(request, "HTTP request");
         assertOpen();
         this.requestWriter.write(request);
         this.metrics.incrementRequestCount();
@@ -261,9 +257,7 @@ public abstract class AbstractHttpClientConnection implements HttpClientConnecti
 
     public void sendRequestEntity(final HttpEntityEnclosingRequest request)
             throws HttpException, IOException {
-        if (request == null) {
-            throw new IllegalArgumentException("HTTP request may not be null");
-        }
+        Args.notNull(request, "HTTP request");
         assertOpen();
         if (request.getEntity() == null) {
             return;
@@ -286,8 +280,8 @@ public abstract class AbstractHttpClientConnection implements HttpClientConnecti
     public HttpResponse receiveResponseHeader()
             throws HttpException, IOException {
         assertOpen();
-        HttpResponse response = this.responseParser.parse();
-        if (response.getStatusLine().getStatusCode() >= 200) {
+        final HttpResponse response = this.responseParser.parse();
+        if (response.getStatusLine().getStatusCode() >= HttpStatus.SC_OK) {
             this.metrics.incrementResponseCount();
         }
         return response;
@@ -295,11 +289,9 @@ public abstract class AbstractHttpClientConnection implements HttpClientConnecti
 
     public void receiveResponseEntity(final HttpResponse response)
             throws HttpException, IOException {
-        if (response == null) {
-            throw new IllegalArgumentException("HTTP response may not be null");
-        }
+        Args.notNull(response, "HTTP response");
         assertOpen();
-        HttpEntity entity = this.entitydeserializer.deserialize(this.inbuffer, response);
+        final HttpEntity entity = this.entitydeserializer.deserialize(this.inbuffer, response);
         response.setEntity(entity);
     }
 
@@ -317,9 +309,9 @@ public abstract class AbstractHttpClientConnection implements HttpClientConnecti
         try {
             this.inbuffer.isDataAvailable(1);
             return isEof();
-        } catch (SocketTimeoutException ex) {
+        } catch (final SocketTimeoutException ex) {
             return false;
-        } catch (IOException ex) {
+        } catch (final IOException ex) {
             return true;
         }
     }
diff --git a/httpcore/src/main/java/org/apache/http/impl/AbstractHttpServerConnection.java b/httpcore/src/main/java-deprecated/org/apache/http/impl/AbstractHttpServerConnection.java
similarity index 89%
rename from httpcore/src/main/java/org/apache/http/impl/AbstractHttpServerConnection.java
rename to httpcore/src/main/java-deprecated/org/apache/http/impl/AbstractHttpServerConnection.java
index 4cb5ac6..0bcecfd 100644
--- a/httpcore/src/main/java/org/apache/http/impl/AbstractHttpServerConnection.java
+++ b/httpcore/src/main/java-deprecated/org/apache/http/impl/AbstractHttpServerConnection.java
@@ -38,7 +38,6 @@ import org.apache.http.HttpRequestFactory;
 import org.apache.http.HttpResponse;
 import org.apache.http.HttpServerConnection;
 import org.apache.http.annotation.NotThreadSafe;
-import org.apache.http.entity.ContentLengthStrategy;
 import org.apache.http.impl.entity.DisallowIdentityContentLengthStrategy;
 import org.apache.http.impl.entity.EntityDeserializer;
 import org.apache.http.impl.entity.EntitySerializer;
@@ -52,9 +51,8 @@ import org.apache.http.io.HttpMessageWriter;
 import org.apache.http.io.HttpTransportMetrics;
 import org.apache.http.io.SessionInputBuffer;
 import org.apache.http.io.SessionOutputBuffer;
-import org.apache.http.message.LineFormatter;
-import org.apache.http.message.LineParser;
 import org.apache.http.params.HttpParams;
+import org.apache.http.util.Args;
 
 /**
  * Abstract server-side HTTP connection capable of transmitting and receiving
@@ -70,8 +68,11 @@ import org.apache.http.params.HttpParams;
  * </ul>
  *
  * @since 4.0
+ *
+ * @deprecated (4.3) use {@link DefaultBHttpServerConnection}
  */
 @NotThreadSafe
+ at Deprecated
 public abstract class AbstractHttpServerConnection implements HttpServerConnection {
 
     private final EntitySerializer entityserializer;
@@ -112,7 +113,7 @@ public abstract class AbstractHttpServerConnection implements HttpServerConnecti
      * <p>
      * This method can be overridden in a super class in order to create
      * instances of {@link EntityDeserializer} using a custom
-     * {@link ContentLengthStrategy}.
+     * {@link org.apache.http.entity.ContentLengthStrategy}.
      *
      * @return HTTP entity deserializer
      */
@@ -128,7 +129,7 @@ public abstract class AbstractHttpServerConnection implements HttpServerConnecti
      * <p>
      * This method can be overridden in a super class in order to create
      * instances of {@link EntitySerializer} using a custom
-     * {@link ContentLengthStrategy}.
+     * {@link org.apache.http.entity.ContentLengthStrategy}.
      *
      * @return HTTP entity serialzier.
      */
@@ -147,7 +148,7 @@ public abstract class AbstractHttpServerConnection implements HttpServerConnecti
      * @return HTTP request factory.
      */
     protected HttpRequestFactory createHttpRequestFactory() {
-        return new DefaultHttpRequestFactory();
+        return DefaultHttpRequestFactory.INSTANCE;
     }
 
     /**
@@ -156,8 +157,9 @@ public abstract class AbstractHttpServerConnection implements HttpServerConnecti
      * <p>
      * This method can be overridden in a super class in order to provide
      * a different implementation of the {@link HttpMessageParser} interface or
-     * to pass a different implementation of the {@link LineParser} to the
-     * the {@link DefaultHttpRequestParser} constructor.
+     * to pass a different implementation of the
+     * {@link org.apache.http.message.LineParser} to the
+     * {@link DefaultHttpRequestParser} constructor.
      *
      * @param buffer the session input buffer.
      * @param requestFactory the HTTP request factory.
@@ -177,8 +179,9 @@ public abstract class AbstractHttpServerConnection implements HttpServerConnecti
      * <p>
      * This method can be overridden in a super class in order to provide
      * a different implementation of the {@link HttpMessageWriter} interface or
-     * to pass a different implementation of {@link LineFormatter} to the
-     * the default implementation {@link HttpResponseWriter}.
+     * to pass a different implementation of
+     * {@link org.apache.http.message.LineFormatter} to the the default
+     * implementation {@link HttpResponseWriter}.
      *
      * @param buffer the session output buffer
      * @param params HTTP parameters
@@ -219,14 +222,8 @@ public abstract class AbstractHttpServerConnection implements HttpServerConnecti
             final SessionInputBuffer inbuffer,
             final SessionOutputBuffer outbuffer,
             final HttpParams params) {
-        if (inbuffer == null) {
-            throw new IllegalArgumentException("Input session buffer may not be null");
-        }
-        if (outbuffer == null) {
-            throw new IllegalArgumentException("Output session buffer may not be null");
-        }
-        this.inbuffer = inbuffer;
-        this.outbuffer = outbuffer;
+        this.inbuffer = Args.notNull(inbuffer, "Input session buffer");
+        this.outbuffer = Args.notNull(outbuffer, "Output session buffer");
         if (inbuffer instanceof EofSensor) {
             this.eofSensor = (EofSensor) inbuffer;
         }
@@ -244,18 +241,16 @@ public abstract class AbstractHttpServerConnection implements HttpServerConnecti
     public HttpRequest receiveRequestHeader()
             throws HttpException, IOException {
         assertOpen();
-        HttpRequest request = this.requestParser.parse();
+        final HttpRequest request = this.requestParser.parse();
         this.metrics.incrementRequestCount();
         return request;
     }
 
     public void receiveRequestEntity(final HttpEntityEnclosingRequest request)
             throws HttpException, IOException {
-        if (request == null) {
-            throw new IllegalArgumentException("HTTP request may not be null");
-        }
+        Args.notNull(request, "HTTP request");
         assertOpen();
-        HttpEntity entity = this.entitydeserializer.deserialize(this.inbuffer, request);
+        final HttpEntity entity = this.entitydeserializer.deserialize(this.inbuffer, request);
         request.setEntity(entity);
     }
 
@@ -270,9 +265,7 @@ public abstract class AbstractHttpServerConnection implements HttpServerConnecti
 
     public void sendResponseHeader(final HttpResponse response)
             throws HttpException, IOException {
-        if (response == null) {
-            throw new IllegalArgumentException("HTTP response may not be null");
-        }
+        Args.notNull(response, "HTTP response");
         assertOpen();
         this.responseWriter.write(response);
         if (response.getStatusLine().getStatusCode() >= 200) {
@@ -305,7 +298,7 @@ public abstract class AbstractHttpServerConnection implements HttpServerConnecti
         try {
             this.inbuffer.isDataAvailable(1);
             return isEof();
-        } catch (IOException ex) {
+        } catch (final IOException ex) {
             return true;
         }
     }
diff --git a/httpcore/src/main/java/org/apache/http/impl/DefaultHttpClientConnection.java b/httpcore/src/main/java-deprecated/org/apache/http/impl/DefaultHttpClientConnection.java
similarity index 57%
rename from httpcore/src/main/java/org/apache/http/impl/DefaultHttpClientConnection.java
rename to httpcore/src/main/java-deprecated/org/apache/http/impl/DefaultHttpClientConnection.java
index 680c8bb..1dfbd8f 100644
--- a/httpcore/src/main/java/org/apache/http/impl/DefaultHttpClientConnection.java
+++ b/httpcore/src/main/java-deprecated/org/apache/http/impl/DefaultHttpClientConnection.java
@@ -31,29 +31,19 @@ import java.io.IOException;
 import java.net.Socket;
 
 import org.apache.http.annotation.NotThreadSafe;
-import org.apache.http.params.HttpConnectionParams;
+import org.apache.http.params.CoreConnectionPNames;
 import org.apache.http.params.HttpParams;
+import org.apache.http.util.Args;
 
 /**
  * Default implementation of a client-side HTTP connection.
- * <p>
- * The following parameters can be used to customize the behavior of this
- * class:
- * <ul>
- *  <li>{@link org.apache.http.params.CoreProtocolPNames#HTTP_ELEMENT_CHARSET}</li>
- *  <li>{@link org.apache.http.params.CoreConnectionPNames#TCP_NODELAY}</li>
- *  <li>{@link org.apache.http.params.CoreConnectionPNames#SO_TIMEOUT}</li>
- *  <li>{@link org.apache.http.params.CoreConnectionPNames#SO_LINGER}</li>
- *  <li>{@link org.apache.http.params.CoreConnectionPNames#SO_KEEPALIVE}</li>
- *  <li>{@link org.apache.http.params.CoreConnectionPNames#SOCKET_BUFFER_SIZE}</li>
- *  <li>{@link org.apache.http.params.CoreConnectionPNames#MAX_LINE_LENGTH}</li>
- *  <li>{@link org.apache.http.params.CoreConnectionPNames#MAX_HEADER_COUNT}</li>
- *  <li>{@link org.apache.http.params.CoreConnectionPNames#MIN_CHUNK_LIMIT}</li>
- * </ul>
  *
  * @since 4.0
+ *
+ * @deprecated (4.3) use {@link DefaultBHttpClientConnection}
  */
 @NotThreadSafe
+ at Deprecated
 public class DefaultHttpClientConnection extends SocketHttpClientConnection {
 
     public DefaultHttpClientConnection() {
@@ -64,18 +54,13 @@ public class DefaultHttpClientConnection extends SocketHttpClientConnection {
     public void bind(
             final Socket socket,
             final HttpParams params) throws IOException {
-        if (socket == null) {
-            throw new IllegalArgumentException("Socket may not be null");
-        }
-        if (params == null) {
-            throw new IllegalArgumentException("HTTP parameters may not be null");
-        }
+        Args.notNull(socket, "Socket");
+        Args.notNull(params, "HTTP parameters");
         assertNotOpen();
-        socket.setTcpNoDelay(HttpConnectionParams.getTcpNoDelay(params));
-        socket.setSoTimeout(HttpConnectionParams.getSoTimeout(params));
-        socket.setKeepAlive(HttpConnectionParams.getSoKeepalive(params));
-
-        int linger = HttpConnectionParams.getLinger(params);
+        socket.setTcpNoDelay(params.getBooleanParameter(CoreConnectionPNames.TCP_NODELAY, true));
+        socket.setSoTimeout(params.getIntParameter(CoreConnectionPNames.SO_TIMEOUT, 0));
+        socket.setKeepAlive(params.getBooleanParameter(CoreConnectionPNames.SO_KEEPALIVE, false));
+        final int linger = params.getIntParameter(CoreConnectionPNames.SO_LINGER, -1);
         if (linger >= 0) {
             socket.setSoLinger(linger > 0, linger);
         }
diff --git a/httpcore/src/main/java/org/apache/http/impl/DefaultHttpServerConnection.java b/httpcore/src/main/java-deprecated/org/apache/http/impl/DefaultHttpServerConnection.java
similarity index 57%
rename from httpcore/src/main/java/org/apache/http/impl/DefaultHttpServerConnection.java
rename to httpcore/src/main/java-deprecated/org/apache/http/impl/DefaultHttpServerConnection.java
index be0861a..9df1039 100644
--- a/httpcore/src/main/java/org/apache/http/impl/DefaultHttpServerConnection.java
+++ b/httpcore/src/main/java-deprecated/org/apache/http/impl/DefaultHttpServerConnection.java
@@ -31,29 +31,19 @@ import java.io.IOException;
 import java.net.Socket;
 
 import org.apache.http.annotation.NotThreadSafe;
-import org.apache.http.params.HttpConnectionParams;
+import org.apache.http.params.CoreConnectionPNames;
 import org.apache.http.params.HttpParams;
+import org.apache.http.util.Args;
 
 /**
  * Default implementation of a server-side HTTP connection.
- * <p>
- * The following parameters can be used to customize the behavior of this
- * class:
- * <ul>
- *  <li>{@link org.apache.http.params.CoreProtocolPNames#HTTP_ELEMENT_CHARSET}</li>
- *  <li>{@link org.apache.http.params.CoreConnectionPNames#TCP_NODELAY}</li>
- *  <li>{@link org.apache.http.params.CoreConnectionPNames#SO_TIMEOUT}</li>
- *  <li>{@link org.apache.http.params.CoreConnectionPNames#SO_LINGER}</li>
- *  <li>{@link org.apache.http.params.CoreConnectionPNames#SO_KEEPALIVE}</li>
- *  <li>{@link org.apache.http.params.CoreConnectionPNames#SOCKET_BUFFER_SIZE}</li>
- *  <li>{@link org.apache.http.params.CoreConnectionPNames#MAX_LINE_LENGTH}</li>
- *  <li>{@link org.apache.http.params.CoreConnectionPNames#MAX_HEADER_COUNT}</li>
- *  <li>{@link org.apache.http.params.CoreConnectionPNames#MIN_CHUNK_LIMIT}</li>
- * </ul>
  *
  * @since 4.0
+ *
+ * @deprecated (4.3) use {@link DefaultBHttpServerConnection}
  */
 @NotThreadSafe
+ at Deprecated
 public class DefaultHttpServerConnection extends SocketHttpServerConnection {
 
     public DefaultHttpServerConnection() {
@@ -62,18 +52,16 @@ public class DefaultHttpServerConnection extends SocketHttpServerConnection {
 
     @Override
     public void bind(final Socket socket, final HttpParams params) throws IOException {
-        if (socket == null) {
-            throw new IllegalArgumentException("Socket may not be null");
-        }
-        if (params == null) {
-            throw new IllegalArgumentException("HTTP parameters may not be null");
-        }
+        Args.notNull(socket, "Socket");
+        Args.notNull(params, "HTTP parameters");
         assertNotOpen();
-        socket.setTcpNoDelay(HttpConnectionParams.getTcpNoDelay(params));
-        socket.setSoTimeout(HttpConnectionParams.getSoTimeout(params));
-        socket.setKeepAlive(HttpConnectionParams.getSoKeepalive(params));
-
-        int linger = HttpConnectionParams.getLinger(params);
+        socket.setTcpNoDelay(params.getBooleanParameter(CoreConnectionPNames.TCP_NODELAY, true));
+        socket.setSoTimeout(params.getIntParameter(CoreConnectionPNames.SO_TIMEOUT, 0));
+        socket.setKeepAlive(params.getBooleanParameter(CoreConnectionPNames.SO_KEEPALIVE, false));
+        final int linger = params.getIntParameter(CoreConnectionPNames.SO_LINGER, -1);
+        if (linger >= 0) {
+            socket.setSoLinger(linger > 0, linger);
+        }
         if (linger >= 0) {
             socket.setSoLinger(linger > 0, linger);
         }
diff --git a/httpcore/src/main/java/org/apache/http/impl/SocketHttpClientConnection.java b/httpcore/src/main/java-deprecated/org/apache/http/impl/SocketHttpClientConnection.java
similarity index 81%
rename from httpcore/src/main/java/org/apache/http/impl/SocketHttpClientConnection.java
rename to httpcore/src/main/java-deprecated/org/apache/http/impl/SocketHttpClientConnection.java
index 73d54a9..f042ae2 100644
--- a/httpcore/src/main/java/org/apache/http/impl/SocketHttpClientConnection.java
+++ b/httpcore/src/main/java-deprecated/org/apache/http/impl/SocketHttpClientConnection.java
@@ -40,28 +40,22 @@ import org.apache.http.impl.io.SocketInputBuffer;
 import org.apache.http.impl.io.SocketOutputBuffer;
 import org.apache.http.io.SessionInputBuffer;
 import org.apache.http.io.SessionOutputBuffer;
-import org.apache.http.params.HttpConnectionParams;
+import org.apache.http.params.CoreConnectionPNames;
 import org.apache.http.params.HttpParams;
+import org.apache.http.util.Args;
+import org.apache.http.util.Asserts;
 
 /**
  * Implementation of a client-side HTTP connection that can be bound to an
  * arbitrary {@link Socket} for receiving data from and transmitting data to
  * a remote server.
- * <p>
- * The following parameters can be used to customize the behavior of this
- * class:
- * <ul>
- *  <li>{@link org.apache.http.params.CoreProtocolPNames#STRICT_TRANSFER_ENCODING}</li>
- *  <li>{@link org.apache.http.params.CoreProtocolPNames#HTTP_ELEMENT_CHARSET}</li>
- *  <li>{@link org.apache.http.params.CoreConnectionPNames#SOCKET_BUFFER_SIZE}</li>
- *  <li>{@link org.apache.http.params.CoreConnectionPNames#MAX_LINE_LENGTH}</li>
- *  <li>{@link org.apache.http.params.CoreConnectionPNames#MAX_HEADER_COUNT}</li>
- *  <li>{@link org.apache.http.params.CoreConnectionPNames#MIN_CHUNK_LIMIT}</li>
- * </ul>
  *
  * @since 4.0
+ *
+ * @deprecated (4.3) use {@link DefaultBHttpClientConnection}
  */
 @NotThreadSafe
+ at Deprecated
 public class SocketHttpClientConnection
         extends AbstractHttpClientConnection implements HttpInetConnection {
 
@@ -73,16 +67,12 @@ public class SocketHttpClientConnection
     }
 
     protected void assertNotOpen() {
-        if (this.open) {
-            throw new IllegalStateException("Connection is already open");
-        }
+        Asserts.check(!this.open, "Connection is already open");
     }
 
     @Override
     protected void assertOpen() {
-        if (!this.open) {
-            throw new IllegalStateException("Connection is not open");
-        }
+        Asserts.check(this.open, "Connection is not open");
     }
 
     /**
@@ -102,7 +92,7 @@ public class SocketHttpClientConnection
      */
     protected SessionInputBuffer createSessionInputBuffer(
             final Socket socket,
-            int buffersize,
+            final int buffersize,
             final HttpParams params) throws IOException {
         return new SocketInputBuffer(socket, buffersize, params);
     }
@@ -124,7 +114,7 @@ public class SocketHttpClientConnection
      */
     protected SessionOutputBuffer createSessionOutputBuffer(
             final Socket socket,
-            int buffersize,
+            final int buffersize,
             final HttpParams params) throws IOException {
         return new SocketOutputBuffer(socket, buffersize, params);
     }
@@ -150,16 +140,11 @@ public class SocketHttpClientConnection
     protected void bind(
             final Socket socket,
             final HttpParams params) throws IOException {
-        if (socket == null) {
-            throw new IllegalArgumentException("Socket may not be null");
-        }
-        if (params == null) {
-            throw new IllegalArgumentException("HTTP parameters may not be null");
-        }
+        Args.notNull(socket, "Socket");
+        Args.notNull(params, "HTTP parameters");
         this.socket = socket;
 
-        int buffersize = HttpConnectionParams.getSocketBufferSize(params);
-
+        final int buffersize = params.getIntParameter(CoreConnectionPNames.SOCKET_BUFFER_SIZE, -1);
         init(
                 createSessionInputBuffer(socket, buffersize, params),
                 createSessionOutputBuffer(socket, buffersize, params),
@@ -208,12 +193,12 @@ public class SocketHttpClientConnection
         }
     }
 
-    public void setSocketTimeout(int timeout) {
+    public void setSocketTimeout(final int timeout) {
         assertOpen();
         if (this.socket != null) {
             try {
                 this.socket.setSoTimeout(timeout);
-            } catch (SocketException ignore) {
+            } catch (final SocketException ignore) {
                 // It is not quite clear from the Sun's documentation if there are any
                 // other legitimate cases for a socket exception to be thrown when setting
                 // SO_TIMEOUT besides the socket being already closed
@@ -225,7 +210,7 @@ public class SocketHttpClientConnection
         if (this.socket != null) {
             try {
                 return this.socket.getSoTimeout();
-            } catch (SocketException ignore) {
+            } catch (final SocketException ignore) {
                 return -1;
             }
         } else {
@@ -235,7 +220,7 @@ public class SocketHttpClientConnection
 
     public void shutdown() throws IOException {
         this.open = false;
-        Socket tmpsocket = this.socket;
+        final Socket tmpsocket = this.socket;
         if (tmpsocket != null) {
             tmpsocket.close();
         }
@@ -246,19 +231,19 @@ public class SocketHttpClientConnection
             return;
         }
         this.open = false;
-        Socket sock = this.socket;
+        final Socket sock = this.socket;
         try {
             doFlush();
             try {
                 try {
                     sock.shutdownOutput();
-                } catch (IOException ignore) {
+                } catch (final IOException ignore) {
                 }
                 try {
                     sock.shutdownInput();
-                } catch (IOException ignore) {
+                } catch (final IOException ignore) {
                 }
-            } catch (UnsupportedOperationException ignore) {
+            } catch (final UnsupportedOperationException ignore) {
                 // if one isn't supported, the other one isn't either
             }
         } finally {
@@ -268,7 +253,7 @@ public class SocketHttpClientConnection
 
     private static void formatAddress(final StringBuilder buffer, final SocketAddress socketAddress) {
         if (socketAddress instanceof InetSocketAddress) {
-            InetSocketAddress addr = ((InetSocketAddress) socketAddress);
+            final InetSocketAddress addr = ((InetSocketAddress) socketAddress);
             buffer.append(addr.getAddress() != null ? addr.getAddress().getHostAddress() :
                 addr.getAddress())
             .append(':')
@@ -281,9 +266,9 @@ public class SocketHttpClientConnection
     @Override
     public String toString() {
         if (this.socket != null) {
-            StringBuilder buffer = new StringBuilder();
-            SocketAddress remoteAddress = this.socket.getRemoteSocketAddress();
-            SocketAddress localAddress = this.socket.getLocalSocketAddress();
+            final StringBuilder buffer = new StringBuilder();
+            final SocketAddress remoteAddress = this.socket.getRemoteSocketAddress();
+            final SocketAddress localAddress = this.socket.getLocalSocketAddress();
             if (remoteAddress != null && localAddress != null) {
                 formatAddress(buffer, localAddress);
                 buffer.append("<->");
diff --git a/httpcore/src/main/java/org/apache/http/impl/SocketHttpServerConnection.java b/httpcore/src/main/java-deprecated/org/apache/http/impl/SocketHttpServerConnection.java
similarity index 78%
rename from httpcore/src/main/java/org/apache/http/impl/SocketHttpServerConnection.java
rename to httpcore/src/main/java-deprecated/org/apache/http/impl/SocketHttpServerConnection.java
index 263ac9d..e17115c 100644
--- a/httpcore/src/main/java/org/apache/http/impl/SocketHttpServerConnection.java
+++ b/httpcore/src/main/java-deprecated/org/apache/http/impl/SocketHttpServerConnection.java
@@ -35,32 +35,16 @@ import java.net.SocketAddress;
 import java.net.SocketException;
 
 import org.apache.http.HttpInetConnection;
-import org.apache.http.annotation.NotThreadSafe;
 import org.apache.http.impl.io.SocketInputBuffer;
 import org.apache.http.impl.io.SocketOutputBuffer;
 import org.apache.http.io.SessionInputBuffer;
 import org.apache.http.io.SessionOutputBuffer;
-import org.apache.http.params.HttpConnectionParams;
+import org.apache.http.params.CoreConnectionPNames;
 import org.apache.http.params.HttpParams;
+import org.apache.http.util.Args;
+import org.apache.http.util.Asserts;
 
-/**
- * Implementation of a server-side HTTP connection that can be bound to a
- * network Socket in order to receive and transmit data.
- * <p>
- * The following parameters can be used to customize the behavior of this
- * class:
- * <ul>
- *  <li>{@link org.apache.http.params.CoreProtocolPNames#STRICT_TRANSFER_ENCODING}</li>
- *  <li>{@link org.apache.http.params.CoreProtocolPNames#HTTP_ELEMENT_CHARSET}</li>
- *  <li>{@link org.apache.http.params.CoreConnectionPNames#SOCKET_BUFFER_SIZE}</li>
- *  <li>{@link org.apache.http.params.CoreConnectionPNames#MAX_LINE_LENGTH}</li>
- *  <li>{@link org.apache.http.params.CoreConnectionPNames#MAX_HEADER_COUNT}</li>
- *  <li>{@link org.apache.http.params.CoreConnectionPNames#MIN_CHUNK_LIMIT}</li>
- * </ul>
- *
- * @since 4.0
- */
- at NotThreadSafe
+ at Deprecated
 public class SocketHttpServerConnection extends
         AbstractHttpServerConnection implements HttpInetConnection {
 
@@ -72,16 +56,12 @@ public class SocketHttpServerConnection extends
     }
 
     protected void assertNotOpen() {
-        if (this.open) {
-            throw new IllegalStateException("Connection is already open");
-        }
+        Asserts.check(!this.open, "Connection is already open");
     }
 
     @Override
     protected void assertOpen() {
-        if (!this.open) {
-            throw new IllegalStateException("Connection is not open");
-        }
+        Asserts.check(this.open, "Connection is not open");
     }
 
     /**
@@ -101,7 +81,7 @@ public class SocketHttpServerConnection extends
      */
     protected SessionInputBuffer createSessionInputBuffer(
             final Socket socket,
-            int buffersize,
+            final int buffersize,
             final HttpParams params) throws IOException {
         return new SocketInputBuffer(socket, buffersize, params);
     }
@@ -123,7 +103,7 @@ public class SocketHttpServerConnection extends
      */
     protected SessionOutputBuffer createSessionOutputBuffer(
             final Socket socket,
-            int buffersize,
+            final int buffersize,
             final HttpParams params) throws IOException {
         return new SocketOutputBuffer(socket, buffersize, params);
     }
@@ -147,16 +127,11 @@ public class SocketHttpServerConnection extends
      * @throws IOException in case of an I/O error.
      */
     protected void bind(final Socket socket, final HttpParams params) throws IOException {
-        if (socket == null) {
-            throw new IllegalArgumentException("Socket may not be null");
-        }
-        if (params == null) {
-            throw new IllegalArgumentException("HTTP parameters may not be null");
-        }
+        Args.notNull(socket, "Socket");
+        Args.notNull(params, "HTTP parameters");
         this.socket = socket;
 
-        int buffersize = HttpConnectionParams.getSocketBufferSize(params);
-
+        final int buffersize = params.getIntParameter(CoreConnectionPNames.SOCKET_BUFFER_SIZE, -1);
         init(
                 createSessionInputBuffer(socket, buffersize, params),
                 createSessionOutputBuffer(socket, buffersize, params),
@@ -205,12 +180,12 @@ public class SocketHttpServerConnection extends
         }
     }
 
-    public void setSocketTimeout(int timeout) {
+    public void setSocketTimeout(final int timeout) {
         assertOpen();
         if (this.socket != null) {
             try {
                 this.socket.setSoTimeout(timeout);
-            } catch (SocketException ignore) {
+            } catch (final SocketException ignore) {
                 // It is not quite clear from the Sun's documentation if there are any
                 // other legitimate cases for a socket exception to be thrown when setting
                 // SO_TIMEOUT besides the socket being already closed
@@ -222,7 +197,7 @@ public class SocketHttpServerConnection extends
         if (this.socket != null) {
             try {
                 return this.socket.getSoTimeout();
-            } catch (SocketException ignore) {
+            } catch (final SocketException ignore) {
                 return -1;
             }
         } else {
@@ -232,7 +207,7 @@ public class SocketHttpServerConnection extends
 
     public void shutdown() throws IOException {
         this.open = false;
-        Socket tmpsocket = this.socket;
+        final Socket tmpsocket = this.socket;
         if (tmpsocket != null) {
             tmpsocket.close();
         }
@@ -244,19 +219,19 @@ public class SocketHttpServerConnection extends
         }
         this.open = false;
         this.open = false;
-        Socket sock = this.socket;
+        final Socket sock = this.socket;
         try {
             doFlush();
             try {
                 try {
                     sock.shutdownOutput();
-                } catch (IOException ignore) {
+                } catch (final IOException ignore) {
                 }
                 try {
                     sock.shutdownInput();
-                } catch (IOException ignore) {
+                } catch (final IOException ignore) {
                 }
-            } catch (UnsupportedOperationException ignore) {
+            } catch (final UnsupportedOperationException ignore) {
                 // if one isn't supported, the other one isn't either
             }
         } finally {
@@ -266,7 +241,7 @@ public class SocketHttpServerConnection extends
 
     private static void formatAddress(final StringBuilder buffer, final SocketAddress socketAddress) {
         if (socketAddress instanceof InetSocketAddress) {
-            InetSocketAddress addr = ((InetSocketAddress) socketAddress);
+            final InetSocketAddress addr = ((InetSocketAddress) socketAddress);
             buffer.append(addr.getAddress() != null ? addr.getAddress().getHostAddress() :
                 addr.getAddress())
             .append(':')
@@ -279,9 +254,9 @@ public class SocketHttpServerConnection extends
     @Override
     public String toString() {
         if (this.socket != null) {
-            StringBuilder buffer = new StringBuilder();
-            SocketAddress remoteAddress = this.socket.getRemoteSocketAddress();
-            SocketAddress localAddress = this.socket.getLocalSocketAddress();
+            final StringBuilder buffer = new StringBuilder();
+            final SocketAddress remoteAddress = this.socket.getRemoteSocketAddress();
+            final SocketAddress localAddress = this.socket.getLocalSocketAddress();
             if (remoteAddress != null && localAddress != null) {
                 formatAddress(buffer, localAddress);
                 buffer.append("<->");
diff --git a/httpcore/src/main/java/org/apache/http/impl/entity/EntityDeserializer.java b/httpcore/src/main/java-deprecated/org/apache/http/impl/entity/EntityDeserializer.java
similarity index 87%
rename from httpcore/src/main/java/org/apache/http/impl/entity/EntityDeserializer.java
rename to httpcore/src/main/java-deprecated/org/apache/http/impl/entity/EntityDeserializer.java
index ccbb4a8..d246379 100644
--- a/httpcore/src/main/java/org/apache/http/impl/entity/EntityDeserializer.java
+++ b/httpcore/src/main/java-deprecated/org/apache/http/impl/entity/EntityDeserializer.java
@@ -41,6 +41,7 @@ import org.apache.http.impl.io.ContentLengthInputStream;
 import org.apache.http.impl.io.IdentityInputStream;
 import org.apache.http.io.SessionInputBuffer;
 import org.apache.http.protocol.HTTP;
+import org.apache.http.util.Args;
 
 /**
  * HTTP entity deserializer.
@@ -57,18 +58,18 @@ import org.apache.http.protocol.HTTP;
  * transparently for the consumer.
  *
  * @since 4.0
+ *
+ * @deprecated (4.3) use {@link org.apache.http.impl.BHttpConnectionBase}
  */
 @Immutable // assuming injected dependencies are immutable
+ at Deprecated
 public class EntityDeserializer {
 
     private final ContentLengthStrategy lenStrategy;
 
     public EntityDeserializer(final ContentLengthStrategy lenStrategy) {
         super();
-        if (lenStrategy == null) {
-            throw new IllegalArgumentException("Content length strategy may not be null");
-        }
-        this.lenStrategy = lenStrategy;
+        this.lenStrategy = Args.notNull(lenStrategy, "Content length strategy");
     }
 
     /**
@@ -89,9 +90,9 @@ public class EntityDeserializer {
     protected BasicHttpEntity doDeserialize(
             final SessionInputBuffer inbuffer,
             final HttpMessage message) throws HttpException, IOException {
-        BasicHttpEntity entity = new BasicHttpEntity();
+        final BasicHttpEntity entity = new BasicHttpEntity();
 
-        long len = this.lenStrategy.determineLength(message);
+        final long len = this.lenStrategy.determineLength(message);
         if (len == ContentLengthStrategy.CHUNKED) {
             entity.setChunked(true);
             entity.setContentLength(-1);
@@ -106,11 +107,11 @@ public class EntityDeserializer {
             entity.setContent(new ContentLengthInputStream(inbuffer, len));
         }
 
-        Header contentTypeHeader = message.getFirstHeader(HTTP.CONTENT_TYPE);
+        final Header contentTypeHeader = message.getFirstHeader(HTTP.CONTENT_TYPE);
         if (contentTypeHeader != null) {
             entity.setContentType(contentTypeHeader);
         }
-        Header contentEncodingHeader = message.getFirstHeader(HTTP.CONTENT_ENCODING);
+        final Header contentEncodingHeader = message.getFirstHeader(HTTP.CONTENT_ENCODING);
         if (contentEncodingHeader != null) {
             entity.setContentEncoding(contentEncodingHeader);
         }
@@ -134,12 +135,8 @@ public class EntityDeserializer {
     public HttpEntity deserialize(
             final SessionInputBuffer inbuffer,
             final HttpMessage message) throws HttpException, IOException {
-        if (inbuffer == null) {
-            throw new IllegalArgumentException("Session input buffer may not be null");
-        }
-        if (message == null) {
-            throw new IllegalArgumentException("HTTP message may not be null");
-        }
+        Args.notNull(inbuffer, "Session input buffer");
+        Args.notNull(message, "HTTP message");
         return doDeserialize(inbuffer, message);
     }
 
diff --git a/httpcore/src/main/java/org/apache/http/impl/entity/EntitySerializer.java b/httpcore/src/main/java-deprecated/org/apache/http/impl/entity/EntitySerializer.java
similarity index 86%
rename from httpcore/src/main/java/org/apache/http/impl/entity/EntitySerializer.java
rename to httpcore/src/main/java-deprecated/org/apache/http/impl/entity/EntitySerializer.java
index 83cadd1..6207cf1 100644
--- a/httpcore/src/main/java/org/apache/http/impl/entity/EntitySerializer.java
+++ b/httpcore/src/main/java-deprecated/org/apache/http/impl/entity/EntitySerializer.java
@@ -39,6 +39,7 @@ import org.apache.http.impl.io.ChunkedOutputStream;
 import org.apache.http.impl.io.ContentLengthOutputStream;
 import org.apache.http.impl.io.IdentityOutputStream;
 import org.apache.http.io.SessionOutputBuffer;
+import org.apache.http.util.Args;
 
 /**
  * HTTP entity serializer.
@@ -54,18 +55,18 @@ import org.apache.http.io.SessionOutputBuffer;
  * using a transfer coding based on properties on the HTTP message.
  *
  * @since 4.0
+ *
+ * @deprecated (4.3) use {@link org.apache.http.impl.BHttpConnectionBase}
  */
 @Immutable // assuming injected dependencies are immutable
+ at Deprecated
 public class EntitySerializer {
 
     private final ContentLengthStrategy lenStrategy;
 
     public EntitySerializer(final ContentLengthStrategy lenStrategy) {
         super();
-        if (lenStrategy == null) {
-            throw new IllegalArgumentException("Content length strategy may not be null");
-        }
-        this.lenStrategy = lenStrategy;
+        this.lenStrategy = Args.notNull(lenStrategy, "Content length strategy");
     }
 
     /**
@@ -85,7 +86,7 @@ public class EntitySerializer {
     protected OutputStream doSerialize(
             final SessionOutputBuffer outbuffer,
             final HttpMessage message) throws HttpException, IOException {
-        long len = this.lenStrategy.determineLength(message);
+        final long len = this.lenStrategy.determineLength(message);
         if (len == ContentLengthStrategy.CHUNKED) {
             return new ChunkedOutputStream(outbuffer);
         } else if (len == ContentLengthStrategy.IDENTITY) {
@@ -109,16 +110,10 @@ public class EntitySerializer {
             final SessionOutputBuffer outbuffer,
             final HttpMessage message,
             final HttpEntity entity) throws HttpException, IOException {
-        if (outbuffer == null) {
-            throw new IllegalArgumentException("Session output buffer may not be null");
-        }
-        if (message == null) {
-            throw new IllegalArgumentException("HTTP message may not be null");
-        }
-        if (entity == null) {
-            throw new IllegalArgumentException("HTTP entity may not be null");
-        }
-        OutputStream outstream = doSerialize(outbuffer, message);
+        Args.notNull(outbuffer, "Session output buffer");
+        Args.notNull(message, "HTTP message");
+        Args.notNull(entity, "HTTP entity");
+        final OutputStream outstream = doSerialize(outbuffer, message);
         entity.writeTo(outstream);
         outstream.close();
     }
diff --git a/httpcore/src/main/java/org/apache/http/impl/io/AbstractSessionInputBuffer.java b/httpcore/src/main/java-deprecated/org/apache/http/impl/io/AbstractSessionInputBuffer.java
similarity index 78%
copy from httpcore/src/main/java/org/apache/http/impl/io/AbstractSessionInputBuffer.java
copy to httpcore/src/main/java-deprecated/org/apache/http/impl/io/AbstractSessionInputBuffer.java
index b160164..a13f11e 100644
--- a/httpcore/src/main/java/org/apache/http/impl/io/AbstractSessionInputBuffer.java
+++ b/httpcore/src/main/java-deprecated/org/apache/http/impl/io/AbstractSessionInputBuffer.java
@@ -36,14 +36,16 @@ import java.nio.charset.CharsetDecoder;
 import java.nio.charset.CoderResult;
 import java.nio.charset.CodingErrorAction;
 
+import org.apache.http.Consts;
 import org.apache.http.annotation.NotThreadSafe;
 import org.apache.http.io.BufferInfo;
-import org.apache.http.io.SessionInputBuffer;
 import org.apache.http.io.HttpTransportMetrics;
+import org.apache.http.io.SessionInputBuffer;
 import org.apache.http.params.CoreConnectionPNames;
+import org.apache.http.params.CoreProtocolPNames;
 import org.apache.http.params.HttpParams;
-import org.apache.http.params.HttpProtocolParams;
 import org.apache.http.protocol.HTTP;
+import org.apache.http.util.Args;
 import org.apache.http.util.ByteArrayBuffer;
 import org.apache.http.util.CharArrayBuffer;
 
@@ -56,39 +58,32 @@ import org.apache.http.util.CharArrayBuffer;
  * class treat a lone LF as valid line delimiters in addition to CR-LF required
  * by the HTTP specification.
  *
- * <p>
- * The following parameters can be used to customize the behavior of this
- * class:
- * <ul>
- *  <li>{@link org.apache.http.params.CoreProtocolPNames#HTTP_ELEMENT_CHARSET}</li>
- *  <li>{@link org.apache.http.params.CoreConnectionPNames#MAX_LINE_LENGTH}</li>
- *  <li>{@link org.apache.http.params.CoreConnectionPNames#MIN_CHUNK_LIMIT}</li>
- * </ul>
  * @since 4.0
+ *
+ * @deprecated (4.3) use {@link SessionInputBufferImpl}
  */
 @NotThreadSafe
+ at Deprecated
 public abstract class AbstractSessionInputBuffer implements SessionInputBuffer, BufferInfo {
 
-    private static final Charset ASCII = Charset.forName("US-ASCII");
-
     private InputStream instream;
     private byte[] buffer;
+    private ByteArrayBuffer linebuffer;
+    private Charset charset;
+    private boolean ascii;
+    private int maxLineLen;
+    private int minChunkLimit;
+    private HttpTransportMetricsImpl metrics;
+    private CodingErrorAction onMalformedCharAction;
+    private CodingErrorAction onUnmappableCharAction;
+
     private int bufferpos;
     private int bufferlen;
-
-    private ByteArrayBuffer linebuffer = null;
-
-    private Charset charset;
     private CharsetDecoder decoder;
     private CharBuffer cbuf;
-    private boolean ascii = true;
-    private int maxLineLen = -1;
-    private int minChunkLimit = 512;
-
-    private HttpTransportMetricsImpl metrics;
 
-    private CodingErrorAction onMalformedInputAction;
-    private CodingErrorAction onUnMappableInputAction;
+    public AbstractSessionInputBuffer() {
+    }
 
     /**
      * Initializes this session input buffer.
@@ -97,29 +92,28 @@ public abstract class AbstractSessionInputBuffer implements SessionInputBuffer,
      * @param buffersize the size of the internal buffer.
      * @param params HTTP parameters.
      */
-    protected void init(final InputStream instream, int buffersize, final HttpParams params) {
-        if (instream == null) {
-            throw new IllegalArgumentException("Input stream may not be null");
-        }
-        if (buffersize <= 0) {
-            throw new IllegalArgumentException("Buffer size may not be negative or zero");
-        }
-        if (params == null) {
-            throw new IllegalArgumentException("HTTP parameters may not be null");
-        }
+    protected void init(final InputStream instream, final int buffersize, final HttpParams params) {
+        Args.notNull(instream, "Input stream");
+        Args.notNegative(buffersize, "Buffer size");
+        Args.notNull(params, "HTTP parameters");
         this.instream = instream;
         this.buffer = new byte[buffersize];
         this.bufferpos = 0;
         this.bufferlen = 0;
         this.linebuffer = new ByteArrayBuffer(buffersize);
-        this.charset = Charset.forName(HttpProtocolParams.getHttpElementCharset(params));
-        this.ascii = this.charset.equals(ASCII);
+        final String charset = (String) params.getParameter(CoreProtocolPNames.HTTP_ELEMENT_CHARSET);
+        this.charset = charset != null ? Charset.forName(charset) : Consts.ASCII;
+        this.ascii = this.charset.equals(Consts.ASCII);
         this.decoder = null;
         this.maxLineLen = params.getIntParameter(CoreConnectionPNames.MAX_LINE_LENGTH, -1);
         this.minChunkLimit = params.getIntParameter(CoreConnectionPNames.MIN_CHUNK_LIMIT, 512);
         this.metrics = createTransportMetrics();
-        this.onMalformedInputAction = HttpProtocolParams.getMalformedInputAction(params);
-        this.onUnMappableInputAction = HttpProtocolParams.getUnmappableInputAction(params);
+        final CodingErrorAction a1 = (CodingErrorAction) params.getParameter(
+                CoreProtocolPNames.HTTP_MALFORMED_INPUT_ACTION);
+        this.onMalformedCharAction = a1 != null ? a1 : CodingErrorAction.REPORT;
+        final CodingErrorAction a2 = (CodingErrorAction) params.getParameter(
+                CoreProtocolPNames.HTTP_UNMAPPABLE_INPUT_ACTION);
+        this.onUnmappableCharAction = a2 != null? a2 : CodingErrorAction.REPORT;
     }
 
     /**
@@ -153,16 +147,16 @@ public abstract class AbstractSessionInputBuffer implements SessionInputBuffer,
     protected int fillBuffer() throws IOException {
         // compact the buffer if necessary
         if (this.bufferpos > 0) {
-            int len = this.bufferlen - this.bufferpos;
+            final int len = this.bufferlen - this.bufferpos;
             if (len > 0) {
                 System.arraycopy(this.buffer, this.bufferpos, this.buffer, 0, len);
             }
             this.bufferpos = 0;
             this.bufferlen = len;
         }
-        int l;
-        int off = this.bufferlen;
-        int len = this.buffer.length - off;
+        final int l;
+        final int off = this.bufferlen;
+        final int len = this.buffer.length - off;
         l = this.instream.read(this.buffer, off, len);
         if (l == -1) {
             return -1;
@@ -178,7 +172,7 @@ public abstract class AbstractSessionInputBuffer implements SessionInputBuffer,
     }
 
     public int read() throws IOException {
-        int noRead = 0;
+        int noRead;
         while (!hasBufferedData()) {
             noRead = fillBuffer();
             if (noRead == -1) {
@@ -188,12 +182,12 @@ public abstract class AbstractSessionInputBuffer implements SessionInputBuffer,
         return this.buffer[this.bufferpos++] & 0xff;
     }
 
-    public int read(final byte[] b, int off, int len) throws IOException {
+    public int read(final byte[] b, final int off, final int len) throws IOException {
         if (b == null) {
             return 0;
         }
         if (hasBufferedData()) {
-            int chunk = Math.min(len, this.bufferlen - this.bufferpos);
+            final int chunk = Math.min(len, this.bufferlen - this.bufferpos);
             System.arraycopy(this.buffer, this.bufferpos, b, off, chunk);
             this.bufferpos += chunk;
             return chunk;
@@ -201,7 +195,7 @@ public abstract class AbstractSessionInputBuffer implements SessionInputBuffer,
         // If the remaining capacity is big enough, read directly from the
         // underlying input stream bypassing the buffer.
         if (len > this.minChunkLimit) {
-            int read = this.instream.read(b, off, len);
+            final int read = this.instream.read(b, off, len);
             if (read > 0) {
                 this.metrics.incrementBytesTransferred(read);
             }
@@ -209,12 +203,12 @@ public abstract class AbstractSessionInputBuffer implements SessionInputBuffer,
         } else {
             // otherwise read to the buffer first
             while (!hasBufferedData()) {
-                int noRead = fillBuffer();
+                final int noRead = fillBuffer();
                 if (noRead == -1) {
                     return -1;
                 }
             }
-            int chunk = Math.min(len, this.bufferlen - this.bufferpos);
+            final int chunk = Math.min(len, this.bufferlen - this.bufferpos);
             System.arraycopy(this.buffer, this.bufferpos, b, off, chunk);
             this.bufferpos += chunk;
             return chunk;
@@ -253,14 +247,12 @@ public abstract class AbstractSessionInputBuffer implements SessionInputBuffer,
      * @exception  IOException  if an I/O error occurs.
      */
     public int readLine(final CharArrayBuffer charbuffer) throws IOException {
-        if (charbuffer == null) {
-            throw new IllegalArgumentException("Char array buffer may not be null");
-        }
+        Args.notNull(charbuffer, "Char array buffer");
         int noRead = 0;
         boolean retry = true;
         while (retry) {
             // attempt to find end of line (LF)
-            int i = locateLF();
+            final int i = locateLF();
             if (i != -1) {
                 // end of line found.
                 if (this.linebuffer.isEmpty()) {
@@ -268,13 +260,13 @@ public abstract class AbstractSessionInputBuffer implements SessionInputBuffer,
                     return lineFromReadBuffer(charbuffer, i);
                 }
                 retry = false;
-                int len = i + 1 - this.bufferpos;
+                final int len = i + 1 - this.bufferpos;
                 this.linebuffer.append(this.buffer, this.bufferpos, len);
                 this.bufferpos = i + 1;
             } else {
                 // end of line not found
                 if (hasBufferedData()) {
-                    int len = this.bufferlen - this.bufferpos;
+                    final int len = this.bufferlen - this.bufferpos;
                     this.linebuffer.append(this.buffer, this.bufferpos, len);
                     this.bufferpos = this.bufferlen;
                 }
@@ -325,27 +317,27 @@ public abstract class AbstractSessionInputBuffer implements SessionInputBuffer,
         if (this.ascii) {
             charbuffer.append(this.linebuffer, 0, len);
         } else {
-            ByteBuffer bbuf =  ByteBuffer.wrap(this.linebuffer.buffer(), 0, len);
+            final ByteBuffer bbuf =  ByteBuffer.wrap(this.linebuffer.buffer(), 0, len);
             len = appendDecoded(charbuffer, bbuf);
         }
         this.linebuffer.clear();
         return len;
     }
 
-    private int lineFromReadBuffer(final CharArrayBuffer charbuffer, int pos)
+    private int lineFromReadBuffer(final CharArrayBuffer charbuffer, final int position)
             throws IOException {
-        int off = this.bufferpos;
-        int len;
-        this.bufferpos = pos + 1;
-        if (pos > off && this.buffer[pos - 1] == HTTP.CR) {
+        final int off = this.bufferpos;
+        int i = position;
+        this.bufferpos = i + 1;
+        if (i > off && this.buffer[i - 1] == HTTP.CR) {
             // skip CR if found
-            pos--;
+            i--;
         }
-        len = pos - off;
+        int len = i - off;
         if (this.ascii) {
             charbuffer.append(this.buffer, off, len);
         } else {
-            ByteBuffer bbuf =  ByteBuffer.wrap(this.buffer, off, len);
+            final ByteBuffer bbuf =  ByteBuffer.wrap(this.buffer, off, len);
             len = appendDecoded(charbuffer, bbuf);
         }
         return len;
@@ -358,8 +350,8 @@ public abstract class AbstractSessionInputBuffer implements SessionInputBuffer,
         }
         if (this.decoder == null) {
             this.decoder = this.charset.newDecoder();
-            this.decoder.onMalformedInput(this.onMalformedInputAction);
-            this.decoder.onUnmappableCharacter(this.onUnMappableInputAction);
+            this.decoder.onMalformedInput(this.onMalformedCharAction);
+            this.decoder.onUnmappableCharacter(this.onUnmappableCharAction);
         }
         if (this.cbuf == null) {
             this.cbuf = CharBuffer.allocate(1024);
@@ -367,10 +359,10 @@ public abstract class AbstractSessionInputBuffer implements SessionInputBuffer,
         this.decoder.reset();
         int len = 0;
         while (bbuf.hasRemaining()) {
-            CoderResult result = this.decoder.decode(bbuf, this.cbuf, true);
+            final CoderResult result = this.decoder.decode(bbuf, this.cbuf, true);
             len += handleDecodingResult(result, charbuffer, bbuf);
         }
-        CoderResult result = this.decoder.flush(this.cbuf);
+        final CoderResult result = this.decoder.flush(this.cbuf);
         len += handleDecodingResult(result, charbuffer, bbuf);
         this.cbuf.clear();
         return len;
@@ -384,7 +376,7 @@ public abstract class AbstractSessionInputBuffer implements SessionInputBuffer,
             result.throwException();
         }
         this.cbuf.flip();
-        int len = this.cbuf.remaining();
+        final int len = this.cbuf.remaining();
         while (this.cbuf.hasRemaining()) {
             charbuffer.append(this.cbuf.get());
         }
@@ -393,8 +385,8 @@ public abstract class AbstractSessionInputBuffer implements SessionInputBuffer,
     }
 
     public String readLine() throws IOException {
-        CharArrayBuffer charbuffer = new CharArrayBuffer(64);
-        int l = readLine(charbuffer);
+        final CharArrayBuffer charbuffer = new CharArrayBuffer(64);
+        final int l = readLine(charbuffer);
         if (l != -1) {
             return charbuffer.toString();
         } else {
diff --git a/httpcore/src/main/java/org/apache/http/impl/io/AbstractSessionOutputBuffer.java b/httpcore/src/main/java-deprecated/org/apache/http/impl/io/AbstractSessionOutputBuffer.java
similarity index 70%
copy from httpcore/src/main/java/org/apache/http/impl/io/AbstractSessionOutputBuffer.java
copy to httpcore/src/main/java-deprecated/org/apache/http/impl/io/AbstractSessionOutputBuffer.java
index 492704d..398c13f 100644
--- a/httpcore/src/main/java/org/apache/http/impl/io/AbstractSessionOutputBuffer.java
+++ b/httpcore/src/main/java-deprecated/org/apache/http/impl/io/AbstractSessionOutputBuffer.java
@@ -36,14 +36,16 @@ import java.nio.charset.CharsetEncoder;
 import java.nio.charset.CoderResult;
 import java.nio.charset.CodingErrorAction;
 
+import org.apache.http.Consts;
 import org.apache.http.annotation.NotThreadSafe;
 import org.apache.http.io.BufferInfo;
-import org.apache.http.io.SessionOutputBuffer;
 import org.apache.http.io.HttpTransportMetrics;
+import org.apache.http.io.SessionOutputBuffer;
 import org.apache.http.params.CoreConnectionPNames;
+import org.apache.http.params.CoreProtocolPNames;
 import org.apache.http.params.HttpParams;
-import org.apache.http.params.HttpProtocolParams;
 import org.apache.http.protocol.HTTP;
+import org.apache.http.util.Args;
 import org.apache.http.util.ByteArrayBuffer;
 import org.apache.http.util.CharArrayBuffer;
 
@@ -51,66 +53,76 @@ import org.apache.http.util.CharArrayBuffer;
  * Abstract base class for session output buffers that stream data to
  * an arbitrary {@link OutputStream}. This class buffers small chunks of
  * output data in an internal byte array for optimal output performance.
- * <p>
+ * </p>
  * {@link #writeLine(CharArrayBuffer)} and {@link #writeLine(String)} methods
  * of this class use CR-LF as a line delimiter.
- * <p>
- * The following parameters can be used to customize the behavior of this
- * class:
- * <ul>
- *  <li>{@link org.apache.http.params.CoreProtocolPNames#HTTP_ELEMENT_CHARSET}</li>
- *  <li>{@link org.apache.http.params.CoreConnectionPNames#MIN_CHUNK_LIMIT}</li>
- * </ul>
- * <p>
  *
  * @since 4.0
+ *
+ * @deprecated (4.3) use {@link SessionOutputBufferImpl}
  */
 @NotThreadSafe
+ at Deprecated
 public abstract class AbstractSessionOutputBuffer implements SessionOutputBuffer, BufferInfo {
 
-    private static final Charset ASCII = Charset.forName("US-ASCII");
     private static final byte[] CRLF = new byte[] {HTTP.CR, HTTP.LF};
 
     private OutputStream outstream;
     private ByteArrayBuffer buffer;
-
     private Charset charset;
+    private boolean ascii;
+    private int minChunkLimit;
+    private HttpTransportMetricsImpl metrics;
+    private CodingErrorAction onMalformedCharAction;
+    private CodingErrorAction onUnmappableCharAction;
+
     private CharsetEncoder encoder;
     private ByteBuffer bbuf;
-    private boolean ascii = true;
-    private int minChunkLimit = 512;
 
-    private HttpTransportMetricsImpl metrics;
+    protected AbstractSessionOutputBuffer(
+            final OutputStream outstream,
+            final int buffersize,
+            final Charset charset,
+            final int minChunkLimit,
+            final CodingErrorAction malformedCharAction,
+            final CodingErrorAction unmappableCharAction) {
+        super();
+        Args.notNull(outstream, "Input stream");
+        Args.notNegative(buffersize, "Buffer size");
+        this.outstream = outstream;
+        this.buffer = new ByteArrayBuffer(buffersize);
+        this.charset = charset != null ? charset : Consts.ASCII;
+        this.ascii = this.charset.equals(Consts.ASCII);
+        this.encoder = null;
+        this.minChunkLimit = minChunkLimit >= 0 ? minChunkLimit : 512;
+        this.metrics = createTransportMetrics();
+        this.onMalformedCharAction = malformedCharAction != null ? malformedCharAction :
+            CodingErrorAction.REPORT;
+        this.onUnmappableCharAction = unmappableCharAction != null? unmappableCharAction :
+            CodingErrorAction.REPORT;
+    }
 
-    private CodingErrorAction onMalformedInputAction;
-    private CodingErrorAction onUnMappableInputAction;
+    public AbstractSessionOutputBuffer() {
+    }
 
-    /**
-     * Initializes this session output buffer.
-     *
-     * @param outstream the destination output stream.
-     * @param buffersize the size of the internal buffer.
-     * @param params HTTP parameters.
-     */
-    protected void init(final OutputStream outstream, int buffersize, final HttpParams params) {
-        if (outstream == null) {
-            throw new IllegalArgumentException("Input stream may not be null");
-        }
-        if (buffersize <= 0) {
-            throw new IllegalArgumentException("Buffer size may not be negative or zero");
-        }
-        if (params == null) {
-            throw new IllegalArgumentException("HTTP parameters may not be null");
-        }
+    protected void init(final OutputStream outstream, final int buffersize, final HttpParams params) {
+        Args.notNull(outstream, "Input stream");
+        Args.notNegative(buffersize, "Buffer size");
+        Args.notNull(params, "HTTP parameters");
         this.outstream = outstream;
         this.buffer = new ByteArrayBuffer(buffersize);
-        this.charset = Charset.forName(HttpProtocolParams.getHttpElementCharset(params));
-        this.ascii = this.charset.equals(ASCII);
+        final String charset = (String) params.getParameter(CoreProtocolPNames.HTTP_ELEMENT_CHARSET);
+        this.charset = charset != null ? Charset.forName(charset) : Consts.ASCII;
+        this.ascii = this.charset.equals(Consts.ASCII);
         this.encoder = null;
         this.minChunkLimit = params.getIntParameter(CoreConnectionPNames.MIN_CHUNK_LIMIT, 512);
         this.metrics = createTransportMetrics();
-        this.onMalformedInputAction = HttpProtocolParams.getMalformedInputAction(params);
-        this.onUnMappableInputAction = HttpProtocolParams.getUnmappableInputAction(params);
+        final CodingErrorAction a1 = (CodingErrorAction) params.getParameter(
+                CoreProtocolPNames.HTTP_MALFORMED_INPUT_ACTION);
+        this.onMalformedCharAction = a1 != null ? a1 : CodingErrorAction.REPORT;
+        final CodingErrorAction a2 = (CodingErrorAction) params.getParameter(
+                CoreProtocolPNames.HTTP_UNMAPPABLE_INPUT_ACTION);
+        this.onUnmappableCharAction = a2 != null? a2 : CodingErrorAction.REPORT;
     }
 
     /**
@@ -142,7 +154,7 @@ public abstract class AbstractSessionOutputBuffer implements SessionOutputBuffer
     }
 
     protected void flushBuffer() throws IOException {
-        int len = this.buffer.length();
+        final int len = this.buffer.length();
         if (len > 0) {
             this.outstream.write(this.buffer.buffer(), 0, len);
             this.buffer.clear();
@@ -155,7 +167,7 @@ public abstract class AbstractSessionOutputBuffer implements SessionOutputBuffer
         this.outstream.flush();
     }
 
-    public void write(final byte[] b, int off, int len) throws IOException {
+    public void write(final byte[] b, final int off, final int len) throws IOException {
         if (b == null) {
             return;
         }
@@ -170,7 +182,7 @@ public abstract class AbstractSessionOutputBuffer implements SessionOutputBuffer
             this.metrics.incrementBytesTransferred(len);
         } else {
             // Do not let the buffer grow unnecessarily
-            int freecapacity = this.buffer.capacity() - this.buffer.length();
+            final int freecapacity = this.buffer.capacity() - this.buffer.length();
             if (len > freecapacity) {
                 // flush the buffer
                 flushBuffer();
@@ -187,7 +199,7 @@ public abstract class AbstractSessionOutputBuffer implements SessionOutputBuffer
         write(b, 0, b.length);
     }
 
-    public void write(int b) throws IOException {
+    public void write(final int b) throws IOException {
         if (this.buffer.isFull()) {
             flushBuffer();
         }
@@ -213,7 +225,7 @@ public abstract class AbstractSessionOutputBuffer implements SessionOutputBuffer
                     write(s.charAt(i));
                 }
             } else {
-                CharBuffer cbuf = CharBuffer.wrap(s);
+                final CharBuffer cbuf = CharBuffer.wrap(s);
                 writeEncoded(cbuf);
             }
         }
@@ -249,7 +261,7 @@ public abstract class AbstractSessionOutputBuffer implements SessionOutputBuffer
                 remaining -= chunk;
             }
         } else {
-            CharBuffer cbuf = CharBuffer.wrap(charbuffer.buffer(), 0, charbuffer.length());
+            final CharBuffer cbuf = CharBuffer.wrap(charbuffer.buffer(), 0, charbuffer.length());
             writeEncoded(cbuf);
         }
         write(CRLF);
@@ -261,18 +273,18 @@ public abstract class AbstractSessionOutputBuffer implements SessionOutputBuffer
         }
         if (this.encoder == null) {
             this.encoder = this.charset.newEncoder();
-            this.encoder.onMalformedInput(this.onMalformedInputAction);
-            this.encoder.onUnmappableCharacter(this.onUnMappableInputAction);
+            this.encoder.onMalformedInput(this.onMalformedCharAction);
+            this.encoder.onUnmappableCharacter(this.onUnmappableCharAction);
         }
         if (this.bbuf == null) {
             this.bbuf = ByteBuffer.allocate(1024);
         }
         this.encoder.reset();
         while (cbuf.hasRemaining()) {
-            CoderResult result = this.encoder.encode(cbuf, this.bbuf, true);
+            final CoderResult result = this.encoder.encode(cbuf, this.bbuf, true);
             handleEncodingResult(result);
         }
-        CoderResult result = this.encoder.flush(this.bbuf);
+        final CoderResult result = this.encoder.flush(this.bbuf);
         handleEncodingResult(result);
         this.bbuf.clear();
     }
diff --git a/httpcore/src/main/java/org/apache/http/impl/io/HttpRequestParser.java b/httpcore/src/main/java-deprecated/org/apache/http/impl/io/HttpRequestParser.java
similarity index 87%
rename from httpcore/src/main/java/org/apache/http/impl/io/HttpRequestParser.java
rename to httpcore/src/main/java-deprecated/org/apache/http/impl/io/HttpRequestParser.java
index e662411..87c61dc 100644
--- a/httpcore/src/main/java/org/apache/http/impl/io/HttpRequestParser.java
+++ b/httpcore/src/main/java-deprecated/org/apache/http/impl/io/HttpRequestParser.java
@@ -32,15 +32,15 @@ import java.io.IOException;
 import org.apache.http.ConnectionClosedException;
 import org.apache.http.HttpException;
 import org.apache.http.HttpMessage;
-import org.apache.http.HttpRequest;
 import org.apache.http.HttpRequestFactory;
-import org.apache.http.RequestLine;
 import org.apache.http.ParseException;
+import org.apache.http.RequestLine;
 import org.apache.http.annotation.NotThreadSafe;
 import org.apache.http.io.SessionInputBuffer;
 import org.apache.http.message.LineParser;
 import org.apache.http.message.ParserCursor;
 import org.apache.http.params.HttpParams;
+import org.apache.http.util.Args;
 import org.apache.http.util.CharArrayBuffer;
 
 /**
@@ -55,7 +55,7 @@ import org.apache.http.util.CharArrayBuffer;
  * </ul>
  *
  * @since 4.0
- * 
+ *
  * @deprecated (4.2) use {@link DefaultHttpRequestParser}
  */
 @Deprecated
@@ -71,7 +71,7 @@ public class HttpRequestParser extends AbstractMessageParser<HttpMessage> {
      * @param buffer the session input buffer.
      * @param parser the line parser.
      * @param requestFactory the factory to use to create
-     *    {@link HttpRequest}s.
+     *    {@link org.apache.http.HttpRequest}s.
      * @param params HTTP parameters.
      */
     public HttpRequestParser(
@@ -80,10 +80,7 @@ public class HttpRequestParser extends AbstractMessageParser<HttpMessage> {
             final HttpRequestFactory requestFactory,
             final HttpParams params) {
         super(buffer, parser, params);
-        if (requestFactory == null) {
-            throw new IllegalArgumentException("Request factory may not be null");
-        }
-        this.requestFactory = requestFactory;
+        this.requestFactory = Args.notNull(requestFactory, "Request factory");
         this.lineBuf = new CharArrayBuffer(128);
     }
 
@@ -93,12 +90,12 @@ public class HttpRequestParser extends AbstractMessageParser<HttpMessage> {
         throws IOException, HttpException, ParseException {
 
         this.lineBuf.clear();
-        int i = sessionBuffer.readLine(this.lineBuf);
+        final int i = sessionBuffer.readLine(this.lineBuf);
         if (i == -1) {
             throw new ConnectionClosedException("Client closed connection");
         }
-        ParserCursor cursor = new ParserCursor(0, this.lineBuf.length());
-        RequestLine requestline = this.lineParser.parseRequestLine(this.lineBuf, cursor);
+        final ParserCursor cursor = new ParserCursor(0, this.lineBuf.length());
+        final RequestLine requestline = this.lineParser.parseRequestLine(this.lineBuf, cursor);
         return this.requestFactory.newHttpRequest(requestline);
     }
 
diff --git a/httpcore/src/main/java/org/apache/http/impl/io/HttpRequestWriter.java b/httpcore/src/main/java-deprecated/org/apache/http/impl/io/HttpRequestWriter.java
similarity index 96%
copy from httpcore/src/main/java/org/apache/http/impl/io/HttpRequestWriter.java
copy to httpcore/src/main/java-deprecated/org/apache/http/impl/io/HttpRequestWriter.java
index af57be2..f130247 100644
--- a/httpcore/src/main/java/org/apache/http/impl/io/HttpRequestWriter.java
+++ b/httpcore/src/main/java-deprecated/org/apache/http/impl/io/HttpRequestWriter.java
@@ -40,8 +40,11 @@ import org.apache.http.params.HttpParams;
  * of {@link SessionOutputBuffer}.
  *
  * @since 4.0
+ *
+ * @deprecated (4.3) use {@link DefaultHttpRequestWriter}
  */
 @NotThreadSafe
+ at Deprecated
 public class HttpRequestWriter extends AbstractMessageWriter<HttpRequest> {
 
     public HttpRequestWriter(final SessionOutputBuffer buffer,
diff --git a/httpcore/src/main/java/org/apache/http/impl/io/HttpResponseParser.java b/httpcore/src/main/java-deprecated/org/apache/http/impl/io/HttpResponseParser.java
similarity index 88%
rename from httpcore/src/main/java/org/apache/http/impl/io/HttpResponseParser.java
rename to httpcore/src/main/java-deprecated/org/apache/http/impl/io/HttpResponseParser.java
index 14f7e0f..26e78c5 100644
--- a/httpcore/src/main/java/org/apache/http/impl/io/HttpResponseParser.java
+++ b/httpcore/src/main/java-deprecated/org/apache/http/impl/io/HttpResponseParser.java
@@ -31,16 +31,16 @@ import java.io.IOException;
 
 import org.apache.http.HttpException;
 import org.apache.http.HttpMessage;
-import org.apache.http.HttpResponse;
 import org.apache.http.HttpResponseFactory;
 import org.apache.http.NoHttpResponseException;
-import org.apache.http.StatusLine;
 import org.apache.http.ParseException;
+import org.apache.http.StatusLine;
 import org.apache.http.annotation.NotThreadSafe;
 import org.apache.http.io.SessionInputBuffer;
 import org.apache.http.message.LineParser;
 import org.apache.http.message.ParserCursor;
 import org.apache.http.params.HttpParams;
+import org.apache.http.util.Args;
 import org.apache.http.util.CharArrayBuffer;
 
 /**
@@ -55,7 +55,7 @@ import org.apache.http.util.CharArrayBuffer;
  * </ul>
  *
  * @since 4.0
- * 
+ *
  * @deprecated (4.2) use {@link DefaultHttpResponseParser}
  */
 @Deprecated
@@ -71,7 +71,7 @@ public class HttpResponseParser extends AbstractMessageParser<HttpMessage> {
      * @param buffer the session input buffer.
      * @param parser the line parser.
      * @param responseFactory the factory to use to create
-     *    {@link HttpResponse}s.
+     *    {@link org.apache.http.HttpResponse}s.
      * @param params HTTP parameters.
      */
     public HttpResponseParser(
@@ -80,10 +80,7 @@ public class HttpResponseParser extends AbstractMessageParser<HttpMessage> {
             final HttpResponseFactory responseFactory,
             final HttpParams params) {
         super(buffer, parser, params);
-        if (responseFactory == null) {
-            throw new IllegalArgumentException("Response factory may not be null");
-        }
-        this.responseFactory = responseFactory;
+        this.responseFactory = Args.notNull(responseFactory, "Response factory");
         this.lineBuf = new CharArrayBuffer(128);
     }
 
@@ -93,13 +90,13 @@ public class HttpResponseParser extends AbstractMessageParser<HttpMessage> {
         throws IOException, HttpException, ParseException {
 
         this.lineBuf.clear();
-        int i = sessionBuffer.readLine(this.lineBuf);
+        final int i = sessionBuffer.readLine(this.lineBuf);
         if (i == -1) {
             throw new NoHttpResponseException("The target server failed to respond");
         }
         //create the status line from the status string
-        ParserCursor cursor = new ParserCursor(0, this.lineBuf.length());
-        StatusLine statusline = lineParser.parseStatusLine(this.lineBuf, cursor);
+        final ParserCursor cursor = new ParserCursor(0, this.lineBuf.length());
+        final StatusLine statusline = lineParser.parseStatusLine(this.lineBuf, cursor);
         return this.responseFactory.newHttpResponse(statusline, null);
     }
 
diff --git a/httpcore/src/main/java/org/apache/http/impl/io/HttpResponseWriter.java b/httpcore/src/main/java-deprecated/org/apache/http/impl/io/HttpResponseWriter.java
similarity index 96%
copy from httpcore/src/main/java/org/apache/http/impl/io/HttpResponseWriter.java
copy to httpcore/src/main/java-deprecated/org/apache/http/impl/io/HttpResponseWriter.java
index bcefdb4..04d18df 100644
--- a/httpcore/src/main/java/org/apache/http/impl/io/HttpResponseWriter.java
+++ b/httpcore/src/main/java-deprecated/org/apache/http/impl/io/HttpResponseWriter.java
@@ -40,8 +40,11 @@ import org.apache.http.params.HttpParams;
  * of {@link SessionOutputBuffer}.
  *
  * @since 4.0
+ *
+ * @deprecated (4.3) use {@link DefaultHttpResponseWriter}
  */
 @NotThreadSafe
+ at Deprecated
 public class HttpResponseWriter extends AbstractMessageWriter<HttpResponse> {
 
     public HttpResponseWriter(final SessionOutputBuffer buffer,
diff --git a/httpcore/src/main/java/org/apache/http/impl/io/SocketInputBuffer.java b/httpcore/src/main/java-deprecated/org/apache/http/impl/io/SocketInputBuffer.java
similarity index 71%
rename from httpcore/src/main/java/org/apache/http/impl/io/SocketInputBuffer.java
rename to httpcore/src/main/java-deprecated/org/apache/http/impl/io/SocketInputBuffer.java
index 80406b2..2b2a8e9 100644
--- a/httpcore/src/main/java/org/apache/http/impl/io/SocketInputBuffer.java
+++ b/httpcore/src/main/java-deprecated/org/apache/http/impl/io/SocketInputBuffer.java
@@ -29,27 +29,22 @@ package org.apache.http.impl.io;
 
 import java.io.IOException;
 import java.net.Socket;
-import java.net.SocketTimeoutException;
 
 import org.apache.http.annotation.NotThreadSafe;
 import org.apache.http.io.EofSensor;
-import org.apache.http.io.SessionInputBuffer;
 import org.apache.http.params.HttpParams;
+import org.apache.http.util.Args;
 
 /**
- * {@link SessionInputBuffer} implementation bound to a {@link Socket}.
- * <p>
- * The following parameters can be used to customize the behavior of this
- * class:
- * <ul>
- *  <li>{@link org.apache.http.params.CoreProtocolPNames#HTTP_ELEMENT_CHARSET}</li>
- *  <li>{@link org.apache.http.params.CoreConnectionPNames#MAX_LINE_LENGTH}</li>
- *  <li>{@link org.apache.http.params.CoreConnectionPNames#MIN_CHUNK_LIMIT}</li>
- * </ul>
+ * {@link org.apache.http.io.SessionInputBuffer} implementation
+ * bound to a {@link Socket}.
  *
  * @since 4.0
+ *
+ * @deprecated (4.3) use {@link SessionInputBufferImpl}
  */
 @NotThreadSafe
+ at Deprecated
 public class SocketInputBuffer extends AbstractSessionInputBuffer implements EofSensor {
 
     private final Socket socket;
@@ -68,40 +63,37 @@ public class SocketInputBuffer extends AbstractSessionInputBuffer implements Eof
      */
     public SocketInputBuffer(
             final Socket socket,
-            int buffersize,
+            final int buffersize,
             final HttpParams params) throws IOException {
         super();
-        if (socket == null) {
-            throw new IllegalArgumentException("Socket may not be null");
-        }
+        Args.notNull(socket, "Socket");
         this.socket = socket;
         this.eof = false;
-        if (buffersize < 0) {
-            buffersize = socket.getReceiveBufferSize();
+        int n = buffersize;
+        if (n < 0) {
+            n = socket.getReceiveBufferSize();
         }
-        if (buffersize < 1024) {
-            buffersize = 1024;
+        if (n < 1024) {
+            n = 1024;
         }
-        init(socket.getInputStream(), buffersize, params);
+        init(socket.getInputStream(), n, params);
     }
 
     @Override
     protected int fillBuffer() throws IOException {
-        int i = super.fillBuffer();
+        final int i = super.fillBuffer();
         this.eof = i == -1;
         return i;
     }
 
-    public boolean isDataAvailable(int timeout) throws IOException {
+    public boolean isDataAvailable(final int timeout) throws IOException {
         boolean result = hasBufferedData();
         if (!result) {
-            int oldtimeout = this.socket.getSoTimeout();
+            final int oldtimeout = this.socket.getSoTimeout();
             try {
                 this.socket.setSoTimeout(timeout);
                 fillBuffer();
                 result = hasBufferedData();
-            } catch (SocketTimeoutException ex) {
-                throw ex;
             } finally {
                 socket.setSoTimeout(oldtimeout);
             }
diff --git a/httpcore/src/main/java/org/apache/http/impl/io/SocketOutputBuffer.java b/httpcore/src/main/java-deprecated/org/apache/http/impl/io/SocketOutputBuffer.java
similarity index 73%
rename from httpcore/src/main/java/org/apache/http/impl/io/SocketOutputBuffer.java
rename to httpcore/src/main/java-deprecated/org/apache/http/impl/io/SocketOutputBuffer.java
index 552afcc..9a35ae1 100644
--- a/httpcore/src/main/java/org/apache/http/impl/io/SocketOutputBuffer.java
+++ b/httpcore/src/main/java-deprecated/org/apache/http/impl/io/SocketOutputBuffer.java
@@ -31,22 +31,19 @@ import java.io.IOException;
 import java.net.Socket;
 
 import org.apache.http.annotation.NotThreadSafe;
-import org.apache.http.io.SessionOutputBuffer;
 import org.apache.http.params.HttpParams;
+import org.apache.http.util.Args;
 
 /**
- * {@link SessionOutputBuffer} implementation bound to a {@link Socket}.
- * <p>
- * The following parameters can be used to customize the behavior of this
- * class:
- * <ul>
- *  <li>{@link org.apache.http.params.CoreProtocolPNames#HTTP_ELEMENT_CHARSET}</li>
- *  <li>{@link org.apache.http.params.CoreConnectionPNames#MIN_CHUNK_LIMIT}</li>
- * </ul>
+ * {@link org.apache.http.io.SessionOutputBuffer} implementation
+ * bound to a {@link Socket}.
  *
  * @since 4.0
+ *
+ * @deprecated (4.3) use {@link SessionOutputBufferImpl}
  */
 @NotThreadSafe
+ at Deprecated
 public class SocketOutputBuffer extends AbstractSessionOutputBuffer {
 
     /**
@@ -61,19 +58,18 @@ public class SocketOutputBuffer extends AbstractSessionOutputBuffer {
      */
     public SocketOutputBuffer(
             final Socket socket,
-            int buffersize,
+            final int buffersize,
             final HttpParams params) throws IOException {
         super();
-        if (socket == null) {
-            throw new IllegalArgumentException("Socket may not be null");
-        }
-        if (buffersize < 0) {
-            buffersize = socket.getSendBufferSize();
+        Args.notNull(socket, "Socket");
+        int n = buffersize;
+        if (n < 0) {
+            n = socket.getSendBufferSize();
         }
-        if (buffersize < 1024) {
-            buffersize = 1024;
+        if (n < 1024) {
+            n = 1024;
         }
-        init(socket.getOutputStream(), buffersize, params);
+        init(socket.getOutputStream(), n, params);
     }
 
 }
diff --git a/httpcore/src/main/java/org/apache/http/params/DefaultedHttpParams.java b/httpcore/src/main/java-deprecated/org/apache/http/params/DefaultedHttpParams.java
similarity index 91%
rename from httpcore/src/main/java/org/apache/http/params/DefaultedHttpParams.java
rename to httpcore/src/main/java-deprecated/org/apache/http/params/DefaultedHttpParams.java
index 2ece8e5..884b0b3 100644
--- a/httpcore/src/main/java/org/apache/http/params/DefaultedHttpParams.java
+++ b/httpcore/src/main/java-deprecated/org/apache/http/params/DefaultedHttpParams.java
@@ -30,7 +30,7 @@ package org.apache.http.params;
 import java.util.HashSet;
 import java.util.Set;
 
-import org.apache.http.params.HttpParams;
+import org.apache.http.util.Args;
 
 /**
  * {@link HttpParams} implementation that delegates resolution of a parameter
@@ -39,7 +39,11 @@ import org.apache.http.params.HttpParams;
  * whereas the default collection is treated as read-only.
  *
  * @since 4.0
+ *
+ * @deprecated (4.3) use configuration classes provided 'org.apache.http.config'
+ *  and 'org.apache.http.client.config'
  */
+ at Deprecated
 public final class DefaultedHttpParams extends AbstractHttpParams {
 
     private final HttpParams local;
@@ -53,21 +57,15 @@ public final class DefaultedHttpParams extends AbstractHttpParams {
      */
     public DefaultedHttpParams(final HttpParams local, final HttpParams defaults) {
         super();
-        if (local == null) {
-            throw new IllegalArgumentException("HTTP parameters may not be null");
-        }
-        this.local = local;
+        this.local = Args.notNull(local, "Local HTTP parameters");
         this.defaults = defaults;
     }
 
     /**
      * Creates a copy of the local collection with the same default
-     *
-     * @deprecated (4.1)
      */
-    @Deprecated
     public HttpParams copy() {
-        HttpParams clone = this.local.copy();
+        final HttpParams clone = this.local.copy();
         return new DefaultedHttpParams(clone, this.defaults);
     }
 
@@ -103,9 +101,7 @@ public final class DefaultedHttpParams extends AbstractHttpParams {
     /**
      *
      * @return the default HttpParams collection
-     * @deprecated (4.1.1) do not use, will be removed in a later version
      */
-    @Deprecated
     public HttpParams getDefaults() {
         return this.defaults;
     }
@@ -123,7 +119,7 @@ public final class DefaultedHttpParams extends AbstractHttpParams {
      */
     @Override
     public Set<String> getNames() {
-        Set<String> combined = new HashSet<String>(getNames(defaults));
+        final Set<String> combined = new HashSet<String>(getNames(defaults));
         combined.addAll(getNames(this.local));
         return combined ;
     }
@@ -157,7 +153,7 @@ public final class DefaultedHttpParams extends AbstractHttpParams {
     }
 
     // Helper method
-    private Set<String> getNames(HttpParams params) {
+    private Set<String> getNames(final HttpParams params) {
         if (params instanceof HttpParamsNames) {
             return ((HttpParamsNames) params).getNames();
         }
diff --git a/httpcore/src/main/java/org/apache/http/params/HttpAbstractParamBean.java b/httpcore/src/main/java-deprecated/org/apache/http/params/HttpAbstractParamBean.java
similarity index 84%
rename from httpcore/src/main/java/org/apache/http/params/HttpAbstractParamBean.java
rename to httpcore/src/main/java-deprecated/org/apache/http/params/HttpAbstractParamBean.java
index f17a4f2..ba147a9 100644
--- a/httpcore/src/main/java/org/apache/http/params/HttpAbstractParamBean.java
+++ b/httpcore/src/main/java-deprecated/org/apache/http/params/HttpAbstractParamBean.java
@@ -27,17 +27,22 @@
 
 package org.apache.http.params;
 
+import org.apache.http.util.Args;
+
 /**
  * @since 4.0
+ *
+ * @deprecated (4.3) use configuration classes provided 'org.apache.http.config'
+ *  and 'org.apache.http.client.config'
  */
+ at Deprecated
 public abstract class HttpAbstractParamBean {
 
     protected final HttpParams params;
 
     public HttpAbstractParamBean (final HttpParams params) {
-        if (params == null)
-            throw new IllegalArgumentException("HTTP parameters may not be null");
-        this.params = params;
+        super();
+        this.params = Args.notNull(params, "HTTP parameters");
     }
 
 }
diff --git a/httpcore/src/main/java/org/apache/http/params/HttpConnectionParamBean.java b/httpcore/src/main/java-deprecated/org/apache/http/params/HttpConnectionParamBean.java
similarity index 79%
rename from httpcore/src/main/java/org/apache/http/params/HttpConnectionParamBean.java
rename to httpcore/src/main/java-deprecated/org/apache/http/params/HttpConnectionParamBean.java
index ce3dab1..975c276 100644
--- a/httpcore/src/main/java/org/apache/http/params/HttpConnectionParamBean.java
+++ b/httpcore/src/main/java-deprecated/org/apache/http/params/HttpConnectionParamBean.java
@@ -33,34 +33,38 @@ package org.apache.http.params;
  * conventions.
  *
  * @since 4.0
+ *
+ * @deprecated (4.3) use configuration classes provided 'org.apache.http.config'
+ *  and 'org.apache.http.client.config'
  */
+ at Deprecated
 public class HttpConnectionParamBean extends HttpAbstractParamBean {
 
     public HttpConnectionParamBean (final HttpParams params) {
         super(params);
     }
 
-    public void setSoTimeout (int soTimeout) {
+    public void setSoTimeout (final int soTimeout) {
         HttpConnectionParams.setSoTimeout(params, soTimeout);
     }
 
-    public void setTcpNoDelay (boolean tcpNoDelay) {
+    public void setTcpNoDelay (final boolean tcpNoDelay) {
         HttpConnectionParams.setTcpNoDelay(params, tcpNoDelay);
     }
 
-    public void setSocketBufferSize (int socketBufferSize) {
+    public void setSocketBufferSize (final int socketBufferSize) {
         HttpConnectionParams.setSocketBufferSize(params, socketBufferSize);
     }
 
-    public void setLinger (int linger) {
+    public void setLinger (final int linger) {
         HttpConnectionParams.setLinger(params, linger);
     }
 
-    public void setConnectionTimeout (int connectionTimeout) {
+    public void setConnectionTimeout (final int connectionTimeout) {
         HttpConnectionParams.setConnectionTimeout(params, connectionTimeout);
     }
 
-    public void setStaleCheckingEnabled (boolean staleCheckingEnabled) {
+    public void setStaleCheckingEnabled (final boolean staleCheckingEnabled) {
         HttpConnectionParams.setStaleCheckingEnabled(params, staleCheckingEnabled);
     }
 
diff --git a/httpcore/src/main/java/org/apache/http/params/HttpConnectionParams.java b/httpcore/src/main/java-deprecated/org/apache/http/params/HttpConnectionParams.java
similarity index 68%
rename from httpcore/src/main/java/org/apache/http/params/HttpConnectionParams.java
rename to httpcore/src/main/java-deprecated/org/apache/http/params/HttpConnectionParams.java
index 17cc349..746847f 100644
--- a/httpcore/src/main/java/org/apache/http/params/HttpConnectionParams.java
+++ b/httpcore/src/main/java-deprecated/org/apache/http/params/HttpConnectionParams.java
@@ -27,11 +27,17 @@
 
 package org.apache.http.params;
 
+import org.apache.http.util.Args;
+
 /**
  * Utility class for accessing connection parameters in {@link HttpParams}.
  *
  * @since 4.0
+ *
+ * @deprecated (4.3) use configuration classes provided 'org.apache.http.config'
+ *  and 'org.apache.http.client.config'
  */
+ at Deprecated
 public final class HttpConnectionParams implements CoreConnectionPNames {
 
     private HttpConnectionParams() {
@@ -46,9 +52,7 @@ public final class HttpConnectionParams implements CoreConnectionPNames {
      * @return SO_TIMEOUT.
      */
     public static int getSoTimeout(final HttpParams params) {
-        if (params == null) {
-            throw new IllegalArgumentException("HTTP parameters may not be null");
-        }
+        Args.notNull(params, "HTTP parameters");
         return params.getIntParameter(CoreConnectionPNames.SO_TIMEOUT, 0);
     }
 
@@ -58,10 +62,8 @@ public final class HttpConnectionParams implements CoreConnectionPNames {
      * @param params HTTP parameters.
      * @param timeout SO_TIMEOUT.
      */
-    public static void setSoTimeout(final HttpParams params, int timeout) {
-        if (params == null) {
-            throw new IllegalArgumentException("HTTP parameters may not be null");
-        }
+    public static void setSoTimeout(final HttpParams params, final int timeout) {
+        Args.notNull(params, "HTTP parameters");
         params.setIntParameter(CoreConnectionPNames.SO_TIMEOUT, timeout);
 
     }
@@ -76,9 +78,7 @@ public final class HttpConnectionParams implements CoreConnectionPNames {
      * @since 4.1
      */
     public static boolean getSoReuseaddr(final HttpParams params) {
-        if (params == null) {
-            throw new IllegalArgumentException("HTTP parameters may not be null");
-        }
+        Args.notNull(params, "HTTP parameters");
         return params.getBooleanParameter(CoreConnectionPNames.SO_REUSEADDR, false);
     }
 
@@ -90,10 +90,8 @@ public final class HttpConnectionParams implements CoreConnectionPNames {
      *
      * @since 4.1
      */
-    public static void setSoReuseaddr(final HttpParams params, boolean reuseaddr) {
-        if (params == null) {
-            throw new IllegalArgumentException("HTTP parameters may not be null");
-        }
+    public static void setSoReuseaddr(final HttpParams params, final boolean reuseaddr) {
+        Args.notNull(params, "HTTP parameters");
         params.setBooleanParameter(CoreConnectionPNames.SO_REUSEADDR, reuseaddr);
     }
 
@@ -105,11 +103,8 @@ public final class HttpConnectionParams implements CoreConnectionPNames {
      * @return Nagle's algorithm flag
      */
     public static boolean getTcpNoDelay(final HttpParams params) {
-        if (params == null) {
-            throw new IllegalArgumentException("HTTP parameters may not be null");
-        }
-        return params.getBooleanParameter
-            (CoreConnectionPNames.TCP_NODELAY, true);
+        Args.notNull(params, "HTTP parameters");
+        return params.getBooleanParameter(CoreConnectionPNames.TCP_NODELAY, true);
     }
 
     /**
@@ -118,10 +113,8 @@ public final class HttpConnectionParams implements CoreConnectionPNames {
      * @param params HTTP parameters.
      * @param value Nagle's algorithm flag
      */
-    public static void setTcpNoDelay(final HttpParams params, boolean value) {
-        if (params == null) {
-            throw new IllegalArgumentException("HTTP parameters may not be null");
-        }
+    public static void setTcpNoDelay(final HttpParams params, final boolean value) {
+        Args.notNull(params, "HTTP parameters");
         params.setBooleanParameter(CoreConnectionPNames.TCP_NODELAY, value);
     }
 
@@ -133,11 +126,8 @@ public final class HttpConnectionParams implements CoreConnectionPNames {
      * @return socket buffer size
      */
     public static int getSocketBufferSize(final HttpParams params) {
-        if (params == null) {
-            throw new IllegalArgumentException("HTTP parameters may not be null");
-        }
-        return params.getIntParameter
-            (CoreConnectionPNames.SOCKET_BUFFER_SIZE, -1);
+        Args.notNull(params, "HTTP parameters");
+        return params.getIntParameter(CoreConnectionPNames.SOCKET_BUFFER_SIZE, -1);
     }
 
     /**
@@ -147,10 +137,8 @@ public final class HttpConnectionParams implements CoreConnectionPNames {
      * @param params HTTP parameters.
      * @param size socket buffer size
      */
-    public static void setSocketBufferSize(final HttpParams params, int size) {
-        if (params == null) {
-            throw new IllegalArgumentException("HTTP parameters may not be null");
-        }
+    public static void setSocketBufferSize(final HttpParams params, final int size) {
+        Args.notNull(params, "HTTP parameters");
         params.setIntParameter(CoreConnectionPNames.SOCKET_BUFFER_SIZE, size);
     }
 
@@ -162,9 +150,7 @@ public final class HttpConnectionParams implements CoreConnectionPNames {
      * @return SO_LINGER.
      */
     public static int getLinger(final HttpParams params) {
-        if (params == null) {
-            throw new IllegalArgumentException("HTTP parameters may not be null");
-        }
+        Args.notNull(params, "HTTP parameters");
         return params.getIntParameter(CoreConnectionPNames.SO_LINGER, -1);
     }
 
@@ -174,10 +160,8 @@ public final class HttpConnectionParams implements CoreConnectionPNames {
      * @param params HTTP parameters.
      * @param value SO_LINGER.
      */
-    public static void setLinger(final HttpParams params, int value) {
-        if (params == null) {
-            throw new IllegalArgumentException("HTTP parameters may not be null");
-        }
+    public static void setLinger(final HttpParams params, final int value) {
+        Args.notNull(params, "HTTP parameters");
         params.setIntParameter(CoreConnectionPNames.SO_LINGER, value);
     }
 
@@ -189,11 +173,8 @@ public final class HttpConnectionParams implements CoreConnectionPNames {
      * @return connect timeout.
      */
     public static int getConnectionTimeout(final HttpParams params) {
-        if (params == null) {
-            throw new IllegalArgumentException("HTTP parameters may not be null");
-        }
-        return params.getIntParameter
-            (CoreConnectionPNames.CONNECTION_TIMEOUT, 0);
+        Args.notNull(params, "HTTP parameters");
+        return params.getIntParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 0);
     }
 
     /**
@@ -203,12 +184,9 @@ public final class HttpConnectionParams implements CoreConnectionPNames {
      * @param params HTTP parameters.
      * @param timeout connect timeout.
      */
-    public static void setConnectionTimeout(final HttpParams params, int timeout) {
-        if (params == null) {
-            throw new IllegalArgumentException("HTTP parameters may not be null");
-        }
-        params.setIntParameter
-            (CoreConnectionPNames.CONNECTION_TIMEOUT, timeout);
+    public static void setConnectionTimeout(final HttpParams params, final int timeout) {
+        Args.notNull(params, "HTTP parameters");
+        params.setIntParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, timeout);
     }
 
     /**
@@ -219,11 +197,8 @@ public final class HttpConnectionParams implements CoreConnectionPNames {
      * @return stale connection check flag.
      */
     public static boolean isStaleCheckingEnabled(final HttpParams params) {
-        if (params == null) {
-            throw new IllegalArgumentException("HTTP parameters may not be null");
-        }
-        return params.getBooleanParameter
-            (CoreConnectionPNames.STALE_CONNECTION_CHECK, true);
+        Args.notNull(params, "HTTP parameters");
+        return params.getBooleanParameter(CoreConnectionPNames.STALE_CONNECTION_CHECK, true);
     }
 
     /**
@@ -233,12 +208,9 @@ public final class HttpConnectionParams implements CoreConnectionPNames {
      * @param params HTTP parameters.
      * @param value stale connection check flag.
      */
-    public static void setStaleCheckingEnabled(final HttpParams params, boolean value) {
-        if (params == null) {
-            throw new IllegalArgumentException("HTTP parameters may not be null");
-        }
-        params.setBooleanParameter
-            (CoreConnectionPNames.STALE_CONNECTION_CHECK, value);
+    public static void setStaleCheckingEnabled(final HttpParams params, final boolean value) {
+        Args.notNull(params, "HTTP parameters");
+        params.setBooleanParameter(CoreConnectionPNames.STALE_CONNECTION_CHECK, value);
     }
 
     /**
@@ -251,9 +223,7 @@ public final class HttpConnectionParams implements CoreConnectionPNames {
      * @since 4.2
      */
     public static boolean getSoKeepalive(final HttpParams params) {
-        if (params == null) {
-            throw new IllegalArgumentException("HTTP parameters may not be null");
-        }
+        Args.notNull(params, "HTTP parameters");
         return params.getBooleanParameter(CoreConnectionPNames.SO_KEEPALIVE, false);
     }
 
@@ -265,14 +235,9 @@ public final class HttpConnectionParams implements CoreConnectionPNames {
      *
      * @since 4.2
      */
-    public static void setSoKeepalive(final HttpParams params, boolean enableKeepalive) {
-        if (params == null) {
-            throw new IllegalArgumentException("HTTP parameters may not be null");
-        }
+    public static void setSoKeepalive(final HttpParams params, final boolean enableKeepalive) {
+        Args.notNull(params, "HTTP parameters");
         params.setBooleanParameter(CoreConnectionPNames.SO_KEEPALIVE, enableKeepalive);
     }
 
-
-
-
 }
diff --git a/httpcore/src/main/java/org/apache/http/params/HttpProtocolParamBean.java b/httpcore/src/main/java-deprecated/org/apache/http/params/HttpProtocolParamBean.java
similarity index 91%
rename from httpcore/src/main/java/org/apache/http/params/HttpProtocolParamBean.java
rename to httpcore/src/main/java-deprecated/org/apache/http/params/HttpProtocolParamBean.java
index 00e0da4..5ec6463 100644
--- a/httpcore/src/main/java/org/apache/http/params/HttpProtocolParamBean.java
+++ b/httpcore/src/main/java-deprecated/org/apache/http/params/HttpProtocolParamBean.java
@@ -35,7 +35,11 @@ import org.apache.http.HttpVersion;
  * conventions.
  *
  * @since 4.0
+ *
+ * @deprecated (4.3) use configuration classes provided 'org.apache.http.config'
+ *  and 'org.apache.http.client.config'
  */
+ at Deprecated
 public class HttpProtocolParamBean extends HttpAbstractParamBean {
 
     public HttpProtocolParamBean (final HttpParams params) {
@@ -58,7 +62,7 @@ public class HttpProtocolParamBean extends HttpAbstractParamBean {
         HttpProtocolParams.setUserAgent(params, userAgent);
     }
 
-    public void setUseExpectContinue (boolean useExpectContinue) {
+    public void setUseExpectContinue (final boolean useExpectContinue) {
         HttpProtocolParams.setUseExpectContinue(params, useExpectContinue);
     }
 
diff --git a/httpcore/src/main/java/org/apache/http/params/HttpProtocolParams.java b/httpcore/src/main/java-deprecated/org/apache/http/params/HttpProtocolParams.java
similarity index 77%
rename from httpcore/src/main/java/org/apache/http/params/HttpProtocolParams.java
rename to httpcore/src/main/java-deprecated/org/apache/http/params/HttpProtocolParams.java
index 439b615..a754703 100644
--- a/httpcore/src/main/java/org/apache/http/params/HttpProtocolParams.java
+++ b/httpcore/src/main/java-deprecated/org/apache/http/params/HttpProtocolParams.java
@@ -27,19 +27,22 @@
 
 package org.apache.http.params;
 
+import java.nio.charset.CodingErrorAction;
+
 import org.apache.http.HttpVersion;
 import org.apache.http.ProtocolVersion;
 import org.apache.http.protocol.HTTP;
-
-import java.nio.charset.CodingErrorAction;
+import org.apache.http.util.Args;
 
 /**
  * Utility class for accessing protocol parameters in {@link HttpParams}.
  *
  * @since 4.0
  *
- * @see CoreProtocolPNames
+ * @deprecated (4.3) use configuration classes provided 'org.apache.http.config'
+ *  and 'org.apache.http.client.config'
  */
+ at Deprecated
 public final class HttpProtocolParams implements CoreProtocolPNames {
 
     private HttpProtocolParams() {
@@ -54,9 +57,7 @@ public final class HttpProtocolParams implements CoreProtocolPNames {
      * @return HTTP element charset.
      */
     public static String getHttpElementCharset(final HttpParams params) {
-        if (params == null) {
-            throw new IllegalArgumentException("HTTP parameters may not be null");
-        }
+        Args.notNull(params, "HTTP parameters");
         String charset = (String) params.getParameter
             (CoreProtocolPNames.HTTP_ELEMENT_CHARSET);
         if (charset == null) {
@@ -72,9 +73,7 @@ public final class HttpProtocolParams implements CoreProtocolPNames {
      * @param charset HTTP element charset.
      */
     public static void setHttpElementCharset(final HttpParams params, final String charset) {
-        if (params == null) {
-            throw new IllegalArgumentException("HTTP parameters may not be null");
-        }
+        Args.notNull(params, "HTTP parameters");
         params.setParameter(CoreProtocolPNames.HTTP_ELEMENT_CHARSET, charset);
     }
 
@@ -86,9 +85,7 @@ public final class HttpProtocolParams implements CoreProtocolPNames {
      * @return HTTP content charset.
      */
     public static String getContentCharset(final HttpParams params) {
-        if (params == null) {
-            throw new IllegalArgumentException("HTTP parameters may not be null");
-        }
+        Args.notNull(params, "HTTP parameters");
         String charset = (String) params.getParameter
             (CoreProtocolPNames.HTTP_CONTENT_CHARSET);
         if (charset == null) {
@@ -104,9 +101,7 @@ public final class HttpProtocolParams implements CoreProtocolPNames {
      * @param charset HTTP content charset.
      */
     public static void setContentCharset(final HttpParams params, final String charset) {
-        if (params == null) {
-            throw new IllegalArgumentException("HTTP parameters may not be null");
-        }
+        Args.notNull(params, "HTTP parameters");
         params.setParameter(CoreProtocolPNames.HTTP_CONTENT_CHARSET, charset);
     }
 
@@ -118,10 +113,8 @@ public final class HttpProtocolParams implements CoreProtocolPNames {
      * @return HTTP protocol version.
      */
     public static ProtocolVersion getVersion(final HttpParams params) {
-        if (params == null) {
-            throw new IllegalArgumentException("HTTP parameters may not be null");
-        }
-        Object param = params.getParameter
+        Args.notNull(params, "HTTP parameters");
+        final Object param = params.getParameter
             (CoreProtocolPNames.PROTOCOL_VERSION);
         if (param == null) {
             return HttpVersion.HTTP_1_1;
@@ -136,9 +129,7 @@ public final class HttpProtocolParams implements CoreProtocolPNames {
      * @param version HTTP protocol version.
      */
     public static void setVersion(final HttpParams params, final ProtocolVersion version) {
-        if (params == null) {
-            throw new IllegalArgumentException("HTTP parameters may not be null");
-        }
+        Args.notNull(params, "HTTP parameters");
         params.setParameter(CoreProtocolPNames.PROTOCOL_VERSION, version);
     }
 
@@ -150,9 +141,7 @@ public final class HttpProtocolParams implements CoreProtocolPNames {
      * @return User agent string.
      */
     public static String getUserAgent(final HttpParams params) {
-        if (params == null) {
-            throw new IllegalArgumentException("HTTP parameters may not be null");
-        }
+        Args.notNull(params, "HTTP parameters");
         return (String) params.getParameter(CoreProtocolPNames.USER_AGENT);
     }
 
@@ -163,9 +152,7 @@ public final class HttpProtocolParams implements CoreProtocolPNames {
      * @param useragent User agent string.
      */
     public static void setUserAgent(final HttpParams params, final String useragent) {
-        if (params == null) {
-            throw new IllegalArgumentException("HTTP parameters may not be null");
-        }
+        Args.notNull(params, "HTTP parameters");
         params.setParameter(CoreProtocolPNames.USER_AGENT, useragent);
     }
 
@@ -177,11 +164,8 @@ public final class HttpProtocolParams implements CoreProtocolPNames {
      * @return User agent string.
      */
     public static boolean useExpectContinue(final HttpParams params) {
-        if (params == null) {
-            throw new IllegalArgumentException("HTTP parameters may not be null");
-        }
-        return params.getBooleanParameter
-            (CoreProtocolPNames.USE_EXPECT_CONTINUE, false);
+        Args.notNull(params, "HTTP parameters");
+        return params.getBooleanParameter(CoreProtocolPNames.USE_EXPECT_CONTINUE, false);
     }
 
     /**
@@ -190,10 +174,8 @@ public final class HttpProtocolParams implements CoreProtocolPNames {
      * @param params HTTP parameters.
      * @param b expect-continue flag.
      */
-    public static void setUseExpectContinue(final HttpParams params, boolean b) {
-        if (params == null) {
-            throw new IllegalArgumentException("HTTP parameters may not be null");
-        }
+    public static void setUseExpectContinue(final HttpParams params, final boolean b) {
+        Args.notNull(params, "HTTP parameters");
         params.setBooleanParameter(CoreProtocolPNames.USE_EXPECT_CONTINUE, b);
     }
 
@@ -205,10 +187,8 @@ public final class HttpProtocolParams implements CoreProtocolPNames {
      * @since 4.2
      */
     public static CodingErrorAction getMalformedInputAction(final HttpParams params) {
-        if (params == null) {
-            throw new IllegalArgumentException("HTTP parameters may not be null");
-        }
-        Object param = params.getParameter(CoreProtocolPNames.HTTP_MALFORMED_INPUT_ACTION);
+        Args.notNull(params, "HTTP parameters");
+        final Object param = params.getParameter(CoreProtocolPNames.HTTP_MALFORMED_INPUT_ACTION);
         if (param == null) {
             // the default CodingErrorAction
             return CodingErrorAction.REPORT;
@@ -223,10 +203,8 @@ public final class HttpProtocolParams implements CoreProtocolPNames {
      *
      * @since 4.2
      */
-    public static void setMalformedInputAction(final HttpParams params, CodingErrorAction action) {
-        if (params == null) {
-            throw new IllegalArgumentException("HTTP parameters may not be null");
-        }
+    public static void setMalformedInputAction(final HttpParams params, final CodingErrorAction action) {
+        Args.notNull(params, "HTTP parameters");
         params.setParameter(CoreProtocolPNames.HTTP_MALFORMED_INPUT_ACTION, action);
     }
 
@@ -238,10 +216,8 @@ public final class HttpProtocolParams implements CoreProtocolPNames {
      * @since 4.2
      */
     public static CodingErrorAction getUnmappableInputAction(final HttpParams params) {
-        if (params == null) {
-            throw new IllegalArgumentException("HTTP parameters may not be null");
-        }
-        Object param = params.getParameter(CoreProtocolPNames.HTTP_UNMAPPABLE_INPUT_ACTION);
+        Args.notNull(params, "HTTP parameters");
+        final Object param = params.getParameter(CoreProtocolPNames.HTTP_UNMAPPABLE_INPUT_ACTION);
         if (param == null) {
             // the default CodingErrorAction
             return CodingErrorAction.REPORT;
@@ -256,10 +232,9 @@ public final class HttpProtocolParams implements CoreProtocolPNames {
      *
      * @since 4.2
      */
-    public static void setUnmappableInputAction(final HttpParams params, CodingErrorAction action) {
-        if (params == null) {
-            throw new IllegalArgumentException("HTTP parameters may no be null");
-        }
+    public static void setUnmappableInputAction(final HttpParams params, final CodingErrorAction action) {
+        Args.notNull(params, "HTTP parameters");
         params.setParameter(CoreProtocolPNames.HTTP_UNMAPPABLE_INPUT_ACTION, action);
     }
+
 }
diff --git a/httpcore/src/main/java/org/apache/http/params/SyncBasicHttpParams.java b/httpcore/src/main/java-deprecated/org/apache/http/params/SyncBasicHttpParams.java
similarity index 94%
rename from httpcore/src/main/java/org/apache/http/params/SyncBasicHttpParams.java
rename to httpcore/src/main/java-deprecated/org/apache/http/params/SyncBasicHttpParams.java
index 931ef9c..ab9cdfb 100644
--- a/httpcore/src/main/java/org/apache/http/params/SyncBasicHttpParams.java
+++ b/httpcore/src/main/java-deprecated/org/apache/http/params/SyncBasicHttpParams.java
@@ -22,8 +22,8 @@
  * individuals on behalf of the Apache Software Foundation.  For more
  * information on the Apache Software Foundation, please see
  * <http://www.apache.org/>.
+ *
  */
-
 package org.apache.http.params;
 
 import org.apache.http.annotation.ThreadSafe;
@@ -32,8 +32,12 @@ import org.apache.http.annotation.ThreadSafe;
  * Thread-safe extension of the {@link BasicHttpParams}.
  *
  * @since 4.1
+ *
+ * @deprecated (4.3) use configuration classes provided 'org.apache.http.config'
+ *  and 'org.apache.http.client.config'
  */
 @ThreadSafe
+ at Deprecated
 public class SyncBasicHttpParams extends BasicHttpParams {
 
     private static final long serialVersionUID = 5387834869062660642L;
diff --git a/httpcore/src/main/java/org/apache/http/protocol/BasicHttpProcessor.java b/httpcore/src/main/java-deprecated/org/apache/http/protocol/BasicHttpProcessor.java
similarity index 83%
rename from httpcore/src/main/java/org/apache/http/protocol/BasicHttpProcessor.java
rename to httpcore/src/main/java-deprecated/org/apache/http/protocol/BasicHttpProcessor.java
index 6dd2e93..4fe64b1 100644
--- a/httpcore/src/main/java/org/apache/http/protocol/BasicHttpProcessor.java
+++ b/httpcore/src/main/java-deprecated/org/apache/http/protocol/BasicHttpProcessor.java
@@ -38,6 +38,7 @@ import org.apache.http.HttpRequestInterceptor;
 import org.apache.http.HttpResponse;
 import org.apache.http.HttpResponseInterceptor;
 import org.apache.http.annotation.NotThreadSafe;
+import org.apache.http.util.Args;
 
 /**
  * Default implementation of {@link HttpProcessor}.
@@ -46,8 +47,11 @@ import org.apache.http.annotation.NotThreadSafe;
  * synchronized and therefore this class may be thread-unsafe.
  *
  * @since 4.0
+ *
+ * @deprecated (4.3)
  */
 @NotThreadSafe
+ at Deprecated
 public final class BasicHttpProcessor implements
     HttpProcessor, HttpRequestInterceptorList, HttpResponseInterceptorList, Cloneable {
 
@@ -63,7 +67,7 @@ public final class BasicHttpProcessor implements
     }
 
     public void addRequestInterceptor(
-            final HttpRequestInterceptor itcp, int index) {
+            final HttpRequestInterceptor itcp, final int index) {
         if (itcp == null) {
             return;
         }
@@ -71,7 +75,7 @@ public final class BasicHttpProcessor implements
     }
 
     public void addResponseInterceptor(
-            final HttpResponseInterceptor itcp, int index) {
+            final HttpResponseInterceptor itcp, final int index) {
         if (itcp == null) {
             return;
         }
@@ -79,9 +83,9 @@ public final class BasicHttpProcessor implements
     }
 
     public void removeRequestInterceptorByClass(final Class<? extends HttpRequestInterceptor> clazz) {
-        for (Iterator<HttpRequestInterceptor> it = this.requestInterceptors.iterator();
+        for (final Iterator<HttpRequestInterceptor> it = this.requestInterceptors.iterator();
              it.hasNext(); ) {
-            Object request = it.next();
+            final Object request = it.next();
             if (request.getClass().equals(clazz)) {
                 it.remove();
             }
@@ -89,9 +93,9 @@ public final class BasicHttpProcessor implements
     }
 
     public void removeResponseInterceptorByClass(final Class<? extends HttpResponseInterceptor> clazz) {
-        for (Iterator<HttpResponseInterceptor> it = this.responseInterceptors.iterator();
+        for (final Iterator<HttpResponseInterceptor> it = this.responseInterceptors.iterator();
              it.hasNext(); ) {
-            Object request = it.next();
+            final Object request = it.next();
             if (request.getClass().equals(clazz)) {
                 it.remove();
             }
@@ -102,7 +106,7 @@ public final class BasicHttpProcessor implements
         addRequestInterceptor(interceptor);
     }
 
-     public final void addInterceptor(final HttpRequestInterceptor interceptor, int index) {
+     public final void addInterceptor(final HttpRequestInterceptor interceptor, final int index) {
         addRequestInterceptor(interceptor, index);
     }
 
@@ -110,9 +114,10 @@ public final class BasicHttpProcessor implements
         return this.requestInterceptors.size();
     }
 
-    public HttpRequestInterceptor getRequestInterceptor(int index) {
-        if ((index < 0) || (index >= this.requestInterceptors.size()))
+    public HttpRequestInterceptor getRequestInterceptor(final int index) {
+        if ((index < 0) || (index >= this.requestInterceptors.size())) {
             return null;
+        }
         return this.requestInterceptors.get(index);
     }
 
@@ -131,7 +136,7 @@ public final class BasicHttpProcessor implements
         addResponseInterceptor(interceptor);
     }
 
-    public final void addInterceptor(final HttpResponseInterceptor interceptor, int index) {
+    public final void addInterceptor(final HttpResponseInterceptor interceptor, final int index) {
         addResponseInterceptor(interceptor, index);
     }
 
@@ -139,9 +144,10 @@ public final class BasicHttpProcessor implements
         return this.responseInterceptors.size();
     }
 
-    public HttpResponseInterceptor getResponseInterceptor(int index) {
-        if ((index < 0) || (index >= this.responseInterceptors.size()))
+    public HttpResponseInterceptor getResponseInterceptor(final int index) {
+        if ((index < 0) || (index >= this.responseInterceptors.size())) {
             return null;
+        }
         return this.responseInterceptors.get(index);
     }
 
@@ -167,18 +173,15 @@ public final class BasicHttpProcessor implements
      *                  from which to initialize
      */
     public void setInterceptors(final List<?> list) {
-        if (list == null) {
-            throw new IllegalArgumentException("List must not be null.");
-        }
+        Args.notNull(list, "Inteceptor list");
         this.requestInterceptors.clear();
         this.responseInterceptors.clear();
-        for (int i = 0; i < list.size(); i++) {
-            Object obj = list.get(i);
+        for (final Object obj : list) {
             if (obj instanceof HttpRequestInterceptor) {
-                addInterceptor((HttpRequestInterceptor)obj);
+                addInterceptor((HttpRequestInterceptor) obj);
             }
             if (obj instanceof HttpResponseInterceptor) {
-                addInterceptor((HttpResponseInterceptor)obj);
+                addInterceptor((HttpResponseInterceptor) obj);
             }
         }
     }
@@ -195,9 +198,7 @@ public final class BasicHttpProcessor implements
             final HttpRequest request,
             final HttpContext context)
             throws IOException, HttpException {
-        for (int i = 0; i < this.requestInterceptors.size(); i++) {
-            HttpRequestInterceptor interceptor =
-                this.requestInterceptors.get(i);
+        for (final HttpRequestInterceptor interceptor : this.requestInterceptors) {
             interceptor.process(request, context);
         }
     }
@@ -206,9 +207,7 @@ public final class BasicHttpProcessor implements
             final HttpResponse response,
             final HttpContext context)
             throws IOException, HttpException {
-        for (int i = 0; i < this.responseInterceptors.size(); i++) {
-            HttpResponseInterceptor interceptor =
-                this.responseInterceptors.get(i);
+        for (final HttpResponseInterceptor interceptor : this.responseInterceptors) {
             interceptor.process(response, context);
         }
     }
@@ -232,14 +231,14 @@ public final class BasicHttpProcessor implements
      * @return new instance of the BasicHttpProcessor
      */
     public BasicHttpProcessor copy() {
-        BasicHttpProcessor clone = new BasicHttpProcessor();
+        final BasicHttpProcessor clone = new BasicHttpProcessor();
         copyInterceptors(clone);
         return clone;
     }
 
     @Override
     public Object clone() throws CloneNotSupportedException {
-        BasicHttpProcessor clone = (BasicHttpProcessor) super.clone();
+        final BasicHttpProcessor clone = (BasicHttpProcessor) super.clone();
         copyInterceptors(clone);
         return clone;
     }
diff --git a/httpcore/src/main/java/org/apache/http/protocol/DefaultedHttpContext.java b/httpcore/src/main/java-deprecated/org/apache/http/protocol/DefaultedHttpContext.java
similarity index 89%
rename from httpcore/src/main/java/org/apache/http/protocol/DefaultedHttpContext.java
rename to httpcore/src/main/java-deprecated/org/apache/http/protocol/DefaultedHttpContext.java
index a9958d8..abcf7f0 100644
--- a/httpcore/src/main/java/org/apache/http/protocol/DefaultedHttpContext.java
+++ b/httpcore/src/main/java-deprecated/org/apache/http/protocol/DefaultedHttpContext.java
@@ -27,7 +27,7 @@
 
 package org.apache.http.protocol;
 
-import org.apache.http.annotation.NotThreadSafe;
+import org.apache.http.util.Args;
 
 /**
  * {@link HttpContext} implementation that delegates resolution of an attribute
@@ -36,8 +36,10 @@ import org.apache.http.annotation.NotThreadSafe;
  * whereas the default context is treated as read-only.
  *
  * @since 4.0
+ *
+ * @deprecated (4.3) no longer used.
  */
- at NotThreadSafe
+ at Deprecated
 public final class DefaultedHttpContext implements HttpContext {
 
     private final HttpContext local;
@@ -45,15 +47,12 @@ public final class DefaultedHttpContext implements HttpContext {
 
     public DefaultedHttpContext(final HttpContext local, final HttpContext defaults) {
         super();
-        if (local == null) {
-            throw new IllegalArgumentException("HTTP context may not be null");
-        }
-        this.local = local;
+        this.local = Args.notNull(local, "HTTP context");
         this.defaults = defaults;
     }
 
     public Object getAttribute(final String id) {
-        Object obj = this.local.getAttribute(id);
+        final Object obj = this.local.getAttribute(id);
         if (obj == null) {
             return this.defaults.getAttribute(id);
         } else {
@@ -75,7 +74,7 @@ public final class DefaultedHttpContext implements HttpContext {
 
     @Override
     public String toString() {
-        StringBuilder buf = new StringBuilder();
+        final StringBuilder buf = new StringBuilder();
         buf.append("[local: ").append(this.local);
         buf.append("defaults: ").append(this.defaults);
         buf.append("]");
diff --git a/httpcore/src/main/java/org/apache/http/protocol/ExecutionContext.java b/httpcore/src/main/java-deprecated/org/apache/http/protocol/ExecutionContext.java
similarity index 95%
rename from httpcore/src/main/java/org/apache/http/protocol/ExecutionContext.java
rename to httpcore/src/main/java-deprecated/org/apache/http/protocol/ExecutionContext.java
index 649c815..f95950f 100644
--- a/httpcore/src/main/java/org/apache/http/protocol/ExecutionContext.java
+++ b/httpcore/src/main/java-deprecated/org/apache/http/protocol/ExecutionContext.java
@@ -31,7 +31,10 @@ package org.apache.http.protocol;
  * {@link HttpContext} attribute names for protocol execution.
  *
  * @since 4.0
+ *
+ * @deprecated (4.3) use {@link HttpCoreContext}.
  */
+ at Deprecated
 public interface ExecutionContext {
 
     /**
@@ -61,7 +64,10 @@ public interface ExecutionContext {
     /**
      * Attribute name of a {@link org.apache.http.HttpHost} object that
      * represents the connection proxy.
+     *
+     * @deprecated (4.3) do not use.
      */
+    @Deprecated
     public static final String HTTP_PROXY_HOST  = "http.proxy_host";
 
     /**
diff --git a/httpcore/src/main/java/org/apache/http/protocol/HttpRequestHandlerRegistry.java b/httpcore/src/main/java-deprecated/org/apache/http/protocol/HttpRequestHandlerRegistry.java
similarity index 92%
copy from httpcore/src/main/java/org/apache/http/protocol/HttpRequestHandlerRegistry.java
copy to httpcore/src/main/java-deprecated/org/apache/http/protocol/HttpRequestHandlerRegistry.java
index 737317b..0d89840 100644
--- a/httpcore/src/main/java/org/apache/http/protocol/HttpRequestHandlerRegistry.java
+++ b/httpcore/src/main/java-deprecated/org/apache/http/protocol/HttpRequestHandlerRegistry.java
@@ -30,6 +30,7 @@ package org.apache.http.protocol;
 import java.util.Map;
 
 import org.apache.http.annotation.ThreadSafe;
+import org.apache.http.util.Args;
 
 /**
  * Maintains a map of HTTP request handlers keyed by a request URI pattern.
@@ -47,8 +48,10 @@ import org.apache.http.annotation.ThreadSafe;
  * specified request URI.
  *
  * @since 4.0
+ * @deprecated (4.3) use {@link UriHttpRequestHandlerMapper}
  */
 @ThreadSafe // provided injected dependencies are thread-safe
+ at Deprecated
 public class HttpRequestHandlerRegistry implements HttpRequestHandlerResolver {
 
     private final UriPatternMatcher<HttpRequestHandler> matcher;
@@ -65,12 +68,8 @@ public class HttpRequestHandlerRegistry implements HttpRequestHandlerResolver {
      * @param handler the handler.
      */
     public void register(final String pattern, final HttpRequestHandler handler) {
-        if (pattern == null) {
-            throw new IllegalArgumentException("URI request pattern may not be null");
-        }
-        if (handler == null) {
-            throw new IllegalArgumentException("Request handler may not be null");
-        }
+        Args.notNull(pattern, "URI request pattern");
+        Args.notNull(handler, "Request handler");
         matcher.register(pattern, handler);
     }
 
diff --git a/httpcore/src/main/java/org/apache/http/protocol/SyncBasicHttpContext.java b/httpcore/src/main/java-deprecated/org/apache/http/protocol/SyncBasicHttpContext.java
similarity index 99%
rename from httpcore/src/main/java/org/apache/http/protocol/SyncBasicHttpContext.java
rename to httpcore/src/main/java-deprecated/org/apache/http/protocol/SyncBasicHttpContext.java
index 1e2176c..bc4a21a 100644
--- a/httpcore/src/main/java/org/apache/http/protocol/SyncBasicHttpContext.java
+++ b/httpcore/src/main/java-deprecated/org/apache/http/protocol/SyncBasicHttpContext.java
@@ -31,7 +31,7 @@ package org.apache.http.protocol;
  * Thread-safe extension of the {@link BasicHttpContext}.
  *
  * @since 4.0
- * 
+ *
  * @deprecated (4.2) HttpContext instances may not be shared by multiple threads
  */
 @Deprecated
diff --git a/httpcore/src/main/java/org/apache/http/util/ExceptionUtils.java b/httpcore/src/main/java-deprecated/org/apache/http/util/ExceptionUtils.java
similarity index 89%
rename from httpcore/src/main/java/org/apache/http/util/ExceptionUtils.java
rename to httpcore/src/main/java-deprecated/org/apache/http/util/ExceptionUtils.java
index 5baecf7..ba44489 100644
--- a/httpcore/src/main/java/org/apache/http/util/ExceptionUtils.java
+++ b/httpcore/src/main/java-deprecated/org/apache/http/util/ExceptionUtils.java
@@ -53,9 +53,9 @@ public final class ExceptionUtils {
      */
     static private Method getInitCauseMethod() {
         try {
-            Class<?>[] paramsClasses = new Class[] { Throwable.class };
+            final Class<?>[] paramsClasses = new Class[] { Throwable.class };
             return Throwable.class.getMethod("initCause", paramsClasses);
-        } catch (NoSuchMethodException e) {
+        } catch (final NoSuchMethodException e) {
             return null;
         }
     }
@@ -66,11 +66,11 @@ public final class ExceptionUtils {
      * @param  throwable The throwable.
      * @param  cause     The cause of the throwable.
      */
-    public static void initCause(Throwable throwable, Throwable cause) {
+    public static void initCause(final Throwable throwable, final Throwable cause) {
         if (INIT_CAUSE_METHOD != null) {
             try {
-                INIT_CAUSE_METHOD.invoke(throwable, new Object[] { cause });
-            } catch (Exception e) {
+                INIT_CAUSE_METHOD.invoke(throwable, cause);
+            } catch (final Exception e) {
                 // Well, with no logging, the only option is to munch the exception
             }
         }
diff --git a/httpcore/src/main/java/org/apache/http/ContentTooLongException.java b/httpcore/src/main/java/org/apache/http/ContentTooLongException.java
index fce2cda..f7020ac 100644
--- a/httpcore/src/main/java/org/apache/http/ContentTooLongException.java
+++ b/httpcore/src/main/java/org/apache/http/ContentTooLongException.java
@@ -43,7 +43,7 @@ public class ContentTooLongException extends IOException {
      *
      * @param message exception message
      */
-    public ContentTooLongException(String message) {
+    public ContentTooLongException(final String message) {
         super(message);
     }
 
diff --git a/httpcore/src/main/java/org/apache/http/HeaderElement.java b/httpcore/src/main/java/org/apache/http/HeaderElement.java
index 4ce2627..022f44b 100644
--- a/httpcore/src/main/java/org/apache/http/HeaderElement.java
+++ b/httpcore/src/main/java/org/apache/http/HeaderElement.java
@@ -99,7 +99,7 @@ public interface HeaderElement {
     /**
      * Returns parameter with the given index.
      *
-     * @param index
+     * @param index index
      * @return name / value pair
      */
     NameValuePair getParameter(int index);
diff --git a/httpcore/src/main/java/org/apache/http/io/EofSensor.java b/httpcore/src/main/java/org/apache/http/HttpConnectionFactory.java
similarity index 81%
copy from httpcore/src/main/java/org/apache/http/io/EofSensor.java
copy to httpcore/src/main/java/org/apache/http/HttpConnectionFactory.java
index b1ec82e..a8a0749 100644
--- a/httpcore/src/main/java/org/apache/http/io/EofSensor.java
+++ b/httpcore/src/main/java/org/apache/http/HttpConnectionFactory.java
@@ -25,15 +25,18 @@
  *
  */
 
-package org.apache.http.io;
+package org.apache.http;
+
+import java.io.IOException;
+import java.net.Socket;
 
 /**
- * EOF sensor.
+ * Factory for {@link HttpConnection} instances.
  *
- * @since 4.0
+ * @since 4.3
  */
-public interface EofSensor {
+public interface HttpConnectionFactory<T extends HttpConnection> {
 
-    boolean isEof();
+    T createConnection(Socket socket) throws IOException;
 
 }
diff --git a/httpcore/src/main/java/org/apache/http/HttpEntityEnclosingRequest.java b/httpcore/src/main/java/org/apache/http/HttpEntityEnclosingRequest.java
index 3237124..c03b3aa 100644
--- a/httpcore/src/main/java/org/apache/http/HttpEntityEnclosingRequest.java
+++ b/httpcore/src/main/java/org/apache/http/HttpEntityEnclosingRequest.java
@@ -1,5 +1,4 @@
 /*
- * $Header: $
  * ====================================================================
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements.  See the NOTICE file
@@ -25,7 +24,6 @@
  * <http://www.apache.org/>.
  *
  */
-
 package org.apache.http;
 
 /**
diff --git a/httpcore/src/main/java/org/apache/http/HttpHost.java b/httpcore/src/main/java/org/apache/http/HttpHost.java
index 9fc1cc4..fa0b535 100644
--- a/httpcore/src/main/java/org/apache/http/HttpHost.java
+++ b/httpcore/src/main/java/org/apache/http/HttpHost.java
@@ -28,9 +28,11 @@
 package org.apache.http;
 
 import java.io.Serializable;
+import java.net.InetAddress;
 import java.util.Locale;
 
 import org.apache.http.annotation.Immutable;
+import org.apache.http.util.Args;
 import org.apache.http.util.LangUtils;
 
 /**
@@ -61,6 +63,7 @@ public final class HttpHost implements Cloneable, Serializable {
     /** The scheme (lowercased) */
     protected final String schemeName;
 
+    protected final InetAddress address;
 
     /**
      * Creates a new {@link HttpHost HttpHost}, specifying all values.
@@ -73,12 +76,9 @@ public final class HttpHost implements Cloneable, Serializable {
      *                  <code>null</code> indicates the
      *                  {@link #DEFAULT_SCHEME_NAME default scheme}
      */
-    public HttpHost(final String hostname, int port, final String scheme) {
+    public HttpHost(final String hostname, final int port, final String scheme) {
         super();
-        if (hostname == null) {
-            throw new IllegalArgumentException("Host name may not be null");
-        }
-        this.hostname   = hostname;
+        this.hostname   = Args.notNull(hostname, "Host name");
         this.lcHostname = hostname.toLowerCase(Locale.ENGLISH);
         if (scheme != null) {
             this.schemeName = scheme.toLowerCase(Locale.ENGLISH);
@@ -86,6 +86,7 @@ public final class HttpHost implements Cloneable, Serializable {
             this.schemeName = DEFAULT_SCHEME_NAME;
         }
         this.port = port;
+        this.address = null;
     }
 
     /**
@@ -95,7 +96,7 @@ public final class HttpHost implements Cloneable, Serializable {
      * @param port      the port number.
      *                  <code>-1</code> indicates the scheme default port.
      */
-    public HttpHost(final String hostname, int port) {
+    public HttpHost(final String hostname, final int port) {
         this(hostname, port, null);
     }
 
@@ -109,12 +110,68 @@ public final class HttpHost implements Cloneable, Serializable {
     }
 
     /**
+     * Creates a new {@link HttpHost HttpHost}, specifying all values.
+     * Constructor for HttpHost.
+     *
+     * @param address   the inet address.
+     * @param port      the port number.
+     *                  <code>-1</code> indicates the scheme default port.
+     * @param scheme    the name of the scheme.
+     *                  <code>null</code> indicates the
+     *                  {@link #DEFAULT_SCHEME_NAME default scheme}
+     *
+     * @since 4.3
+     */
+    public HttpHost(final InetAddress address, final int port, final String scheme) {
+        super();
+        this.address = Args.notNull(address, "Inet address");
+        this.hostname = address.getHostAddress();
+        this.lcHostname = this.hostname.toLowerCase(Locale.ENGLISH);
+        if (scheme != null) {
+            this.schemeName = scheme.toLowerCase(Locale.ENGLISH);
+        } else {
+            this.schemeName = DEFAULT_SCHEME_NAME;
+        }
+        this.port = port;
+    }
+
+    /**
+     * Creates a new {@link HttpHost HttpHost}, with default scheme.
+     *
+     * @param address   the inet address.
+     * @param port      the port number.
+     *                  <code>-1</code> indicates the scheme default port.
+     *
+     * @since 4.3
+     */
+    public HttpHost(final InetAddress address, final int port) {
+        this(address, port, null);
+    }
+
+    /**
+     * Creates a new {@link HttpHost HttpHost}, with default scheme and port.
+     *
+     * @param address   the inet address.
+     *
+     * @since 4.3
+     */
+    public HttpHost(final InetAddress address) {
+        this(address, -1, null);
+    }
+
+    /**
      * Copy constructor for {@link HttpHost HttpHost}.
      *
      * @param httphost the HTTP host to copy details from
      */
     public HttpHost (final HttpHost httphost) {
-        this(httphost.hostname, httphost.port, httphost.schemeName);
+        super();
+        Args.notNull(httphost, "HTTP host");
+        this.hostname   = httphost.hostname;
+        this.lcHostname = httphost.lcHostname;
+        this.schemeName = httphost.schemeName;
+        this.port = httphost.port;
+        this.address = httphost.address;
     }
 
     /**
@@ -145,12 +202,23 @@ public final class HttpHost implements Cloneable, Serializable {
     }
 
     /**
+     * Returns the inet address if explicitly set by a constructor,
+     *   <code>null</code> otherwise.
+     * @return the inet address
+     *
+     * @since 4.3
+     */
+    public InetAddress getAddress() {
+        return this.address;
+    }
+
+    /**
      * Return the host URI, as a string.
      *
      * @return the host URI
      */
     public String toURI() {
-        StringBuilder buffer = new StringBuilder();
+        final StringBuilder buffer = new StringBuilder();
         buffer.append(this.schemeName);
         buffer.append("://");
         buffer.append(this.hostname);
@@ -170,7 +238,7 @@ public final class HttpHost implements Cloneable, Serializable {
     public String toHostString() {
         if (this.port != -1) {
             //the highest port number is 65535, which is length 6 with the addition of the colon
-            StringBuilder buffer = new StringBuilder(this.hostname.length() + 6);
+            final StringBuilder buffer = new StringBuilder(this.hostname.length() + 6);
             buffer.append(this.hostname);
             buffer.append(":");
             buffer.append(Integer.toString(this.port));
@@ -189,9 +257,11 @@ public final class HttpHost implements Cloneable, Serializable {
 
     @Override
     public boolean equals(final Object obj) {
-        if (this == obj) return true;
+        if (this == obj) {
+            return true;
+        }
         if (obj instanceof HttpHost) {
-            HttpHost that = (HttpHost) obj;
+            final HttpHost that = (HttpHost) obj;
             return this.lcHostname.equals(that.lcHostname)
                 && this.port == that.port
                 && this.schemeName.equals(that.schemeName);
diff --git a/httpcore/src/main/java/org/apache/http/HttpMessage.java b/httpcore/src/main/java/org/apache/http/HttpMessage.java
index 08c9e28..ebc54be 100644
--- a/httpcore/src/main/java/org/apache/http/HttpMessage.java
+++ b/httpcore/src/main/java/org/apache/http/HttpMessage.java
@@ -53,6 +53,7 @@ import org.apache.http.params.HttpParams;
  *
  * @since 4.0
  */
+ at SuppressWarnings("deprecation")
 public interface HttpMessage {
 
     /**
@@ -189,13 +190,21 @@ public interface HttpMessage {
     /**
      * Returns the parameters effective for this message as set by
      * {@link #setParams(HttpParams)}.
+     *
+     * @deprecated (4.3) use configuration classes provided 'org.apache.http.config'
+     *  and 'org.apache.http.client.config'
      */
+    @Deprecated
     HttpParams getParams();
 
     /**
      * Provides parameters to be used for the processing of this message.
      * @param params the parameters
+     *
+     * @deprecated (4.3) use configuration classes provided 'org.apache.http.config'
+     *  and 'org.apache.http.client.config'
      */
+    @Deprecated
     void setParams(HttpParams params);
 
 }
diff --git a/httpcore/src/main/java/org/apache/http/HttpResponse.java b/httpcore/src/main/java/org/apache/http/HttpResponse.java
index fed42d9..ccbdc4d 100644
--- a/httpcore/src/main/java/org/apache/http/HttpResponse.java
+++ b/httpcore/src/main/java/org/apache/http/HttpResponse.java
@@ -131,14 +131,15 @@ public interface HttpResponse extends HttpMessage {
     /**
      * Associates a response entity with this response.
      * <p/>
-     * Please note that if an entity has already been set for this response and it depends on 
-     * an input stream ({@link HttpEntity#isStreaming()} returns <code>true</code>), 
+     * Please note that if an entity has already been set for this response and it depends on
+     * an input stream ({@link HttpEntity#isStreaming()} returns <code>true</code>),
      * it must be fully consumed in order to ensure release of resources.
      *
      * @param entity    the entity to associate with this response, or
      *                  <code>null</code> to unset
-     *                  
+     *
      * @see HttpEntity#isStreaming()
+     * @see org.apache.http.util.EntityUtils#updateEntity(HttpResponse, HttpEntity)
      */
     void setEntity(HttpEntity entity);
 
@@ -149,7 +150,10 @@ public interface HttpResponse extends HttpMessage {
      * It can be changed using {@link #setLocale setLocale}.
      *
      * @return  the locale of this response, never <code>null</code>
+     *
+     * @deprecated (4.3) use {@link org.apache.http.impl.DefaultHttpRequestFactory}
      */
+    @Deprecated
     Locale getLocale();
 
     /**
@@ -159,8 +163,9 @@ public interface HttpResponse extends HttpMessage {
      *
      * @param loc       the new locale
      *
-     * @see #getLocale getLocale
-     * @see #setStatusCode setStatusCode
+     * @deprecated (4.3) use {@link org.apache.http.impl.DefaultHttpRequestFactory}
      */
+    @Deprecated
     void setLocale(Locale loc);
+
 }
diff --git a/httpcore/src/main/java/org/apache/http/HttpVersion.java b/httpcore/src/main/java/org/apache/http/HttpVersion.java
index 02ab0d9..1a983d0 100644
--- a/httpcore/src/main/java/org/apache/http/HttpVersion.java
+++ b/httpcore/src/main/java/org/apache/http/HttpVersion.java
@@ -71,7 +71,7 @@ public final class HttpVersion extends ProtocolVersion
      *
      * @throws IllegalArgumentException if either major or minor version number is negative
      */
-    public HttpVersion(int major, int minor) {
+    public HttpVersion(final int major, final int minor) {
         super(HTTP, major, minor);
     }
 
@@ -85,7 +85,7 @@ public final class HttpVersion extends ProtocolVersion
      * @return  an instance of {@link HttpVersion} with the argument version
      */
     @Override
-    public ProtocolVersion forVersion(int major, int minor) {
+    public ProtocolVersion forVersion(final int major, final int minor) {
 
         if ((major == this.major) && (minor == this.minor)) {
             return this;
diff --git a/httpcore/src/main/java/org/apache/http/ContentTooLongException.java b/httpcore/src/main/java/org/apache/http/MessageConstraintException.java
similarity index 77%
copy from httpcore/src/main/java/org/apache/http/ContentTooLongException.java
copy to httpcore/src/main/java/org/apache/http/MessageConstraintException.java
index fce2cda..2e09ee1 100644
--- a/httpcore/src/main/java/org/apache/http/ContentTooLongException.java
+++ b/httpcore/src/main/java/org/apache/http/MessageConstraintException.java
@@ -30,20 +30,20 @@ package org.apache.http;
 import java.io.IOException;
 
 /**
- * Signals that HTTP entity content is too long.
+ * Signals a message constraint violation.
  *
- * @since 4.2
+ * @since 4.3
  */
-public class ContentTooLongException extends IOException {
+public class MessageConstraintException extends IOException {
 
-    private static final long serialVersionUID = -924287689552495383L;
+    private static final long serialVersionUID = 6077207720446368695L;
 
     /**
-     * Creates a new ContentTooLongException with the specified detail message.
+     * Creates a TruncatedChunkException with the specified detail message.
      *
-     * @param message exception message
+     * @param message The exception detail message
      */
-    public ContentTooLongException(String message) {
+    public MessageConstraintException(final String message) {
         super(message);
     }
 
diff --git a/httpcore/src/main/java/org/apache/http/NoHttpResponseException.java b/httpcore/src/main/java/org/apache/http/NoHttpResponseException.java
index ffe35c1..ac17c48 100644
--- a/httpcore/src/main/java/org/apache/http/NoHttpResponseException.java
+++ b/httpcore/src/main/java/org/apache/http/NoHttpResponseException.java
@@ -43,7 +43,7 @@ public class NoHttpResponseException extends IOException {
      *
      * @param message exception message
      */
-    public NoHttpResponseException(String message) {
+    public NoHttpResponseException(final String message) {
         super(message);
     }
 
diff --git a/httpcore/src/main/java/org/apache/http/ParseException.java b/httpcore/src/main/java/org/apache/http/ParseException.java
index f7291c9..2b3a046 100644
--- a/httpcore/src/main/java/org/apache/http/ParseException.java
+++ b/httpcore/src/main/java/org/apache/http/ParseException.java
@@ -54,7 +54,7 @@ public class ParseException extends RuntimeException {
      *
      * @param message the exception detail message, or <code>null</code>
      */
-    public ParseException(String message) {
+    public ParseException(final String message) {
         super(message);
     }
 
diff --git a/httpcore/src/main/java/org/apache/http/ProtocolException.java b/httpcore/src/main/java/org/apache/http/ProtocolException.java
index ae42eda..6428d40 100644
--- a/httpcore/src/main/java/org/apache/http/ProtocolException.java
+++ b/httpcore/src/main/java/org/apache/http/ProtocolException.java
@@ -50,7 +50,7 @@ public class ProtocolException extends HttpException {
      *
      * @param message The exception detail message
      */
-    public ProtocolException(String message) {
+    public ProtocolException(final String message) {
         super(message);
     }
 
@@ -61,7 +61,7 @@ public class ProtocolException extends HttpException {
      * @param cause the <tt>Throwable</tt> that caused this exception, or <tt>null</tt>
      * if the cause is unavailable, unknown, or not a <tt>Throwable</tt>
      */
-    public ProtocolException(String message, Throwable cause) {
+    public ProtocolException(final String message, final Throwable cause) {
         super(message, cause);
     }
 }
diff --git a/httpcore/src/main/java/org/apache/http/ProtocolVersion.java b/httpcore/src/main/java/org/apache/http/ProtocolVersion.java
index 6e03ff7..1581f19 100644
--- a/httpcore/src/main/java/org/apache/http/ProtocolVersion.java
+++ b/httpcore/src/main/java/org/apache/http/ProtocolVersion.java
@@ -30,6 +30,7 @@ package org.apache.http;
 import java.io.Serializable;
 
 import org.apache.http.annotation.Immutable;
+import org.apache.http.util.Args;
 
 /**
  * Represents a protocol version. The "major.minor" numbering
@@ -66,22 +67,10 @@ public class ProtocolVersion implements Serializable, Cloneable {
      * @param major      the major version number of the protocol
      * @param minor      the minor version number of the protocol
      */
-    public ProtocolVersion(String protocol, int major, int minor) {
-        if (protocol == null) {
-            throw new IllegalArgumentException
-                ("Protocol name must not be null.");
-        }
-        if (major < 0) {
-            throw new IllegalArgumentException
-                ("Protocol major version number must not be negative.");
-        }
-        if (minor < 0) {
-            throw new IllegalArgumentException
-                ("Protocol minor version number may not be negative");
-        }
-        this.protocol = protocol;
-        this.major = major;
-        this.minor = minor;
+    public ProtocolVersion(final String protocol, final int major, final int minor) {
+        this.protocol = Args.notNull(protocol, "Protocol name");
+        this.major = Args.notNegative(major, "Protocol minor version");
+        this.minor = Args.notNegative(minor, "Protocol minor version");
     }
 
     /**
@@ -127,7 +116,7 @@ public class ProtocolVersion implements Serializable, Cloneable {
      * @return  a protocol version with the same protocol name
      *          and the argument version
      */
-    public ProtocolVersion forVersion(int major, int minor) {
+    public ProtocolVersion forVersion(final int major, final int minor) {
 
         if ((major == this.major) && (minor == this.minor)) {
             return this;
@@ -163,14 +152,14 @@ public class ProtocolVersion implements Serializable, Cloneable {
      *          <code>false</code> otherwise
      */
     @Override
-    public final boolean equals(Object obj) {
+    public final boolean equals(final Object obj) {
         if (this == obj) {
             return true;
         }
         if (!(obj instanceof ProtocolVersion)) {
             return false;
         }
-        ProtocolVersion that = (ProtocolVersion) obj;
+        final ProtocolVersion that = (ProtocolVersion) obj;
 
         return ((this.protocol.equals(that.protocol)) &&
                 (this.major == that.major) &&
@@ -188,7 +177,7 @@ public class ProtocolVersion implements Serializable, Cloneable {
      * @return  <code>true</code> if {@link #compareToVersion compareToVersion}
      *          can be called with the argument, <code>false</code> otherwise
      */
-    public boolean isComparable(ProtocolVersion that) {
+    public boolean isComparable(final ProtocolVersion that) {
         return (that != null) && this.protocol.equals(that.protocol);
     }
 
@@ -199,7 +188,7 @@ public class ProtocolVersion implements Serializable, Cloneable {
      * This method does <i>not</i> define a total ordering, as it would be
      * required for {@link java.lang.Comparable}.
      *
-     * @param that      the protocl version to compare with
+     * @param that      the protocol version to compare with
      *
      * @return   a negative integer, zero, or a positive integer
      *           as this version is less than, equal to, or greater than
@@ -209,17 +198,10 @@ public class ProtocolVersion implements Serializable, Cloneable {
      *         if the argument has a different protocol name than this object,
      *         or if the argument is <code>null</code>
      */
-    public int compareToVersion(ProtocolVersion that) {
-        if (that == null) {
-            throw new IllegalArgumentException
-                ("Protocol version must not be null.");
-        }
-        if (!this.protocol.equals(that.protocol)) {
-            throw new IllegalArgumentException
-                ("Versions for different protocols cannot be compared. " +
-                 this + " " + that);
-        }
-
+    public int compareToVersion(final ProtocolVersion that) {
+        Args.notNull(that, "Protocol version");
+        Args.check(this.protocol.equals(that.protocol),
+                "Versions for different protocols cannot be compared: %s %s", this, that);
         int delta = getMajor() - that.getMajor();
         if (delta == 0) {
             delta = getMinor() - that.getMinor();
@@ -238,7 +220,7 @@ public class ProtocolVersion implements Serializable, Cloneable {
      *          and {@link #compareToVersion compares} as greater or equal,
      *          <code>false</code> otherwise
      */
-    public final boolean greaterEquals(ProtocolVersion version) {
+    public final boolean greaterEquals(final ProtocolVersion version) {
         return isComparable(version) && (compareToVersion(version) >= 0);
     }
 
@@ -253,7 +235,7 @@ public class ProtocolVersion implements Serializable, Cloneable {
      *          and {@link #compareToVersion compares} as less or equal,
      *          <code>false</code> otherwise
      */
-    public final boolean lessEquals(ProtocolVersion version) {
+    public final boolean lessEquals(final ProtocolVersion version) {
         return isComparable(version) && (compareToVersion(version) <= 0);
     }
 
@@ -265,7 +247,7 @@ public class ProtocolVersion implements Serializable, Cloneable {
      */
     @Override
     public String toString() {
-        StringBuilder buffer = new StringBuilder();
+        final StringBuilder buffer = new StringBuilder();
         buffer.append(this.protocol);
         buffer.append('/');
         buffer.append(Integer.toString(this.major));
diff --git a/httpcore/src/main/java/org/apache/http/UnsupportedHttpVersionException.java b/httpcore/src/main/java/org/apache/http/UnsupportedHttpVersionException.java
index d9b698c..788fb36 100644
--- a/httpcore/src/main/java/org/apache/http/UnsupportedHttpVersionException.java
+++ b/httpcore/src/main/java/org/apache/http/UnsupportedHttpVersionException.java
@@ -27,7 +27,6 @@
 
 package org.apache.http;
 
-import org.apache.http.ProtocolException;
 
 /**
  * Signals an unsupported version of the HTTP protocol.
diff --git a/httpcore/src/main/java/org/apache/http/annotation/GuardedBy.java b/httpcore/src/main/java/org/apache/http/annotation/GuardedBy.java
index 5907d26..9e931cb 100644
--- a/httpcore/src/main/java/org/apache/http/annotation/GuardedBy.java
+++ b/httpcore/src/main/java/org/apache/http/annotation/GuardedBy.java
@@ -1,20 +1,21 @@
 /*
  * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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
  *
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You 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
  *
- *      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.
+ * 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.
  * ====================================================================
  *
  * This software consists of voluntary contributions made by many
diff --git a/httpcore/src/main/java/org/apache/http/annotation/Immutable.java b/httpcore/src/main/java/org/apache/http/annotation/Immutable.java
index da201b3..ad08d41 100644
--- a/httpcore/src/main/java/org/apache/http/annotation/Immutable.java
+++ b/httpcore/src/main/java/org/apache/http/annotation/Immutable.java
@@ -1,20 +1,21 @@
 /*
  * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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
  *
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You 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
  *
- *      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.
+ * 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.
  * ====================================================================
  *
  * This software consists of voluntary contributions made by many
diff --git a/httpcore/src/main/java/org/apache/http/annotation/NotThreadSafe.java b/httpcore/src/main/java/org/apache/http/annotation/NotThreadSafe.java
index ddc6787..d453d65 100644
--- a/httpcore/src/main/java/org/apache/http/annotation/NotThreadSafe.java
+++ b/httpcore/src/main/java/org/apache/http/annotation/NotThreadSafe.java
@@ -1,20 +1,21 @@
 /*
  * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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
  *
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You 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
  *
- *      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.
+ * 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.
  * ====================================================================
  *
  * This software consists of voluntary contributions made by many
diff --git a/httpcore/src/main/java/org/apache/http/annotation/ThreadSafe.java b/httpcore/src/main/java/org/apache/http/annotation/ThreadSafe.java
index 53c91b9..809b99e 100644
--- a/httpcore/src/main/java/org/apache/http/annotation/ThreadSafe.java
+++ b/httpcore/src/main/java/org/apache/http/annotation/ThreadSafe.java
@@ -1,20 +1,21 @@
 /*
  * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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
  *
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You 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
  *
- *      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.
+ * 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.
  * ====================================================================
  *
  * This software consists of voluntary contributions made by many
diff --git a/httpcore/src/main/java/org/apache/http/concurrent/BasicFuture.java b/httpcore/src/main/java/org/apache/http/concurrent/BasicFuture.java
index 46a3aca..5c59dd3 100644
--- a/httpcore/src/main/java/org/apache/http/concurrent/BasicFuture.java
+++ b/httpcore/src/main/java/org/apache/http/concurrent/BasicFuture.java
@@ -26,6 +26,8 @@
  */
 package org.apache.http.concurrent;
 
+import org.apache.http.util.Args;
+
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Future;
 import java.util.concurrent.TimeUnit;
@@ -75,10 +77,11 @@ public class BasicFuture<T> implements Future<T>, Cancellable {
         return getResult();
     }
 
-    public synchronized T get(long timeout, final TimeUnit unit)
+    public synchronized T get(final long timeout, final TimeUnit unit)
             throws InterruptedException, ExecutionException, TimeoutException {
-        long msecs = unit.toMillis(timeout);
-        long startTime = (msecs <= 0) ? 0 : System.currentTimeMillis();
+        Args.notNull(unit, "Time unit");
+        final long msecs = unit.toMillis(timeout);
+        final long startTime = (msecs <= 0) ? 0 : System.currentTimeMillis();
         long waitTime = msecs;
         if (this.completed) {
             return getResult();
@@ -129,7 +132,7 @@ public class BasicFuture<T> implements Future<T>, Cancellable {
         return true;
     }
 
-    public boolean cancel(boolean mayInterruptIfRunning) {
+    public boolean cancel(final boolean mayInterruptIfRunning) {
         synchronized(this) {
             if (this.completed) {
                 return false;
diff --git a/httpcore/src/main/java/org/apache/http/concurrent/FutureCallback.java b/httpcore/src/main/java/org/apache/http/concurrent/FutureCallback.java
index 228c659..234c47b 100644
--- a/httpcore/src/main/java/org/apache/http/concurrent/FutureCallback.java
+++ b/httpcore/src/main/java/org/apache/http/concurrent/FutureCallback.java
@@ -26,10 +26,9 @@
  */
 package org.apache.http.concurrent;
 
-import java.util.concurrent.Future;
-
 /**
- * A callback interface that gets invoked upon completion of a {@link Future}.
+ * A callback interface that gets invoked upon completion of
+ * a {@link java.util.concurrent.Future}.
  *
  * @param <T> the future result type returned by this callback.
  * @since 4.2
diff --git a/httpcore/src/main/java/org/apache/http/config/ConnectionConfig.java b/httpcore/src/main/java/org/apache/http/config/ConnectionConfig.java
new file mode 100644
index 0000000..2c466c3
--- /dev/null
+++ b/httpcore/src/main/java/org/apache/http/config/ConnectionConfig.java
@@ -0,0 +1,192 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+
+package org.apache.http.config;
+
+import java.nio.charset.Charset;
+import java.nio.charset.CodingErrorAction;
+
+import org.apache.http.Consts;
+import org.apache.http.annotation.Immutable;
+import org.apache.http.util.Args;
+
+/**
+ * HTTP connection configuration.
+ *
+ * @since 4.3
+ */
+ at Immutable
+public class ConnectionConfig implements Cloneable {
+
+    public static final ConnectionConfig DEFAULT = new Builder().build();
+
+    private final int bufferSize;
+    private final int fragmentSizeHint;
+    private final Charset charset;
+    private final CodingErrorAction malformedInputAction;
+    private final CodingErrorAction unmappableInputAction;
+    private final MessageConstraints messageConstraints;
+
+    ConnectionConfig(
+            final int bufferSize,
+            final int fragmentSizeHint,
+            final Charset charset,
+            final CodingErrorAction malformedInputAction,
+            final CodingErrorAction unmappableInputAction,
+            final MessageConstraints messageConstraints) {
+        super();
+        this.bufferSize = bufferSize;
+        this.fragmentSizeHint = fragmentSizeHint;
+        this.charset = charset;
+        this.malformedInputAction = malformedInputAction;
+        this.unmappableInputAction = unmappableInputAction;
+        this.messageConstraints = messageConstraints;
+    }
+
+    public int getBufferSize() {
+        return bufferSize;
+    }
+
+    public int getFragmentSizeHint() {
+        return fragmentSizeHint;
+    }
+
+    public Charset getCharset() {
+        return charset;
+    }
+
+    public CodingErrorAction getMalformedInputAction() {
+        return malformedInputAction;
+    }
+
+    public CodingErrorAction getUnmappableInputAction() {
+        return unmappableInputAction;
+    }
+
+    public MessageConstraints getMessageConstraints() {
+        return messageConstraints;
+    }
+
+    @Override
+    protected ConnectionConfig clone() throws CloneNotSupportedException {
+        return (ConnectionConfig) super.clone();
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder builder = new StringBuilder();
+        builder.append("[bufferSize=").append(this.bufferSize)
+                .append(", fragmentSizeHint=").append(this.fragmentSizeHint)
+                .append(", charset=").append(this.charset)
+                .append(", malformedInputAction=").append(this.malformedInputAction)
+                .append(", unmappableInputAction=").append(this.unmappableInputAction)
+                .append(", messageConstraints=").append(this.messageConstraints)
+                .append("]");
+        return builder.toString();
+    }
+
+    public static ConnectionConfig.Builder custom() {
+        return new Builder();
+    }
+
+    public static ConnectionConfig.Builder copy(final ConnectionConfig config) {
+        Args.notNull(config, "Connection config");
+        return new Builder()
+            .setCharset(config.getCharset())
+            .setMalformedInputAction(config.getMalformedInputAction())
+            .setUnmappableInputAction(config.getUnmappableInputAction())
+            .setMessageConstraints(config.getMessageConstraints());
+    }
+
+    public static class Builder {
+
+        private int bufferSize;
+        private int fragmentSizeHint;
+        private Charset charset;
+        private CodingErrorAction malformedInputAction;
+        private CodingErrorAction unmappableInputAction;
+        private MessageConstraints messageConstraints;
+
+        Builder() {
+            this.fragmentSizeHint = -1;
+        }
+
+        public Builder setBufferSize(final int bufferSize) {
+            this.bufferSize = bufferSize;
+            return this;
+        }
+
+        public Builder setFragmentSizeHint(final int fragmentSizeHint) {
+            this.fragmentSizeHint = fragmentSizeHint;
+            return this;
+        }
+
+        public Builder setCharset(final Charset charset) {
+            this.charset = charset;
+            return this;
+        }
+
+        public Builder setMalformedInputAction(final CodingErrorAction malformedInputAction) {
+            this.malformedInputAction = malformedInputAction;
+            if (malformedInputAction != null && this.charset == null) {
+                this.charset = Consts.ASCII;
+            }
+            return this;
+        }
+
+        public Builder setUnmappableInputAction(final CodingErrorAction unmappableInputAction) {
+            this.unmappableInputAction = unmappableInputAction;
+            if (unmappableInputAction != null && this.charset == null) {
+                this.charset = Consts.ASCII;
+            }
+            return this;
+        }
+
+        public Builder setMessageConstraints(final MessageConstraints messageConstraints) {
+            this.messageConstraints = messageConstraints;
+            return this;
+        }
+
+        public ConnectionConfig build() {
+            Charset cs = charset;
+            if (cs == null && (malformedInputAction != null || unmappableInputAction != null)) {
+                cs = Consts.ASCII;
+            }
+            final int bufSize = this.bufferSize > 0 ? this.bufferSize : 8 * 1024;
+            final int fragmentHintSize  = this.fragmentSizeHint >= 0 ? this.fragmentSizeHint : bufSize;
+            return new ConnectionConfig(
+                    bufSize,
+                    fragmentHintSize,
+                    cs,
+                    malformedInputAction,
+                    unmappableInputAction,
+                    messageConstraints);
+        }
+
+    }
+
+}
diff --git a/httpcore-benchmark/src/main/java/org/apache/http/benchmark/httpcore/HttpWorkerCallback.java b/httpcore/src/main/java/org/apache/http/config/Lookup.java
similarity index 88%
rename from httpcore-benchmark/src/main/java/org/apache/http/benchmark/httpcore/HttpWorkerCallback.java
rename to httpcore/src/main/java/org/apache/http/config/Lookup.java
index c370359..ff3759c 100644
--- a/httpcore-benchmark/src/main/java/org/apache/http/benchmark/httpcore/HttpWorkerCallback.java
+++ b/httpcore/src/main/java/org/apache/http/config/Lookup.java
@@ -24,12 +24,17 @@
  * <http://www.apache.org/>.
  *
  */
-package org.apache.http.benchmark.httpcore;
 
-interface HttpWorkerCallback {
+package org.apache.http.config;
 
-    void started(HttpWorker worker);
 
-    void shutdown(HttpWorker worker);
+/**
+ * Generic lookup by low-case string ID.
+ *
+ * @since 4.3
+ */
+public interface Lookup<I> {
+
+    I lookup(String name);
 
-}
\ No newline at end of file
+}
diff --git a/httpcore/src/main/java/org/apache/http/config/MessageConstraints.java b/httpcore/src/main/java/org/apache/http/config/MessageConstraints.java
new file mode 100644
index 0000000..5c65e23
--- /dev/null
+++ b/httpcore/src/main/java/org/apache/http/config/MessageConstraints.java
@@ -0,0 +1,113 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+
+package org.apache.http.config;
+
+import org.apache.http.util.Args;
+
+/**
+ * HTTP Message constraints: line length and header count.
+ *
+ * @since 4.3
+ */
+public class MessageConstraints implements Cloneable {
+
+    public static final MessageConstraints DEFAULT = new Builder().build();
+
+    private final int maxLineLength;
+    private final int maxHeaderCount;
+
+    MessageConstraints(final int maxLineLength, final int maxHeaderCount) {
+        super();
+        this.maxLineLength = maxLineLength;
+        this.maxHeaderCount = maxHeaderCount;
+    }
+
+    public int getMaxLineLength() {
+        return maxLineLength;
+    }
+
+    public int getMaxHeaderCount() {
+        return maxHeaderCount;
+    }
+
+    @Override
+    protected MessageConstraints clone() throws CloneNotSupportedException {
+        return (MessageConstraints) super.clone();
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder builder = new StringBuilder();
+        builder.append("[maxLineLength=").append(maxLineLength)
+                .append(", maxHeaderCount=").append(maxHeaderCount)
+                .append("]");
+        return builder.toString();
+    }
+
+    public static MessageConstraints lineLen(final int max) {
+        return new MessageConstraints(Args.notNegative(max, "Max line length"), -1);
+    }
+
+    public static MessageConstraints.Builder custom() {
+        return new Builder();
+    }
+
+    public static MessageConstraints.Builder copy(final MessageConstraints config) {
+        Args.notNull(config, "Message constraints");
+        return new Builder()
+            .setMaxHeaderCount(config.getMaxHeaderCount())
+            .setMaxLineLength(config.getMaxLineLength());
+    }
+
+    public static class Builder {
+
+        private int maxLineLength;
+        private int maxHeaderCount;
+
+        Builder() {
+            this.maxLineLength = -1;
+            this.maxHeaderCount = -1;
+        }
+
+        public Builder setMaxLineLength(final int maxLineLength) {
+            this.maxLineLength = maxLineLength;
+            return this;
+        }
+
+        public Builder setMaxHeaderCount(final int maxHeaderCount) {
+            this.maxHeaderCount = maxHeaderCount;
+            return this;
+        }
+
+        public MessageConstraints build() {
+            return new MessageConstraints(maxLineLength, maxHeaderCount);
+        }
+
+    }
+
+}
diff --git a/httpcore/src/main/java/org/apache/http/UnsupportedHttpVersionException.java b/httpcore/src/main/java/org/apache/http/config/Registry.java
similarity index 64%
copy from httpcore/src/main/java/org/apache/http/UnsupportedHttpVersionException.java
copy to httpcore/src/main/java/org/apache/http/config/Registry.java
index d9b698c..d79c71d 100644
--- a/httpcore/src/main/java/org/apache/http/UnsupportedHttpVersionException.java
+++ b/httpcore/src/main/java/org/apache/http/config/Registry.java
@@ -25,34 +25,39 @@
  *
  */
 
-package org.apache.http;
+package org.apache.http.config;
 
-import org.apache.http.ProtocolException;
+import java.util.Locale;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.apache.http.annotation.ThreadSafe;
 
 /**
- * Signals an unsupported version of the HTTP protocol.
+ * Generic registry of items keyed by low-case string ID.
  *
- * @since 4.0
+ * @since 4.3
  */
-public class UnsupportedHttpVersionException extends ProtocolException {
-
-    private static final long serialVersionUID = -1348448090193107031L;
+ at ThreadSafe
+public final class Registry<I> implements Lookup<I> {
 
+    private final Map<String, I> map;
 
-    /**
-     * Creates an exception without a detail message.
-     */
-    public UnsupportedHttpVersionException() {
+    Registry(final Map<String, I> map) {
         super();
+        this.map = new ConcurrentHashMap<String, I>(map);
+    }
+
+    public I lookup(final String key) {
+        if (key == null) {
+            return null;
+        }
+        return map.get(key.toLowerCase(Locale.US));
     }
 
-    /**
-     * Creates an exception with the specified detail message.
-     *
-     * @param message The exception detail message
-     */
-    public UnsupportedHttpVersionException(final String message) {
-        super(message);
+    @Override
+    public String toString() {
+        return map.toString();
     }
 
 }
diff --git a/httpcore/src/main/java/org/apache/http/impl/io/HttpTransportMetricsImpl.java b/httpcore/src/main/java/org/apache/http/config/RegistryBuilder.java
similarity index 62%
copy from httpcore/src/main/java/org/apache/http/impl/io/HttpTransportMetricsImpl.java
copy to httpcore/src/main/java/org/apache/http/config/RegistryBuilder.java
index 9e8f55b..e5687da 100644
--- a/httpcore/src/main/java/org/apache/http/impl/io/HttpTransportMetricsImpl.java
+++ b/httpcore/src/main/java/org/apache/http/config/RegistryBuilder.java
@@ -25,39 +25,48 @@
  *
  */
 
-package org.apache.http.impl.io;
+package org.apache.http.config;
+
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
 
 import org.apache.http.annotation.NotThreadSafe;
-import org.apache.http.io.HttpTransportMetrics;
+import org.apache.http.util.Args;
 
 /**
- * Default implementation of {@link HttpTransportMetrics}.
+ * Builder for {@link Registry} instances.
  *
- * @since 4.0
+ * @since 4.3
  */
 @NotThreadSafe
-public class HttpTransportMetricsImpl implements HttpTransportMetrics {
+public final class RegistryBuilder<I> {
 
-    private long bytesTransferred = 0;
+    private final Map<String, I> items;
 
-    public HttpTransportMetricsImpl() {
-        super();
+    public static <I> RegistryBuilder<I> create() {
+        return new RegistryBuilder<I>();
     }
 
-    public long getBytesTransferred() {
-        return this.bytesTransferred;
+    RegistryBuilder() {
+        super();
+        this.items = new HashMap<String, I>();
     }
 
-    public void setBytesTransferred(long count) {
-        this.bytesTransferred = count;
+    public RegistryBuilder<I> register(final String id, final I item) {
+        Args.notEmpty(id, "ID");
+        Args.notNull(item, "Item");
+        items.put(id.toLowerCase(Locale.US), item);
+        return this;
     }
 
-    public void incrementBytesTransferred(long count) {
-        this.bytesTransferred += count;
+    public Registry<I> build() {
+        return new Registry<I>(items);
     }
 
-    public void reset() {
-        this.bytesTransferred = 0;
+    @Override
+    public String toString() {
+        return items.toString();
     }
 
 }
diff --git a/httpcore/src/main/java/org/apache/http/config/SocketConfig.java b/httpcore/src/main/java/org/apache/http/config/SocketConfig.java
new file mode 100644
index 0000000..bea618f
--- /dev/null
+++ b/httpcore/src/main/java/org/apache/http/config/SocketConfig.java
@@ -0,0 +1,197 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+
+package org.apache.http.config;
+
+import org.apache.http.annotation.Immutable;
+import org.apache.http.util.Args;
+
+/**
+ * Socket configuration.
+ *
+ * @since 4.3
+ */
+ at Immutable
+public class SocketConfig implements Cloneable {
+
+    public static final SocketConfig DEFAULT = new Builder().build();
+
+    private final int soTimeout;
+    private final boolean soReuseAddress;
+    private final int soLinger;
+    private final boolean soKeepAlive;
+    private final boolean tcpNoDelay;
+
+    SocketConfig(
+            final int soTimeout,
+            final boolean soReuseAddress,
+            final int soLinger,
+            final boolean soKeepAlive,
+            final boolean tcpNoDelay) {
+        super();
+        this.soTimeout = soTimeout;
+        this.soReuseAddress = soReuseAddress;
+        this.soLinger = soLinger;
+        this.soKeepAlive = soKeepAlive;
+        this.tcpNoDelay = tcpNoDelay;
+    }
+
+    /**
+     * Determines the default socket timeout value for non-blocking I/O operations.
+     * <p/>
+     * Default: <code>0</code> (no timeout)
+     *
+     * @see java.net.SocketOptions#SO_TIMEOUT
+     */
+    public int getSoTimeout() {
+        return soTimeout;
+    }
+
+    /**
+     * Determines the default value of the {@link java.net.SocketOptions#SO_REUSEADDR} parameter
+     * for newly created sockets.
+     * <p/>
+     * Default: <code>false</code>
+     *
+     * @see java.net.SocketOptions#SO_REUSEADDR
+     */
+    public boolean isSoReuseAddress() {
+        return soReuseAddress;
+    }
+
+    /**
+     * Determines the default value of the {@link java.net.SocketOptions#SO_LINGER} parameter
+     * for newly created sockets.
+     * <p/>
+     * Default: <code>-1</code>
+     *
+     * @see java.net.SocketOptions#SO_LINGER
+     */
+    public int getSoLinger() {
+        return soLinger;
+    }
+
+    /**
+     * Determines the default value of the {@link java.net.SocketOptions#SO_KEEPALIVE} parameter
+     * for newly created sockets.
+     * <p/>
+     * Default: <code>-1</code>
+     *
+     * @see java.net.SocketOptions#SO_KEEPALIVE
+     */
+    public boolean isSoKeepAlive() {
+        return this.soKeepAlive;
+    }
+
+    /**
+     * Determines the default value of the {@link java.net.SocketOptions#TCP_NODELAY} parameter
+     * for newly created sockets.
+     * <p/>
+     * Default: <code>false</code>
+     *
+     * @see java.net.SocketOptions#TCP_NODELAY
+     */
+    public boolean isTcpNoDelay() {
+        return tcpNoDelay;
+    }
+
+    @Override
+    protected SocketConfig clone() throws CloneNotSupportedException {
+        return (SocketConfig) super.clone();
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder builder = new StringBuilder();
+        builder.append("[soTimeout=").append(this.soTimeout)
+                .append(", soReuseAddress=").append(this.soReuseAddress)
+                .append(", soLinger=").append(this.soLinger)
+                .append(", soKeepAlive=").append(this.soKeepAlive)
+                .append(", tcpNoDelay=").append(this.tcpNoDelay)
+                .append("]");
+        return builder.toString();
+    }
+
+    public static SocketConfig.Builder custom() {
+        return new Builder();
+    }
+
+    public static SocketConfig.Builder copy(final SocketConfig config) {
+        Args.notNull(config, "Socket config");
+        return new Builder()
+            .setSoTimeout(config.getSoTimeout())
+            .setSoReuseAddress(config.isSoReuseAddress())
+            .setSoLinger(config.getSoLinger())
+            .setSoKeepAlive(config.isSoKeepAlive())
+            .setTcpNoDelay(config.isTcpNoDelay());
+    }
+
+    public static class Builder {
+
+        private int soTimeout;
+        private boolean soReuseAddress;
+        private int soLinger;
+        private boolean soKeepAlive;
+        private boolean tcpNoDelay;
+
+        Builder() {
+            this.soLinger = -1;
+            this.tcpNoDelay = true;
+        }
+
+        public Builder setSoTimeout(final int soTimeout) {
+            this.soTimeout = soTimeout;
+            return this;
+        }
+
+        public Builder setSoReuseAddress(final boolean soReuseAddress) {
+            this.soReuseAddress = soReuseAddress;
+            return this;
+        }
+
+        public Builder setSoLinger(final int soLinger) {
+            this.soLinger = soLinger;
+            return this;
+        }
+
+        public Builder setSoKeepAlive(final boolean soKeepAlive) {
+            this.soKeepAlive = soKeepAlive;
+            return this;
+        }
+
+        public Builder setTcpNoDelay(final boolean tcpNoDelay) {
+            this.tcpNoDelay = tcpNoDelay;
+            return this;
+        }
+
+        public SocketConfig build() {
+            return new SocketConfig(soTimeout, soReuseAddress, soLinger, soKeepAlive, tcpNoDelay);
+        }
+
+    }
+
+}
diff --git a/httpcore/src/main/java/org/apache/http/entity/AbstractHttpEntity.java b/httpcore/src/main/java/org/apache/http/entity/AbstractHttpEntity.java
index ef07c63..82366b1 100644
--- a/httpcore/src/main/java/org/apache/http/entity/AbstractHttpEntity.java
+++ b/httpcore/src/main/java/org/apache/http/entity/AbstractHttpEntity.java
@@ -28,7 +28,6 @@
 package org.apache.http.entity;
 
 import java.io.IOException;
-import java.io.OutputStream;
 
 import org.apache.http.Header;
 import org.apache.http.HttpEntity;
@@ -46,6 +45,13 @@ import org.apache.http.protocol.HTTP;
 @NotThreadSafe
 public abstract class AbstractHttpEntity implements HttpEntity {
 
+    /**
+     * Buffer size for output stream processing.
+     *
+     * @since 4.3
+     */
+    protected static final int OUTPUT_BUFFER_SIZE = 4096;
+
     protected Header contentType;
     protected Header contentEncoding;
     protected boolean chunked;
@@ -167,7 +173,7 @@ public abstract class AbstractHttpEntity implements HttpEntity {
      *
      * @param b         the new 'chunked' flag
      */
-    public void setChunked(boolean b) {
+    public void setChunked(final boolean b) {
         this.chunked = b;
     }
 
@@ -176,7 +182,7 @@ public abstract class AbstractHttpEntity implements HttpEntity {
      * The default implementation does not consume anything.
      *
      * @deprecated (4.1) Either use {@link #getContent()} and call {@link java.io.InputStream#close()} on that;
-     * otherwise call {@link #writeTo(OutputStream)} which is required to free the resources.
+     * otherwise call {@link #writeTo(java.io.OutputStream)} which is required to free the resources.
      */
     @Deprecated
     public void consumeContent() throws IOException {
diff --git a/httpcore/src/main/java/org/apache/http/entity/BasicHttpEntity.java b/httpcore/src/main/java/org/apache/http/entity/BasicHttpEntity.java
index de3a6be..737a3f9 100644
--- a/httpcore/src/main/java/org/apache/http/entity/BasicHttpEntity.java
+++ b/httpcore/src/main/java/org/apache/http/entity/BasicHttpEntity.java
@@ -32,6 +32,8 @@ import java.io.InputStream;
 import java.io.OutputStream;
 
 import org.apache.http.annotation.NotThreadSafe;
+import org.apache.http.util.Args;
+import org.apache.http.util.Asserts;
 
 /**
  * A generic streamed, non-repeatable entity that obtains its content
@@ -69,11 +71,8 @@ public class BasicHttpEntity extends AbstractHttpEntity {
      *          if the content has not been provided
      */
     public InputStream getContent() throws IllegalStateException {
-        if (this.content == null) {
-            throw new IllegalStateException("Content has not been provided");
-        }
+        Asserts.check(this.content != null, "Content has not been provided");
         return this.content;
-
     }
 
     /**
@@ -91,7 +90,7 @@ public class BasicHttpEntity extends AbstractHttpEntity {
      * @param len       the number of bytes in the content, or
      *                  a negative number to indicate an unknown length
      */
-    public void setContentLength(long len) {
+    public void setContentLength(final long len) {
         this.length = len;
     }
 
@@ -106,13 +105,11 @@ public class BasicHttpEntity extends AbstractHttpEntity {
     }
 
     public void writeTo(final OutputStream outstream) throws IOException {
-        if (outstream == null) {
-            throw new IllegalArgumentException("Output stream may not be null");
-        }
-        InputStream instream = getContent();
+        Args.notNull(outstream, "Output stream");
+        final InputStream instream = getContent();
         try {
             int l;
-            byte[] tmp = new byte[2048];
+            final byte[] tmp = new byte[OUTPUT_BUFFER_SIZE];
             while ((l = instream.read(tmp)) != -1) {
                 outstream.write(tmp, 0, l);
             }
@@ -125,18 +122,4 @@ public class BasicHttpEntity extends AbstractHttpEntity {
         return this.content != null;
     }
 
-    /**
-     * Closes the content InputStream.
-     *
-     * @deprecated (4.1) Either use {@link #getContent()} and call {@link java.io.InputStream#close()} on that;
-     * otherwise call {@link #writeTo(OutputStream)} which is required to free the resources.
-     */
-    @Deprecated
-    @Override
-    public void consumeContent() throws IOException {
-        if (content != null) {
-            content.close(); // reads to the end of the entity
-        }
-    }
-
 }
diff --git a/httpcore/src/main/java/org/apache/http/entity/BufferedHttpEntity.java b/httpcore/src/main/java/org/apache/http/entity/BufferedHttpEntity.java
index 1b82f9f..c5fc33a 100644
--- a/httpcore/src/main/java/org/apache/http/entity/BufferedHttpEntity.java
+++ b/httpcore/src/main/java/org/apache/http/entity/BufferedHttpEntity.java
@@ -34,6 +34,7 @@ import java.io.OutputStream;
 
 import org.apache.http.HttpEntity;
 import org.apache.http.annotation.NotThreadSafe;
+import org.apache.http.util.Args;
 import org.apache.http.util.EntityUtils;
 
 /**
@@ -70,7 +71,7 @@ public class BufferedHttpEntity extends HttpEntityWrapper {
         if (this.buffer != null) {
             return this.buffer.length;
         } else {
-            return wrappedEntity.getContentLength();
+            return super.getContentLength();
         }
     }
 
@@ -79,7 +80,7 @@ public class BufferedHttpEntity extends HttpEntityWrapper {
         if (this.buffer != null) {
             return new ByteArrayInputStream(this.buffer);
         } else {
-            return wrappedEntity.getContent();
+            return super.getContent();
         }
     }
 
@@ -90,7 +91,7 @@ public class BufferedHttpEntity extends HttpEntityWrapper {
      */
     @Override
     public boolean isChunked() {
-        return (buffer == null) && wrappedEntity.isChunked();
+        return (buffer == null) && super.isChunked();
     }
 
     /**
@@ -106,13 +107,11 @@ public class BufferedHttpEntity extends HttpEntityWrapper {
 
     @Override
     public void writeTo(final OutputStream outstream) throws IOException {
-        if (outstream == null) {
-            throw new IllegalArgumentException("Output stream may not be null");
-        }
+        Args.notNull(outstream, "Output stream");
         if (this.buffer != null) {
             outstream.write(this.buffer);
         } else {
-            wrappedEntity.writeTo(outstream);
+            super.writeTo(outstream);
         }
     }
 
@@ -120,7 +119,7 @@ public class BufferedHttpEntity extends HttpEntityWrapper {
     // non-javadoc, see interface HttpEntity
     @Override
     public boolean isStreaming() {
-        return (buffer == null) && wrappedEntity.isStreaming();
+        return (buffer == null) && super.isStreaming();
     }
 
 } // class BufferedHttpEntity
diff --git a/httpcore/src/main/java/org/apache/http/entity/ByteArrayEntity.java b/httpcore/src/main/java/org/apache/http/entity/ByteArrayEntity.java
index 20b7680..5c21365 100644
--- a/httpcore/src/main/java/org/apache/http/entity/ByteArrayEntity.java
+++ b/httpcore/src/main/java/org/apache/http/entity/ByteArrayEntity.java
@@ -33,6 +33,7 @@ import java.io.InputStream;
 import java.io.OutputStream;
 
 import org.apache.http.annotation.NotThreadSafe;
+import org.apache.http.util.Args;
 
 /**
  * A self contained, repeatable entity that obtains its content from a byte array.
@@ -55,9 +56,7 @@ public class ByteArrayEntity extends AbstractHttpEntity implements Cloneable {
      */
     public ByteArrayEntity(final byte[] b, final ContentType contentType) {
         super();
-        if (b == null) {
-            throw new IllegalArgumentException("Source byte array may not be null");
-        }
+        Args.notNull(b, "Source byte array");
         this.content = b;
         this.b = b;
         this.off = 0;
@@ -70,11 +69,9 @@ public class ByteArrayEntity extends AbstractHttpEntity implements Cloneable {
     /**
      * @since 4.2
      */
-    public ByteArrayEntity(final byte[] b, int off, int len, final ContentType contentType) {
+    public ByteArrayEntity(final byte[] b, final int off, final int len, final ContentType contentType) {
         super();
-        if (b == null) {
-            throw new IllegalArgumentException("Source byte array may not be null");
-        }
+        Args.notNull(b, "Source byte array");
         if ((off < 0) || (off > b.length) || (len < 0) ||
                 ((off + len) < 0) || ((off + len) > b.length)) {
             throw new IndexOutOfBoundsException("off: " + off + " len: " + len + " b.length: " + b.length);
@@ -92,7 +89,7 @@ public class ByteArrayEntity extends AbstractHttpEntity implements Cloneable {
         this(b, null);
     }
 
-    public ByteArrayEntity(final byte[] b, int off, int len) {
+    public ByteArrayEntity(final byte[] b, final int off, final int len) {
         this(b, off, len, null);
     }
 
@@ -109,9 +106,7 @@ public class ByteArrayEntity extends AbstractHttpEntity implements Cloneable {
     }
 
     public void writeTo(final OutputStream outstream) throws IOException {
-        if (outstream == null) {
-            throw new IllegalArgumentException("Output stream may not be null");
-        }
+        Args.notNull(outstream, "Output stream");
         outstream.write(this.b, this.off, this.len);
         outstream.flush();
     }
diff --git a/httpcore/src/main/java/org/apache/http/entity/ContentLengthStrategy.java b/httpcore/src/main/java/org/apache/http/entity/ContentLengthStrategy.java
index 6b4867b..bb14409 100644
--- a/httpcore/src/main/java/org/apache/http/entity/ContentLengthStrategy.java
+++ b/httpcore/src/main/java/org/apache/http/entity/ContentLengthStrategy.java
@@ -47,7 +47,7 @@ public interface ContentLengthStrategy {
      * message will be delimited by the end of connection, or {@link #CHUNKED}
      * if the message is chunk coded
      *
-     * @param message
+     * @param message HTTP message
      * @return content length, {@link #IDENTITY}, or {@link #CHUNKED}
      *
      * @throws HttpException in case of HTTP protocol violation
diff --git a/httpcore/src/main/java/org/apache/http/entity/ContentType.java b/httpcore/src/main/java/org/apache/http/entity/ContentType.java
index c89e07c..8e20778 100644
--- a/httpcore/src/main/java/org/apache/http/entity/ContentType.java
+++ b/httpcore/src/main/java/org/apache/http/entity/ContentType.java
@@ -39,7 +39,12 @@ import org.apache.http.HttpEntity;
 import org.apache.http.NameValuePair;
 import org.apache.http.ParseException;
 import org.apache.http.annotation.Immutable;
+import org.apache.http.message.BasicHeaderValueFormatter;
 import org.apache.http.message.BasicHeaderValueParser;
+import org.apache.http.message.ParserCursor;
+import org.apache.http.util.Args;
+import org.apache.http.util.CharArrayBuffer;
+import org.apache.http.util.TextUtils;
 
 /**
  * Content type information consisting of a MIME type and an optional charset.
@@ -54,7 +59,7 @@ import org.apache.http.message.BasicHeaderValueParser;
 public final class ContentType implements Serializable {
 
     private static final long serialVersionUID = -7768694718232371896L;
-    
+
     // constants
     public static final ContentType APPLICATION_ATOM_XML = create(
             "application/atom+xml", Consts.ISO_8859_1);
@@ -87,17 +92,23 @@ public final class ContentType implements Serializable {
 
     private final String mimeType;
     private final Charset charset;
+    private final NameValuePair[] params;
 
-    /**
-     * Given a MIME type and a character set, constructs a ContentType.
-     * @param mimeType The MIME type to use for the ContentType header.
-     * @param charset The optional character set to use with the ContentType header.
-     * @throws  UnsupportedCharsetException
-     *          If no support for the named charset is available in this Java virtual machine
-     */
-    ContentType(final String mimeType, final Charset charset) {
+    ContentType(
+            final String mimeType,
+            final Charset charset) {
         this.mimeType = mimeType;
         this.charset = charset;
+        this.params = null;
+    }
+
+    ContentType(
+            final String mimeType,
+            final NameValuePair[] params) throws UnsupportedCharsetException {
+        this.mimeType = mimeType;
+        this.params = params;
+        final String s = getParameter("charset");
+        this.charset = !TextUtils.isBlank(s) ? Charset.forName(s) : null;
     }
 
     public String getMimeType() {
@@ -109,14 +120,33 @@ public final class ContentType implements Serializable {
     }
 
     /**
-     * Converts a ContentType to a string which can be used as a ContentType header.
-     * If a charset is provided by the ContentType, it will be included in the string.
+     * @since 4.3
+     */
+    public String getParameter(final String name) {
+        Args.notEmpty(name, "Parameter name");
+        if (this.params == null) {
+            return null;
+        }
+        for (final NameValuePair param: this.params) {
+            if (param.getName().equalsIgnoreCase(name)) {
+                return param.getValue();
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Generates textual representation of this content type which can be used as the value
+     * of a <code>Content-Type</code> header.
      */
     @Override
     public String toString() {
-        StringBuilder buf = new StringBuilder();
+        final CharArrayBuffer buf = new CharArrayBuffer(64);
         buf.append(this.mimeType);
-        if (this.charset != null) {
+        if (this.params != null) {
+            buf.append("; ");
+            BasicHeaderValueFormatter.INSTANCE.formatParameters(buf, this.params, false);
+        } else if (this.charset != null) {
             buf.append("; charset=");
             buf.append(this.charset.name());
         }
@@ -125,7 +155,7 @@ public final class ContentType implements Serializable {
 
     private static boolean valid(final String s) {
         for (int i = 0; i < s.length(); i++) {
-            char ch = s.charAt(i);
+            final char ch = s.charAt(i);
             if (ch == '"' || ch == ',' || ch == ';') {
                 return false;
             }
@@ -142,16 +172,8 @@ public final class ContentType implements Serializable {
      * @return content type
      */
     public static ContentType create(final String mimeType, final Charset charset) {
-        if (mimeType == null) {
-            throw new IllegalArgumentException("MIME type may not be null");
-        }
-        String type = mimeType.trim().toLowerCase(Locale.US);
-        if (type.length() == 0) {
-            throw new IllegalArgumentException("MIME type may not be empty");
-        }
-        if (!valid(type)) {
-            throw new IllegalArgumentException("MIME type may not contain reserved characters");
-        }
+        final String type = Args.notBlank(mimeType, "MIME type").toLowerCase(Locale.US);
+        Args.check(valid(type), "MIME type may not contain reserved characters");
         return new ContentType(type, charset);
     }
 
@@ -165,7 +187,7 @@ public final class ContentType implements Serializable {
     public static ContentType create(final String mimeType) {
         return new ContentType(mimeType, (Charset) null);
     }
-    
+
     /**
      * Creates a new instance of {@link ContentType}.
      *
@@ -174,21 +196,18 @@ public final class ContentType implements Serializable {
      * @param charset charset. It may not contain characters <">, <;>, <,> reserved by the HTTP
      *        specification. This parameter is optional.
      * @return content type
+     * @throws UnsupportedCharsetException Thrown when the named charset is not available in
+     * this instance of the Java virtual machine
      */
     public static ContentType create(
             final String mimeType, final String charset) throws UnsupportedCharsetException {
-        return create(mimeType, 
-                (charset != null && charset.length() > 0) ? Charset.forName(charset) : null);
+        return create(mimeType, !TextUtils.isBlank(charset) ? Charset.forName(charset) : null);
     }
 
     private static ContentType create(final HeaderElement helem) {
-        String mimeType = helem.getName();
-        String charset = null;
-        NameValuePair param = helem.getParameterByName("charset");
-        if (param != null) {
-            charset = param.getValue();
-        }
-        return create(mimeType, charset);
+        final String mimeType = helem.getName();
+        final NameValuePair[] params = helem.getParameters();
+        return new ContentType(mimeType, params != null && params.length > 0 ? params : null);
     }
 
     /**
@@ -198,13 +217,16 @@ public final class ContentType implements Serializable {
      * @return content type
      * @throws ParseException if the given text does not represent a valid
      * <code>Content-Type</code> value.
+     * @throws UnsupportedCharsetException Thrown when the named charset is not available in
+     * this instance of the Java virtual machine
      */
     public static ContentType parse(
             final String s) throws ParseException, UnsupportedCharsetException {
-        if (s == null) {
-            throw new IllegalArgumentException("Content type may not be null");
-        }
-        HeaderElement[] elements = BasicHeaderValueParser.parseElements(s, null);
+        Args.notNull(s, "Content type");
+        final CharArrayBuffer buf = new CharArrayBuffer(s.length());
+        buf.append(s);
+        final ParserCursor cursor = new ParserCursor(0, s.length());
+        final HeaderElement[] elements = BasicHeaderValueParser.INSTANCE.parseElements(buf, cursor);
         if (elements.length > 0) {
             return create(elements[0]);
         } else {
@@ -221,15 +243,17 @@ public final class ContentType implements Serializable {
      * @return content type
      * @throws ParseException if the given text does not represent a valid
      * <code>Content-Type</code> value.
+     * @throws UnsupportedCharsetException Thrown when the named charset is not available in
+     * this instance of the Java virtual machine
      */
     public static ContentType get(
             final HttpEntity entity) throws ParseException, UnsupportedCharsetException {
         if (entity == null) {
             return null;
         }
-        Header header = entity.getContentType();
+        final Header header = entity.getContentType();
         if (header != null) {
-            HeaderElement[] elements = header.getElements();
+            final HeaderElement[] elements = header.getElements();
             if (elements.length > 0) {
                 return create(elements[0]);
             }
@@ -238,18 +262,44 @@ public final class ContentType implements Serializable {
     }
 
     /**
-     * Extracts <code>Content-Type</code> value from {@link HttpEntity} or returns default value
-     * if not explicitly specified.
+     * Extracts <code>Content-Type</code> value from {@link HttpEntity} or returns the default value
+     * {@link #DEFAULT_TEXT} if not explicitly specified.
      *
      * @param entity HTTP entity
      * @return content type
      * @throws ParseException if the given text does not represent a valid
      * <code>Content-Type</code> value.
+     * @throws UnsupportedCharsetException Thrown when the named charset is not available in
+     * this instance of the Java virtual machine
      */
     public static ContentType getOrDefault(
             final HttpEntity entity) throws ParseException, UnsupportedCharsetException {
-        ContentType contentType = get(entity);
+        final ContentType contentType = get(entity);
         return contentType != null ? contentType : DEFAULT_TEXT;
     }
 
+    /**
+     * Creates a new instance with this MIME type and the given Charset.
+     *
+     * @param charset charset
+     * @return a new instance with this MIME type and the given Charset.
+     * @since 4.3
+     */
+    public ContentType withCharset(final Charset charset) {
+        return create(this.getMimeType(), charset);
+    }
+
+    /**
+     * Creates a new instance with this MIME type and the given Charset name.
+     *
+     * @param charset name
+     * @return a new instance with this MIME type and the given Charset name.
+     * @throws UnsupportedCharsetException Thrown when the named charset is not available in
+     * this instance of the Java virtual machine
+     * @since 4.3
+     */
+    public ContentType withCharset(final String charset) {
+        return create(this.getMimeType(), charset);
+    }
+
 }
diff --git a/httpcore/src/main/java/org/apache/http/entity/EntityTemplate.java b/httpcore/src/main/java/org/apache/http/entity/EntityTemplate.java
index 0638f35..3bfcaea 100644
--- a/httpcore/src/main/java/org/apache/http/entity/EntityTemplate.java
+++ b/httpcore/src/main/java/org/apache/http/entity/EntityTemplate.java
@@ -33,6 +33,8 @@ import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
 
+import org.apache.http.util.Args;
+
 /**
  * Entity that delegates the process of content generation
  * to a {@link ContentProducer}.
@@ -45,10 +47,7 @@ public class EntityTemplate extends AbstractHttpEntity {
 
     public EntityTemplate(final ContentProducer contentproducer) {
         super();
-        if (contentproducer == null) {
-            throw new IllegalArgumentException("Content producer may not be null");
-        }
-        this.contentproducer = contentproducer;
+        this.contentproducer = Args.notNull(contentproducer, "Content producer");
     }
 
     public long getContentLength() {
@@ -56,7 +55,7 @@ public class EntityTemplate extends AbstractHttpEntity {
     }
 
     public InputStream getContent() throws IOException {
-        ByteArrayOutputStream buf = new ByteArrayOutputStream();
+        final ByteArrayOutputStream buf = new ByteArrayOutputStream();
         writeTo(buf);
         return new ByteArrayInputStream(buf.toByteArray());
     }
@@ -66,9 +65,7 @@ public class EntityTemplate extends AbstractHttpEntity {
     }
 
     public void writeTo(final OutputStream outstream) throws IOException {
-        if (outstream == null) {
-            throw new IllegalArgumentException("Output stream may not be null");
-        }
+        Args.notNull(outstream, "Output stream");
         this.contentproducer.writeTo(outstream);
     }
 
diff --git a/httpcore/src/main/java/org/apache/http/entity/FileEntity.java b/httpcore/src/main/java/org/apache/http/entity/FileEntity.java
index 86e5bba..73ef359 100644
--- a/httpcore/src/main/java/org/apache/http/entity/FileEntity.java
+++ b/httpcore/src/main/java/org/apache/http/entity/FileEntity.java
@@ -34,6 +34,7 @@ import java.io.InputStream;
 import java.io.OutputStream;
 
 import org.apache.http.annotation.NotThreadSafe;
+import org.apache.http.util.Args;
 
 /**
  * A self contained, repeatable entity that obtains its content from a file.
@@ -51,10 +52,7 @@ public class FileEntity extends AbstractHttpEntity implements Cloneable {
     @Deprecated
     public FileEntity(final File file, final String contentType) {
         super();
-        if (file == null) {
-            throw new IllegalArgumentException("File may not be null");
-        }
-        this.file = file;
+        this.file = Args.notNull(file, "File");
         setContentType(contentType);
     }
 
@@ -63,10 +61,7 @@ public class FileEntity extends AbstractHttpEntity implements Cloneable {
      */
     public FileEntity(final File file, final ContentType contentType) {
         super();
-        if (file == null) {
-            throw new IllegalArgumentException("File may not be null");
-        }
-        this.file = file;
+        this.file = Args.notNull(file, "File");
         if (contentType != null) {
             setContentType(contentType.toString());
         }
@@ -77,10 +72,7 @@ public class FileEntity extends AbstractHttpEntity implements Cloneable {
      */
     public FileEntity(final File file) {
         super();
-        if (file == null) {
-            throw new IllegalArgumentException("File may not be null");
-        }
-        this.file = file;
+        this.file = Args.notNull(file, "File");
     }
 
     public boolean isRepeatable() {
@@ -96,12 +88,10 @@ public class FileEntity extends AbstractHttpEntity implements Cloneable {
     }
 
     public void writeTo(final OutputStream outstream) throws IOException {
-        if (outstream == null) {
-            throw new IllegalArgumentException("Output stream may not be null");
-        }
-        InputStream instream = new FileInputStream(this.file);
+        Args.notNull(outstream, "Output stream");
+        final InputStream instream = new FileInputStream(this.file);
         try {
-            byte[] tmp = new byte[4096];
+            final byte[] tmp = new byte[OUTPUT_BUFFER_SIZE];
             int l;
             while ((l = instream.read(tmp)) != -1) {
                 outstream.write(tmp, 0, l);
diff --git a/httpcore/src/main/java/org/apache/http/entity/HttpEntityWrapper.java b/httpcore/src/main/java/org/apache/http/entity/HttpEntityWrapper.java
index 1d1cabc..65819ab 100644
--- a/httpcore/src/main/java/org/apache/http/entity/HttpEntityWrapper.java
+++ b/httpcore/src/main/java/org/apache/http/entity/HttpEntityWrapper.java
@@ -34,6 +34,7 @@ import java.io.OutputStream;
 import org.apache.http.Header;
 import org.apache.http.HttpEntity;
 import org.apache.http.annotation.NotThreadSafe;
+import org.apache.http.util.Args;
 
 /**
  * Base class for wrapping entities.
@@ -52,22 +53,12 @@ public class HttpEntityWrapper implements HttpEntity {
 
     /**
      * Creates a new entity wrapper.
-     *
-     * @param wrapped   the entity to wrap, not null
-     * @throws IllegalArgumentException if wrapped is null
      */
-    public HttpEntityWrapper(HttpEntity wrapped) {
+    public HttpEntityWrapper(final HttpEntity wrappedEntity) {
         super();
-
-        if (wrapped == null) {
-            throw new IllegalArgumentException
-                ("wrapped entity must not be null");
-        }
-        wrappedEntity = wrapped;
-
+        this.wrappedEntity = Args.notNull(wrappedEntity, "Wrapped entity");
     } // constructor
 
-
     public boolean isRepeatable() {
         return wrappedEntity.isRepeatable();
     }
@@ -93,7 +84,7 @@ public class HttpEntityWrapper implements HttpEntity {
         return wrappedEntity.getContent();
     }
 
-    public void writeTo(OutputStream outstream)
+    public void writeTo(final OutputStream outstream)
         throws IOException {
         wrappedEntity.writeTo(outstream);
     }
diff --git a/httpcore/src/main/java/org/apache/http/entity/InputStreamEntity.java b/httpcore/src/main/java/org/apache/http/entity/InputStreamEntity.java
index 9dd034b..dcec0c0 100644
--- a/httpcore/src/main/java/org/apache/http/entity/InputStreamEntity.java
+++ b/httpcore/src/main/java/org/apache/http/entity/InputStreamEntity.java
@@ -32,6 +32,7 @@ import java.io.InputStream;
 import java.io.OutputStream;
 
 import org.apache.http.annotation.NotThreadSafe;
+import org.apache.http.util.Args;
 
 /**
  * A streamed, non-repeatable entity that obtains its content from
@@ -42,24 +43,55 @@ import org.apache.http.annotation.NotThreadSafe;
 @NotThreadSafe
 public class InputStreamEntity extends AbstractHttpEntity {
 
-    private final static int BUFFER_SIZE = 2048;
-
     private final InputStream content;
     private final long length;
 
-    public InputStreamEntity(final InputStream instream, long length) {
+    /**
+     * Creates an entity with an unknown length.
+     * Equivalent to {@code new InputStreamEntity(instream, -1)}.
+     *
+     * @param instream input stream
+     * @throws IllegalArgumentException if {@code instream} is {@code null}
+     * @since 4.3
+     */
+    public InputStreamEntity(final InputStream instream) {
+        this(instream, -1);
+    }
+
+    /**
+     * Creates an entity with a specified content length.
+     *
+     * @param instream input stream
+     * @param length of the input stream, {@code -1} if unknown
+     * @throws IllegalArgumentException if {@code instream} is {@code null}
+     */
+    public InputStreamEntity(final InputStream instream, final long length) {
         this(instream, length, null);
     }
 
     /**
+     * Creates an entity with a content type and unknown length.
+     * Equivalent to {@code new InputStreamEntity(instream, -1, contentType)}.
+     *
+     * @param instream input stream
+     * @param contentType content type
+     * @throws IllegalArgumentException if {@code instream} is {@code null}
+     * @since 4.3
+     */
+    public InputStreamEntity(final InputStream instream, final ContentType contentType) {
+        this(instream, -1, contentType);
+    }
+
+    /**
+     * @param instream input stream
+     * @param length of the input stream, {@code -1} if unknown
+     * @param contentType for specifying the {@code Content-Type} header, may be {@code null}
+     * @throws IllegalArgumentException if {@code instream} is {@code null}
      * @since 4.2
      */
-    public InputStreamEntity(final InputStream instream, long length, final ContentType contentType) {
+    public InputStreamEntity(final InputStream instream, final long length, final ContentType contentType) {
         super();
-        if (instream == null) {
-            throw new IllegalArgumentException("Source input stream may not be null");
-        }
-        this.content = instream;
+        this.content = Args.notNull(instream, "Source input stream");
         this.length = length;
         if (contentType != null) {
             setContentType(contentType.toString());
@@ -70,6 +102,9 @@ public class InputStreamEntity extends AbstractHttpEntity {
         return false;
     }
 
+    /**
+     * @return the content length or {@code -1} if unknown
+     */
     public long getContentLength() {
         return this.length;
     }
@@ -78,13 +113,18 @@ public class InputStreamEntity extends AbstractHttpEntity {
         return this.content;
     }
 
+    /**
+     * Writes bytes from the {@code InputStream} this entity was constructed
+     * with to an {@code OutputStream}.  The content length
+     * determines how many bytes are written.  If the length is unknown ({@code -1}), the
+     * stream will be completely consumed (to the end of the stream).
+     *
+     */
     public void writeTo(final OutputStream outstream) throws IOException {
-        if (outstream == null) {
-            throw new IllegalArgumentException("Output stream may not be null");
-        }
-        InputStream instream = this.content;
+        Args.notNull(outstream, "Output stream");
+        final InputStream instream = this.content;
         try {
-            byte[] buffer = new byte[BUFFER_SIZE];
+            final byte[] buffer = new byte[OUTPUT_BUFFER_SIZE];
             int l;
             if (this.length < 0) {
                 // consume until EOF
@@ -95,7 +135,7 @@ public class InputStreamEntity extends AbstractHttpEntity {
                 // consume no more than length
                 long remaining = this.length;
                 while (remaining > 0) {
-                    l = instream.read(buffer, 0, (int)Math.min(BUFFER_SIZE, remaining));
+                    l = instream.read(buffer, 0, (int)Math.min(OUTPUT_BUFFER_SIZE, remaining));
                     if (l == -1) {
                         break;
                     }
@@ -112,16 +152,4 @@ public class InputStreamEntity extends AbstractHttpEntity {
         return true;
     }
 
-    /**
-     * @deprecated (4.1) Either use {@link #getContent()} and call {@link java.io.InputStream#close()} on that;
-     * otherwise call {@link #writeTo(OutputStream)} which is required to free the resources.
-     */
-    @Deprecated
-    @Override
-    public void consumeContent() throws IOException {
-        // If the input stream is from a connection, closing it will read to
-        // the end of the content. Otherwise, we don't care what it does.
-        this.content.close();
-    }
-
 }
diff --git a/httpcore/src/main/java/org/apache/http/entity/SerializableEntity.java b/httpcore/src/main/java/org/apache/http/entity/SerializableEntity.java
index f3f9191..c6578f1 100644
--- a/httpcore/src/main/java/org/apache/http/entity/SerializableEntity.java
+++ b/httpcore/src/main/java/org/apache/http/entity/SerializableEntity.java
@@ -36,6 +36,7 @@ import java.io.OutputStream;
 import java.io.Serializable;
 
 import org.apache.http.annotation.NotThreadSafe;
+import org.apache.http.util.Args;
 
 /**
  * A streamed entity that obtains its content from a {@link Serializable}.
@@ -60,12 +61,9 @@ public class SerializableEntity extends AbstractHttpEntity {
      *        stored in an internal buffer
      * @throws IOException in case of an I/O error
      */
-    public SerializableEntity(Serializable ser, boolean bufferize) throws IOException {
+    public SerializableEntity(final Serializable ser, final boolean bufferize) throws IOException {
         super();
-        if (ser == null) {
-            throw new IllegalArgumentException("Source object may not be null");
-        }
-
+        Args.notNull(ser, "Source object");
         if (bufferize) {
             createBytes(ser);
         } else {
@@ -73,9 +71,18 @@ public class SerializableEntity extends AbstractHttpEntity {
         }
     }
 
-    private void createBytes(Serializable ser) throws IOException {
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        ObjectOutputStream out = new ObjectOutputStream(baos);
+    /**
+     * @since 4.3
+     */
+    public SerializableEntity(final Serializable ser) {
+        super();
+        Args.notNull(ser, "Source object");
+        this.objRef = ser;
+    }
+
+    private void createBytes(final Serializable ser) throws IOException {
+        final ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        final ObjectOutputStream out = new ObjectOutputStream(baos);
         out.writeObject(ser);
         out.flush();
         this.objSer = baos.toByteArray();
@@ -104,13 +111,10 @@ public class SerializableEntity extends AbstractHttpEntity {
         return this.objSer == null;
     }
 
-    public void writeTo(OutputStream outstream) throws IOException {
-        if (outstream == null) {
-            throw new IllegalArgumentException("Output stream may not be null");
-        }
-
+    public void writeTo(final OutputStream outstream) throws IOException {
+        Args.notNull(outstream, "Output stream");
         if (this.objSer == null) {
-            ObjectOutputStream out = new ObjectOutputStream(outstream);
+            final ObjectOutputStream out = new ObjectOutputStream(outstream);
             out.writeObject(this.objRef);
             out.flush();
         } else {
diff --git a/httpcore/src/main/java/org/apache/http/entity/StringEntity.java b/httpcore/src/main/java/org/apache/http/entity/StringEntity.java
index a1f96c7..00f81b0 100644
--- a/httpcore/src/main/java/org/apache/http/entity/StringEntity.java
+++ b/httpcore/src/main/java/org/apache/http/entity/StringEntity.java
@@ -37,6 +37,7 @@ import java.nio.charset.UnsupportedCharsetException;
 
 import org.apache.http.annotation.NotThreadSafe;
 import org.apache.http.protocol.HTTP;
+import org.apache.http.util.Args;
 
 /**
  * A self contained, repeatable entity that obtains its content from
@@ -62,16 +63,14 @@ public class StringEntity extends AbstractHttpEntity implements Cloneable {
      */
     public StringEntity(final String string, final ContentType contentType) {
         super();
-        if (string == null) {
-            throw new IllegalArgumentException("Source string may not be null");
-        }
+        Args.notNull(string, "Source string");
         Charset charset = contentType != null ? contentType.getCharset() : null;
         if (charset == null) {
             charset = HTTP.DEF_CONTENT_CHARSET;
         }
         try {
             this.content = string.getBytes(charset.name());
-        } catch (UnsupportedEncodingException ex) {
+        } catch (final UnsupportedEncodingException ex) {
             // should never happen
             throw new UnsupportedCharsetException(charset.name());
         }
@@ -95,20 +94,14 @@ public class StringEntity extends AbstractHttpEntity implements Cloneable {
      * @deprecated (4.1.3) use {@link #StringEntity(String, ContentType)}
      */
     @Deprecated
-    public StringEntity(final String string, String mimeType, String charset)
-            throws UnsupportedEncodingException {
+    public StringEntity(
+            final String string, final String mimeType, final String charset) throws UnsupportedEncodingException {
         super();
-        if (string == null) {
-            throw new IllegalArgumentException("Source string may not be null");
-        }
-        if (mimeType == null) {
-            mimeType = HTTP.PLAIN_TEXT_TYPE;
-        }
-        if (charset == null) {
-            charset = HTTP.DEFAULT_CONTENT_CHARSET;
-        }
-        this.content = string.getBytes(charset);
-        setContentType(mimeType + HTTP.CHARSET_PARAM + charset);
+        Args.notNull(string, "Source string");
+        final String mt = mimeType != null ? mimeType : HTTP.PLAIN_TEXT_TYPE;
+        final String cs = charset != null ? charset :HTTP.DEFAULT_CONTENT_CHARSET;
+        this.content = string.getBytes(cs);
+        setContentType(mt + HTTP.CHARSET_PARAM + cs);
     }
 
     /**
@@ -120,7 +113,8 @@ public class StringEntity extends AbstractHttpEntity implements Cloneable {
      *   is {@link HTTP#DEF_CONTENT_CHARSET} is assumed
      *
      * @throws IllegalArgumentException if the string parameter is null
-     * @throws UnsupportedEncodingException if the charset is not supported.
+     * @throws UnsupportedCharsetException Thrown when the named charset is not available in
+     * this instance of the Java virtual machine
      */
     public StringEntity(final String string, final String charset)
             throws UnsupportedEncodingException {
@@ -136,7 +130,7 @@ public class StringEntity extends AbstractHttpEntity implements Cloneable {
      *   is {@link HTTP#DEF_CONTENT_CHARSET} is assumed
      *
      * @throws IllegalArgumentException if the string parameter is null
-     * 
+     *
      * @since 4.2
      */
     public StringEntity(final String string, final Charset charset) {
@@ -170,9 +164,7 @@ public class StringEntity extends AbstractHttpEntity implements Cloneable {
     }
 
     public void writeTo(final OutputStream outstream) throws IOException {
-        if (outstream == null) {
-            throw new IllegalArgumentException("Output stream may not be null");
-        }
+        Args.notNull(outstream, "Output stream");
         outstream.write(this.content);
         outstream.flush();
     }
diff --git a/httpcore/src/main/java/org/apache/http/impl/BHttpConnectionBase.java b/httpcore/src/main/java/org/apache/http/impl/BHttpConnectionBase.java
new file mode 100644
index 0000000..21f76a3
--- /dev/null
+++ b/httpcore/src/main/java/org/apache/http/impl/BHttpConnectionBase.java
@@ -0,0 +1,393 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+
+package org.apache.http.impl;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.InetAddress;
+import java.net.Socket;
+import java.net.SocketAddress;
+import java.net.SocketException;
+import java.net.SocketTimeoutException;
+import java.nio.charset.CharsetDecoder;
+import java.nio.charset.CharsetEncoder;
+
+import org.apache.http.Header;
+import org.apache.http.HttpConnection;
+import org.apache.http.HttpConnectionMetrics;
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpException;
+import org.apache.http.HttpInetConnection;
+import org.apache.http.HttpMessage;
+import org.apache.http.annotation.NotThreadSafe;
+import org.apache.http.config.MessageConstraints;
+import org.apache.http.entity.BasicHttpEntity;
+import org.apache.http.entity.ContentLengthStrategy;
+import org.apache.http.impl.entity.LaxContentLengthStrategy;
+import org.apache.http.impl.entity.StrictContentLengthStrategy;
+import org.apache.http.impl.io.ChunkedInputStream;
+import org.apache.http.impl.io.ChunkedOutputStream;
+import org.apache.http.impl.io.ContentLengthInputStream;
+import org.apache.http.impl.io.ContentLengthOutputStream;
+import org.apache.http.impl.io.HttpTransportMetricsImpl;
+import org.apache.http.impl.io.IdentityInputStream;
+import org.apache.http.impl.io.IdentityOutputStream;
+import org.apache.http.impl.io.SessionInputBufferImpl;
+import org.apache.http.impl.io.SessionOutputBufferImpl;
+import org.apache.http.io.SessionInputBuffer;
+import org.apache.http.io.SessionOutputBuffer;
+import org.apache.http.protocol.HTTP;
+import org.apache.http.util.Args;
+import org.apache.http.util.Asserts;
+import org.apache.http.util.NetUtils;
+
+/**
+ * This class serves as a base for all {@link HttpConnection} implementations and provides
+ * functionality common to both client and server HTTP connections.
+ *
+ * @since 4.0
+ */
+ at NotThreadSafe
+public class BHttpConnectionBase implements HttpConnection, HttpInetConnection {
+
+    private final SessionInputBufferImpl inbuffer;
+    private final SessionOutputBufferImpl outbuffer;
+    private final HttpConnectionMetricsImpl connMetrics;
+    private final ContentLengthStrategy incomingContentStrategy;
+    private final ContentLengthStrategy outgoingContentStrategy;
+
+    private volatile boolean open;
+    private volatile Socket socket;
+
+    /**
+     * Creates new instance of BHttpConnectionBase.
+     *
+     * @param buffersize buffer size. Must be a positive number.
+     * @param fragmentSizeHint fragment size hint.
+     * @param chardecoder decoder to be used for decoding HTTP protocol elements.
+     *   If <code>null</code> simple type cast will be used for byte to char conversion.
+     * @param charencoder encoder to be used for encoding HTTP protocol elements.
+     *   If <code>null</code> simple type cast will be used for char to byte conversion.
+     * @param constraints Message constraints. If <code>null</code>
+     *   {@link MessageConstraints#DEFAULT} will be used.
+     * @param incomingContentStrategy incoming content length strategy. If <code>null</code>
+     *   {@link LaxContentLengthStrategy#INSTANCE} will be used.
+     * @param outgoingContentStrategy outgoing content length strategy. If <code>null</code>
+     *   {@link StrictContentLengthStrategy#INSTANCE} will be used.
+     */
+    protected BHttpConnectionBase(
+            final int buffersize,
+            final int fragmentSizeHint,
+            final CharsetDecoder chardecoder,
+            final CharsetEncoder charencoder,
+            final MessageConstraints constraints,
+            final ContentLengthStrategy incomingContentStrategy,
+            final ContentLengthStrategy outgoingContentStrategy) {
+        super();
+        Args.positive(buffersize, "Buffer size");
+        final HttpTransportMetricsImpl inTransportMetrics = new HttpTransportMetricsImpl();
+        final HttpTransportMetricsImpl outTransportMetrics = new HttpTransportMetricsImpl();
+        this.inbuffer = new SessionInputBufferImpl(inTransportMetrics, buffersize, -1,
+                constraints != null ? constraints : MessageConstraints.DEFAULT, chardecoder);
+        this.outbuffer = new SessionOutputBufferImpl(outTransportMetrics, buffersize, fragmentSizeHint,
+                charencoder);
+        this.connMetrics = new HttpConnectionMetricsImpl(inTransportMetrics, outTransportMetrics);
+        this.incomingContentStrategy = incomingContentStrategy != null ? incomingContentStrategy :
+            LaxContentLengthStrategy.INSTANCE;
+        this.outgoingContentStrategy = outgoingContentStrategy != null ? outgoingContentStrategy :
+            StrictContentLengthStrategy.INSTANCE;
+    }
+
+    protected void ensureOpen() throws IOException {
+        Asserts.check(this.open, "Connection is not open");
+        if (!this.inbuffer.isBound()) {
+            this.inbuffer.bind(getSocketInputStream(this.socket));
+        }
+        if (!this.outbuffer.isBound()) {
+            this.outbuffer.bind(getSocketOutputStream(this.socket));
+        }
+    }
+
+    protected InputStream getSocketInputStream(final Socket socket) throws IOException {
+        return socket.getInputStream();
+    }
+
+    protected OutputStream getSocketOutputStream(final Socket socket) throws IOException {
+        return socket.getOutputStream();
+    }
+
+    /**
+     * Binds this connection to the given {@link Socket}. This socket will be
+     * used by the connection to send and receive data.
+     * <p/>
+     * After this method's execution the connection status will be reported
+     * as open and the {@link #isOpen()} will return <code>true</code>.
+     *
+     * @param socket the socket.
+     * @throws IOException in case of an I/O error.
+     */
+    protected void bind(final Socket socket) throws IOException {
+        Args.notNull(socket, "Socket");
+        this.socket = socket;
+        this.open = true;
+        this.inbuffer.bind(null);
+        this.outbuffer.bind(null);
+    }
+
+    protected SessionInputBuffer getSessionInputBuffer() {
+        return this.inbuffer;
+    }
+
+    protected SessionOutputBuffer getSessionOutputBuffer() {
+        return this.outbuffer;
+    }
+
+    protected void doFlush() throws IOException {
+        this.outbuffer.flush();
+    }
+
+    public boolean isOpen() {
+        return this.open;
+    }
+
+    protected Socket getSocket() {
+        return this.socket;
+    }
+
+    protected OutputStream createOutputStream(
+            final long len,
+            final SessionOutputBuffer outbuffer) {
+        if (len == ContentLengthStrategy.CHUNKED) {
+            return new ChunkedOutputStream(2048, outbuffer);
+        } else if (len == ContentLengthStrategy.IDENTITY) {
+            return new IdentityOutputStream(outbuffer);
+        } else {
+            return new ContentLengthOutputStream(outbuffer, len);
+        }
+    }
+
+    protected OutputStream prepareOutput(final HttpMessage message) throws HttpException {
+        final long len = this.outgoingContentStrategy.determineLength(message);
+        return createOutputStream(len, this.outbuffer);
+    }
+
+    protected InputStream createInputStream(
+            final long len,
+            final SessionInputBuffer inbuffer) {
+        if (len == ContentLengthStrategy.CHUNKED) {
+            return new ChunkedInputStream(inbuffer);
+        } else if (len == ContentLengthStrategy.IDENTITY) {
+            return new IdentityInputStream(inbuffer);
+        } else {
+            return new ContentLengthInputStream(inbuffer, len);
+        }
+    }
+
+    protected HttpEntity prepareInput(final HttpMessage message) throws HttpException {
+        final BasicHttpEntity entity = new BasicHttpEntity();
+
+        final long len = this.incomingContentStrategy.determineLength(message);
+        final InputStream instream = createInputStream(len, this.inbuffer);
+        if (len == ContentLengthStrategy.CHUNKED) {
+            entity.setChunked(true);
+            entity.setContentLength(-1);
+            entity.setContent(instream);
+        } else if (len == ContentLengthStrategy.IDENTITY) {
+            entity.setChunked(false);
+            entity.setContentLength(-1);
+            entity.setContent(instream);
+        } else {
+            entity.setChunked(false);
+            entity.setContentLength(len);
+            entity.setContent(instream);
+        }
+
+        final Header contentTypeHeader = message.getFirstHeader(HTTP.CONTENT_TYPE);
+        if (contentTypeHeader != null) {
+            entity.setContentType(contentTypeHeader);
+        }
+        final Header contentEncodingHeader = message.getFirstHeader(HTTP.CONTENT_ENCODING);
+        if (contentEncodingHeader != null) {
+            entity.setContentEncoding(contentEncodingHeader);
+        }
+        return entity;
+    }
+
+    public InetAddress getLocalAddress() {
+        if (this.socket != null) {
+            return this.socket.getLocalAddress();
+        } else {
+            return null;
+        }
+    }
+
+    public int getLocalPort() {
+        if (this.socket != null) {
+            return this.socket.getLocalPort();
+        } else {
+            return -1;
+        }
+    }
+
+    public InetAddress getRemoteAddress() {
+        if (this.socket != null) {
+            return this.socket.getInetAddress();
+        } else {
+            return null;
+        }
+    }
+
+    public int getRemotePort() {
+        if (this.socket != null) {
+            return this.socket.getPort();
+        } else {
+            return -1;
+        }
+    }
+
+    public void setSocketTimeout(final int timeout) {
+        if (this.socket != null) {
+            try {
+                this.socket.setSoTimeout(timeout);
+            } catch (final SocketException ignore) {
+                // It is not quite clear from the Sun's documentation if there are any
+                // other legitimate cases for a socket exception to be thrown when setting
+                // SO_TIMEOUT besides the socket being already closed
+            }
+        }
+    }
+
+    public int getSocketTimeout() {
+        if (this.socket != null) {
+            try {
+                return this.socket.getSoTimeout();
+            } catch (final SocketException ignore) {
+                return -1;
+            }
+        } else {
+            return -1;
+        }
+    }
+
+    public void shutdown() throws IOException {
+        this.open = false;
+        final Socket tmpsocket = this.socket;
+        if (tmpsocket != null) {
+            tmpsocket.close();
+        }
+    }
+
+    public void close() throws IOException {
+        if (!this.open) {
+            return;
+        }
+        this.open = false;
+        final Socket sock = this.socket;
+        try {
+            this.inbuffer.clear();
+            this.outbuffer.flush();
+            try {
+                try {
+                    sock.shutdownOutput();
+                } catch (final IOException ignore) {
+                }
+                try {
+                    sock.shutdownInput();
+                } catch (final IOException ignore) {
+                }
+            } catch (final UnsupportedOperationException ignore) {
+                // if one isn't supported, the other one isn't either
+            }
+        } finally {
+            sock.close();
+        }
+    }
+
+    private int fillInputBuffer(final int timeout) throws IOException {
+        final int oldtimeout = this.socket.getSoTimeout();
+        try {
+            this.socket.setSoTimeout(timeout);
+            return this.inbuffer.fillBuffer();
+        } finally {
+            this.socket.setSoTimeout(oldtimeout);
+        }
+    }
+
+    protected boolean awaitInput(final int timeout) throws IOException {
+        if (this.inbuffer.hasBufferedData()) {
+            return true;
+        }
+        fillInputBuffer(timeout);
+        return this.inbuffer.hasBufferedData();
+    }
+
+    public boolean isStale() {
+        if (!isOpen()) {
+            return true;
+        }
+        try {
+            final int bytesRead = fillInputBuffer(1);
+            return bytesRead < 0;
+        } catch (final SocketTimeoutException ex) {
+            return false;
+        } catch (final IOException ex) {
+            return true;
+        }
+    }
+
+    protected void incrementRequestCount() {
+        this.connMetrics.incrementRequestCount();
+    }
+
+    protected void incrementResponseCount() {
+        this.connMetrics.incrementResponseCount();
+    }
+
+    public HttpConnectionMetrics getMetrics() {
+        return this.connMetrics;
+    }
+
+    @Override
+    public String toString() {
+        if (this.socket != null) {
+            final StringBuilder buffer = new StringBuilder();
+            final SocketAddress remoteAddress = this.socket.getRemoteSocketAddress();
+            final SocketAddress localAddress = this.socket.getLocalSocketAddress();
+            if (remoteAddress != null && localAddress != null) {
+                NetUtils.formatAddress(buffer, localAddress);
+                buffer.append("<->");
+                NetUtils.formatAddress(buffer, remoteAddress);
+            }
+            return buffer.toString();
+        } else {
+            return "[Not bound]";
+        }
+    }
+
+}
diff --git a/httpcore/src/main/java/org/apache/http/impl/ConnSupport.java b/httpcore/src/main/java/org/apache/http/impl/ConnSupport.java
new file mode 100644
index 0000000..a957629
--- /dev/null
+++ b/httpcore/src/main/java/org/apache/http/impl/ConnSupport.java
@@ -0,0 +1,75 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+package org.apache.http.impl;
+
+import org.apache.http.config.ConnectionConfig;
+
+import java.nio.charset.Charset;
+import java.nio.charset.CharsetDecoder;
+import java.nio.charset.CharsetEncoder;
+import java.nio.charset.CodingErrorAction;
+
+/**
+ * Connection support methods.
+ *
+ * @since 4.3
+ */
+public final class ConnSupport {
+
+    public static CharsetDecoder createDecoder(final ConnectionConfig cconfig) {
+        if (cconfig == null) {
+            return null;
+        }
+        final Charset charset = cconfig.getCharset();
+        final CodingErrorAction malformed = cconfig.getMalformedInputAction();
+        final CodingErrorAction unmappable = cconfig.getUnmappableInputAction();
+        if (charset != null) {
+            return charset.newDecoder()
+                    .onMalformedInput(malformed != null ? malformed : CodingErrorAction.REPORT)
+                    .onUnmappableCharacter(unmappable != null ? unmappable: CodingErrorAction.REPORT);
+        } else {
+            return null;
+        }
+    }
+
+    public static CharsetEncoder createEncoder(final ConnectionConfig cconfig) {
+        if (cconfig == null) {
+            return null;
+        }
+        final Charset charset = cconfig.getCharset();
+        if (charset != null) {
+            final CodingErrorAction malformed = cconfig.getMalformedInputAction();
+            final CodingErrorAction unmappable = cconfig.getUnmappableInputAction();
+            return charset.newEncoder()
+                .onMalformedInput(malformed != null ? malformed : CodingErrorAction.REPORT)
+                .onUnmappableCharacter(unmappable != null ? unmappable: CodingErrorAction.REPORT);
+        } else {
+            return null;
+        }
+    }
+
+}
diff --git a/httpcore/src/main/java/org/apache/http/impl/DefaultBHttpClientConnection.java b/httpcore/src/main/java/org/apache/http/impl/DefaultBHttpClientConnection.java
new file mode 100644
index 0000000..2e333aa
--- /dev/null
+++ b/httpcore/src/main/java/org/apache/http/impl/DefaultBHttpClientConnection.java
@@ -0,0 +1,182 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+
+package org.apache.http.impl;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.net.Socket;
+import java.net.SocketTimeoutException;
+import java.nio.charset.CharsetDecoder;
+import java.nio.charset.CharsetEncoder;
+
+import org.apache.http.HttpClientConnection;
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpEntityEnclosingRequest;
+import org.apache.http.HttpException;
+import org.apache.http.HttpRequest;
+import org.apache.http.HttpResponse;
+import org.apache.http.HttpStatus;
+import org.apache.http.annotation.NotThreadSafe;
+import org.apache.http.config.MessageConstraints;
+import org.apache.http.entity.ContentLengthStrategy;
+import org.apache.http.impl.io.DefaultHttpRequestWriterFactory;
+import org.apache.http.impl.io.DefaultHttpResponseParserFactory;
+import org.apache.http.io.HttpMessageParser;
+import org.apache.http.io.HttpMessageParserFactory;
+import org.apache.http.io.HttpMessageWriter;
+import org.apache.http.io.HttpMessageWriterFactory;
+import org.apache.http.util.Args;
+
+/**
+ * Default implementation of {@link HttpClientConnection}.
+ *
+ * @since 4.3
+ */
+ at NotThreadSafe
+public class DefaultBHttpClientConnection extends BHttpConnectionBase
+                                                   implements HttpClientConnection {
+
+    private final HttpMessageParser<HttpResponse> responseParser;
+    private final HttpMessageWriter<HttpRequest> requestWriter;
+
+    /**
+     * Creates new instance of DefaultBHttpClientConnection.
+     *
+     * @param buffersize buffer size. Must be a positive number.
+     * @param fragmentSizeHint fragment size hint.
+     * @param chardecoder decoder to be used for decoding HTTP protocol elements.
+     *   If <code>null</code> simple type cast will be used for byte to char conversion.
+     * @param charencoder encoder to be used for encoding HTTP protocol elements.
+     *   If <code>null</code> simple type cast will be used for char to byte conversion.
+     * @param constraints Message constraints. If <code>null</code>
+     *   {@link MessageConstraints#DEFAULT} will be used.
+     * @param incomingContentStrategy incoming content length strategy. If <code>null</code>
+     *   {@link org.apache.http.impl.entity.LaxContentLengthStrategy#INSTANCE} will be used.
+     * @param outgoingContentStrategy outgoing content length strategy. If <code>null</code>
+     *   {@link org.apache.http.impl.entity.StrictContentLengthStrategy#INSTANCE} will be used.
+     * @param requestWriterFactory request writer factory. If <code>null</code>
+     *   {@link DefaultHttpRequestWriterFactory#INSTANCE} will be used.
+     * @param responseParserFactory response parser factory. If <code>null</code>
+     *   {@link DefaultHttpResponseParserFactory#INSTANCE} will be used.
+     */
+    public DefaultBHttpClientConnection(
+            final int buffersize,
+            final int fragmentSizeHint,
+            final CharsetDecoder chardecoder,
+            final CharsetEncoder charencoder,
+            final MessageConstraints constraints,
+            final ContentLengthStrategy incomingContentStrategy,
+            final ContentLengthStrategy outgoingContentStrategy,
+            final HttpMessageWriterFactory<HttpRequest> requestWriterFactory,
+            final HttpMessageParserFactory<HttpResponse> responseParserFactory) {
+        super(buffersize, fragmentSizeHint, chardecoder, charencoder,
+                constraints, incomingContentStrategy, outgoingContentStrategy);
+        this.requestWriter = (requestWriterFactory != null ? requestWriterFactory :
+            DefaultHttpRequestWriterFactory.INSTANCE).create(getSessionOutputBuffer());
+        this.responseParser = (responseParserFactory != null ? responseParserFactory :
+            DefaultHttpResponseParserFactory.INSTANCE).create(getSessionInputBuffer(), constraints);
+    }
+
+    public DefaultBHttpClientConnection(
+            final int buffersize,
+            final CharsetDecoder chardecoder,
+            final CharsetEncoder charencoder,
+            final MessageConstraints constraints) {
+        this(buffersize, buffersize, chardecoder, charencoder, constraints, null, null, null, null);
+    }
+
+    public DefaultBHttpClientConnection(final int buffersize) {
+        this(buffersize, buffersize, null, null, null, null, null, null, null);
+    }
+
+    protected void onResponseReceived(final HttpResponse response) {
+    }
+
+    protected void onRequestSubmitted(final HttpRequest request) {
+    }
+
+    @Override
+    public void bind(final Socket socket) throws IOException {
+        super.bind(socket);
+    }
+
+    public boolean isResponseAvailable(final int timeout) throws IOException {
+        ensureOpen();
+        try {
+            return awaitInput(timeout);
+        } catch (final SocketTimeoutException ex) {
+            return false;
+        }
+    }
+
+    public void sendRequestHeader(final HttpRequest request)
+            throws HttpException, IOException {
+        Args.notNull(request, "HTTP request");
+        ensureOpen();
+        this.requestWriter.write(request);
+        onRequestSubmitted(request);
+        incrementRequestCount();
+    }
+
+    public void sendRequestEntity(final HttpEntityEnclosingRequest request)
+            throws HttpException, IOException {
+        Args.notNull(request, "HTTP request");
+        ensureOpen();
+        final HttpEntity entity = request.getEntity();
+        if (entity == null) {
+            return;
+        }
+        final OutputStream outstream = prepareOutput(request);
+        entity.writeTo(outstream);
+        outstream.close();
+    }
+
+    public HttpResponse receiveResponseHeader() throws HttpException, IOException {
+        ensureOpen();
+        final HttpResponse response = this.responseParser.parse();
+        onResponseReceived(response);
+        if (response.getStatusLine().getStatusCode() >= HttpStatus.SC_OK) {
+            incrementResponseCount();
+        }
+        return response;
+    }
+
+    public void receiveResponseEntity(
+            final HttpResponse response) throws HttpException, IOException {
+        Args.notNull(response, "HTTP response");
+        ensureOpen();
+        final HttpEntity entity = prepareInput(response);
+        response.setEntity(entity);
+    }
+
+    public void flush() throws IOException {
+        ensureOpen();
+        doFlush();
+    }
+
+}
diff --git a/httpcore/src/main/java/org/apache/http/impl/DefaultBHttpClientConnectionFactory.java b/httpcore/src/main/java/org/apache/http/impl/DefaultBHttpClientConnectionFactory.java
new file mode 100644
index 0000000..f44be11
--- /dev/null
+++ b/httpcore/src/main/java/org/apache/http/impl/DefaultBHttpClientConnectionFactory.java
@@ -0,0 +1,103 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+
+package org.apache.http.impl;
+
+import org.apache.http.HttpConnectionFactory;
+import org.apache.http.HttpRequest;
+import org.apache.http.HttpResponse;
+import org.apache.http.annotation.Immutable;
+import org.apache.http.config.ConnectionConfig;
+import org.apache.http.entity.ContentLengthStrategy;
+import org.apache.http.io.HttpMessageParserFactory;
+import org.apache.http.io.HttpMessageWriterFactory;
+
+import java.io.IOException;
+import java.net.Socket;
+
+/**
+ * Default factory for {@link org.apache.http.HttpClientConnection}s.
+ *
+ * @since 4.3
+ */
+ at Immutable
+public class DefaultBHttpClientConnectionFactory
+        implements HttpConnectionFactory<DefaultBHttpClientConnection> {
+
+    public static final DefaultBHttpClientConnectionFactory INSTANCE = new DefaultBHttpClientConnectionFactory();
+
+    private final ConnectionConfig cconfig;
+    private final ContentLengthStrategy incomingContentStrategy;
+    private final ContentLengthStrategy outgoingContentStrategy;
+    private final HttpMessageWriterFactory<HttpRequest> requestWriterFactory;
+    private final HttpMessageParserFactory<HttpResponse> responseParserFactory;
+
+    public DefaultBHttpClientConnectionFactory(
+            final ConnectionConfig cconfig,
+            final ContentLengthStrategy incomingContentStrategy,
+            final ContentLengthStrategy outgoingContentStrategy,
+            final HttpMessageWriterFactory<HttpRequest> requestWriterFactory,
+            final HttpMessageParserFactory<HttpResponse> responseParserFactory) {
+        super();
+        this.cconfig = cconfig != null ? cconfig : ConnectionConfig.DEFAULT;
+        this.incomingContentStrategy = incomingContentStrategy;
+        this.outgoingContentStrategy = outgoingContentStrategy;
+        this.requestWriterFactory = requestWriterFactory;
+        this.responseParserFactory = responseParserFactory;
+    }
+
+    public DefaultBHttpClientConnectionFactory(
+            final ConnectionConfig cconfig,
+            final HttpMessageWriterFactory<HttpRequest> requestWriterFactory,
+            final HttpMessageParserFactory<HttpResponse> responseParserFactory) {
+        this(cconfig, null, null, requestWriterFactory, responseParserFactory);
+    }
+
+    public DefaultBHttpClientConnectionFactory(final ConnectionConfig cconfig) {
+        this(cconfig, null, null, null, null);
+    }
+
+    public DefaultBHttpClientConnectionFactory() {
+        this(null, null, null, null, null);
+    }
+
+    public DefaultBHttpClientConnection createConnection(final Socket socket) throws IOException {
+        final DefaultBHttpClientConnection conn = new DefaultBHttpClientConnection(
+                this.cconfig.getBufferSize(),
+                this.cconfig.getFragmentSizeHint(),
+                ConnSupport.createDecoder(this.cconfig),
+                ConnSupport.createEncoder(this.cconfig),
+                this.cconfig.getMessageConstraints(),
+                this.incomingContentStrategy,
+                this.outgoingContentStrategy,
+                this.requestWriterFactory,
+                this.responseParserFactory);
+        conn.bind(socket);
+        return conn;
+    }
+
+}
diff --git a/httpcore/src/main/java/org/apache/http/impl/DefaultBHttpServerConnection.java b/httpcore/src/main/java/org/apache/http/impl/DefaultBHttpServerConnection.java
new file mode 100644
index 0000000..b76a424
--- /dev/null
+++ b/httpcore/src/main/java/org/apache/http/impl/DefaultBHttpServerConnection.java
@@ -0,0 +1,174 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+
+package org.apache.http.impl;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.net.Socket;
+import java.nio.charset.CharsetDecoder;
+import java.nio.charset.CharsetEncoder;
+
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpEntityEnclosingRequest;
+import org.apache.http.HttpException;
+import org.apache.http.HttpRequest;
+import org.apache.http.HttpResponse;
+import org.apache.http.HttpServerConnection;
+import org.apache.http.annotation.NotThreadSafe;
+import org.apache.http.config.MessageConstraints;
+import org.apache.http.entity.ContentLengthStrategy;
+import org.apache.http.impl.entity.DisallowIdentityContentLengthStrategy;
+import org.apache.http.impl.io.DefaultHttpRequestParserFactory;
+import org.apache.http.impl.io.DefaultHttpResponseWriterFactory;
+import org.apache.http.io.HttpMessageParser;
+import org.apache.http.io.HttpMessageParserFactory;
+import org.apache.http.io.HttpMessageWriter;
+import org.apache.http.io.HttpMessageWriterFactory;
+import org.apache.http.util.Args;
+
+/**
+ * Default implementation of {@link HttpServerConnection}.
+ *
+ * @since 4.3
+ */
+ at NotThreadSafe
+public class DefaultBHttpServerConnection extends BHttpConnectionBase
+                                                   implements HttpServerConnection {
+
+    private final HttpMessageParser<HttpRequest> requestParser;
+    private final HttpMessageWriter<HttpResponse> responseWriter;
+
+    /**
+     * Creates new instance of DefaultBHttpServerConnection.
+     *
+     * @param buffersize buffer size. Must be a positive number.
+     * @param fragmentSizeHint fragment size hint.
+     * @param chardecoder decoder to be used for decoding HTTP protocol elements.
+     *   If <code>null</code> simple type cast will be used for byte to char conversion.
+     * @param charencoder encoder to be used for encoding HTTP protocol elements.
+     *   If <code>null</code> simple type cast will be used for char to byte conversion.
+     * @param constraints Message constraints. If <code>null</code>
+     *   {@link MessageConstraints#DEFAULT} will be used.
+     * @param incomingContentStrategy incoming content length strategy. If <code>null</code>
+     *   {@link DisallowIdentityContentLengthStrategy#INSTANCE} will be used.
+     * @param outgoingContentStrategy outgoing content length strategy. If <code>null</code>
+     *   {@link org.apache.http.impl.entity.StrictContentLengthStrategy#INSTANCE} will be used.
+     * @param requestParserFactory request parser factory. If <code>null</code>
+     *   {@link DefaultHttpRequestParserFactory#INSTANCE} will be used.
+     * @param responseWriterFactory response writer factory. If <code>null</code>
+     *   {@link DefaultHttpResponseWriterFactory#INSTANCE} will be used.
+     */
+    public DefaultBHttpServerConnection(
+            final int buffersize,
+            final int fragmentSizeHint,
+            final CharsetDecoder chardecoder,
+            final CharsetEncoder charencoder,
+            final MessageConstraints constraints,
+            final ContentLengthStrategy incomingContentStrategy,
+            final ContentLengthStrategy outgoingContentStrategy,
+            final HttpMessageParserFactory<HttpRequest> requestParserFactory,
+            final HttpMessageWriterFactory<HttpResponse> responseWriterFactory) {
+        super(buffersize, fragmentSizeHint, chardecoder, charencoder, constraints,
+                incomingContentStrategy != null ? incomingContentStrategy :
+                    DisallowIdentityContentLengthStrategy.INSTANCE, outgoingContentStrategy);
+        this.requestParser = (requestParserFactory != null ? requestParserFactory :
+            DefaultHttpRequestParserFactory.INSTANCE).create(getSessionInputBuffer(), constraints);
+        this.responseWriter = (responseWriterFactory != null ? responseWriterFactory :
+            DefaultHttpResponseWriterFactory.INSTANCE).create(getSessionOutputBuffer());
+    }
+
+    public DefaultBHttpServerConnection(
+            final int buffersize,
+            final CharsetDecoder chardecoder,
+            final CharsetEncoder charencoder,
+            final MessageConstraints constraints) {
+        this(buffersize, buffersize, chardecoder, charencoder, constraints, null, null, null, null);
+    }
+
+    public DefaultBHttpServerConnection(final int buffersize) {
+        this(buffersize, buffersize, null, null, null, null, null, null, null);
+    }
+
+    protected void onRequestReceived(final HttpRequest request) {
+    }
+
+    protected void onResponseSubmitted(final HttpResponse response) {
+    }
+
+    @Override
+    public void bind(final Socket socket) throws IOException {
+        super.bind(socket);
+    }
+
+    public HttpRequest receiveRequestHeader()
+            throws HttpException, IOException {
+        ensureOpen();
+        final HttpRequest request = this.requestParser.parse();
+        onRequestReceived(request);
+        incrementRequestCount();
+        return request;
+    }
+
+    public void receiveRequestEntity(final HttpEntityEnclosingRequest request)
+            throws HttpException, IOException {
+        Args.notNull(request, "HTTP request");
+        ensureOpen();
+        final HttpEntity entity = prepareInput(request);
+        request.setEntity(entity);
+    }
+
+    public void sendResponseHeader(final HttpResponse response)
+            throws HttpException, IOException {
+        Args.notNull(response, "HTTP response");
+        ensureOpen();
+        this.responseWriter.write(response);
+        onResponseSubmitted(response);
+        if (response.getStatusLine().getStatusCode() >= 200) {
+            incrementResponseCount();
+        }
+    }
+
+    public void sendResponseEntity(final HttpResponse response)
+            throws HttpException, IOException {
+        Args.notNull(response, "HTTP response");
+        ensureOpen();
+        final HttpEntity entity = response.getEntity();
+        if (entity == null) {
+            return;
+        }
+        final OutputStream outstream = prepareOutput(response);
+        entity.writeTo(outstream);
+        outstream.close();
+    }
+
+    public void flush() throws IOException {
+        ensureOpen();
+        doFlush();
+    }
+
+}
diff --git a/httpcore/src/main/java/org/apache/http/impl/DefaultBHttpServerConnectionFactory.java b/httpcore/src/main/java/org/apache/http/impl/DefaultBHttpServerConnectionFactory.java
new file mode 100644
index 0000000..b944b3d
--- /dev/null
+++ b/httpcore/src/main/java/org/apache/http/impl/DefaultBHttpServerConnectionFactory.java
@@ -0,0 +1,103 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+
+package org.apache.http.impl;
+
+import org.apache.http.HttpConnectionFactory;
+import org.apache.http.HttpRequest;
+import org.apache.http.HttpResponse;
+import org.apache.http.annotation.Immutable;
+import org.apache.http.config.ConnectionConfig;
+import org.apache.http.entity.ContentLengthStrategy;
+import org.apache.http.io.HttpMessageParserFactory;
+import org.apache.http.io.HttpMessageWriterFactory;
+
+import java.io.IOException;
+import java.net.Socket;
+
+/**
+ * Default factory for {@link org.apache.http.HttpServerConnection}s.
+ *
+ * @since 4.3
+ */
+ at Immutable
+public class DefaultBHttpServerConnectionFactory
+        implements HttpConnectionFactory<DefaultBHttpServerConnection> {
+
+    public static final DefaultBHttpServerConnectionFactory INSTANCE = new DefaultBHttpServerConnectionFactory();
+
+    private final ConnectionConfig cconfig;
+    private final ContentLengthStrategy incomingContentStrategy;
+    private final ContentLengthStrategy outgoingContentStrategy;
+    private final HttpMessageParserFactory<HttpRequest> requestParserFactory;
+    private final HttpMessageWriterFactory<HttpResponse> responseWriterFactory;
+
+    public DefaultBHttpServerConnectionFactory(
+            final ConnectionConfig cconfig,
+            final ContentLengthStrategy incomingContentStrategy,
+            final ContentLengthStrategy outgoingContentStrategy,
+            final HttpMessageParserFactory<HttpRequest> requestParserFactory,
+            final HttpMessageWriterFactory<HttpResponse> responseWriterFactory) {
+        super();
+        this.cconfig = cconfig != null ? cconfig : ConnectionConfig.DEFAULT;
+        this.incomingContentStrategy = incomingContentStrategy;
+        this.outgoingContentStrategy = outgoingContentStrategy;
+        this.requestParserFactory = requestParserFactory;
+        this.responseWriterFactory = responseWriterFactory;
+    }
+
+    public DefaultBHttpServerConnectionFactory(
+            final ConnectionConfig cconfig,
+            final HttpMessageParserFactory<HttpRequest> requestParserFactory,
+            final HttpMessageWriterFactory<HttpResponse> responseWriterFactory) {
+        this(cconfig, null, null, requestParserFactory, responseWriterFactory);
+    }
+
+    public DefaultBHttpServerConnectionFactory(final ConnectionConfig cconfig) {
+        this(cconfig, null, null, null, null);
+    }
+
+    public DefaultBHttpServerConnectionFactory() {
+        this(null, null, null, null, null);
+    }
+
+    public DefaultBHttpServerConnection createConnection(final Socket socket) throws IOException {
+        final DefaultBHttpServerConnection conn = new DefaultBHttpServerConnection(
+                this.cconfig.getBufferSize(),
+                this.cconfig.getFragmentSizeHint(),
+                ConnSupport.createDecoder(this.cconfig),
+                ConnSupport.createEncoder(this.cconfig),
+                this.cconfig.getMessageConstraints(),
+                this.incomingContentStrategy,
+                this.outgoingContentStrategy,
+                this.requestParserFactory,
+                this.responseWriterFactory);
+        conn.bind(socket);
+        return conn;
+    }
+
+}
diff --git a/httpcore/src/main/java/org/apache/http/impl/DefaultConnectionReuseStrategy.java b/httpcore/src/main/java/org/apache/http/impl/DefaultConnectionReuseStrategy.java
index a7c6b60..a8bc914 100644
--- a/httpcore/src/main/java/org/apache/http/impl/DefaultConnectionReuseStrategy.java
+++ b/httpcore/src/main/java/org/apache/http/impl/DefaultConnectionReuseStrategy.java
@@ -35,11 +35,12 @@ import org.apache.http.HttpStatus;
 import org.apache.http.HttpVersion;
 import org.apache.http.ParseException;
 import org.apache.http.ProtocolVersion;
-import org.apache.http.protocol.HTTP;
-import org.apache.http.protocol.HttpContext;
 import org.apache.http.TokenIterator;
 import org.apache.http.annotation.Immutable;
 import org.apache.http.message.BasicTokenIterator;
+import org.apache.http.protocol.HTTP;
+import org.apache.http.protocol.HttpContext;
+import org.apache.http.util.Args;
 
 /**
  * Default implementation of a strategy deciding about connection re-use.
@@ -62,6 +63,8 @@ import org.apache.http.message.BasicTokenIterator;
 @Immutable
 public class DefaultConnectionReuseStrategy implements ConnectionReuseStrategy {
 
+    public static final DefaultConnectionReuseStrategy INSTANCE = new DefaultConnectionReuseStrategy();
+
     public DefaultConnectionReuseStrategy() {
         super();
     }
@@ -69,35 +72,29 @@ public class DefaultConnectionReuseStrategy implements ConnectionReuseStrategy {
     // see interface ConnectionReuseStrategy
     public boolean keepAlive(final HttpResponse response,
                              final HttpContext context) {
-        if (response == null) {
-            throw new IllegalArgumentException
-                ("HTTP response may not be null.");
-        }
-        if (context == null) {
-            throw new IllegalArgumentException
-                ("HTTP context may not be null.");
-        }
+        Args.notNull(response, "HTTP response");
+        Args.notNull(context, "HTTP context");
 
         // Check for a self-terminating entity. If the end of the entity will
         // be indicated by closing the connection, there is no keep-alive.
-        ProtocolVersion ver = response.getStatusLine().getProtocolVersion();
-        Header teh = response.getFirstHeader(HTTP.TRANSFER_ENCODING);
+        final ProtocolVersion ver = response.getStatusLine().getProtocolVersion();
+        final Header teh = response.getFirstHeader(HTTP.TRANSFER_ENCODING);
         if (teh != null) {
             if (!HTTP.CHUNK_CODING.equalsIgnoreCase(teh.getValue())) {
                 return false;
             }
         } else {
             if (canResponseHaveBody(response)) {
-                Header[] clhs = response.getHeaders(HTTP.CONTENT_LEN);
+                final Header[] clhs = response.getHeaders(HTTP.CONTENT_LEN);
                 // Do not reuse if not properly content-length delimited
                 if (clhs.length == 1) {
-                    Header clh = clhs[0];
+                    final Header clh = clhs[0];
                     try {
-                        int contentLen = Integer.parseInt(clh.getValue());
+                        final int contentLen = Integer.parseInt(clh.getValue());
                         if (contentLen < 0) {
                             return false;
                         }
-                    } catch (NumberFormatException ex) {
+                    } catch (final NumberFormatException ex) {
                         return false;
                     }
                 } else {
@@ -110,8 +107,9 @@ public class DefaultConnectionReuseStrategy implements ConnectionReuseStrategy {
         // the "Proxy-Connection" header. The latter is an unspecified and
         // broken but unfortunately common extension of HTTP.
         HeaderIterator hit = response.headerIterator(HTTP.CONN_DIRECTIVE);
-        if (!hit.hasNext())
+        if (!hit.hasNext()) {
             hit = response.headerIterator("Proxy-Connection");
+        }
 
         // Experimental usage of the "Connection" header in HTTP/1.0 is
         // documented in RFC 2068, section 19.7.1. A token "keep-alive" is
@@ -138,7 +136,7 @@ public class DefaultConnectionReuseStrategy implements ConnectionReuseStrategy {
 
         if (hit.hasNext()) {
             try {
-                TokenIterator ti = createTokenIterator(hit);
+                final TokenIterator ti = createTokenIterator(hit);
                 boolean keepalive = false;
                 while (ti.hasNext()) {
                     final String token = ti.nextToken();
@@ -150,10 +148,12 @@ public class DefaultConnectionReuseStrategy implements ConnectionReuseStrategy {
                     }
                 }
                 if (keepalive)
+                 {
                     return true;
                 // neither "close" nor "keep-alive", use default policy
+                }
 
-            } catch (ParseException px) {
+            } catch (final ParseException px) {
                 // invalid connection header means no persistent connection
                 // we don't have logging in HttpCore, so the exception is lost
                 return false;
@@ -174,12 +174,12 @@ public class DefaultConnectionReuseStrategy implements ConnectionReuseStrategy {
      *
      * @return  the token iterator
      */
-    protected TokenIterator createTokenIterator(HeaderIterator hit) {
+    protected TokenIterator createTokenIterator(final HeaderIterator hit) {
         return new BasicTokenIterator(hit);
     }
 
     private boolean canResponseHaveBody(final HttpResponse response) {
-        int status = response.getStatusLine().getStatusCode();
+        final int status = response.getStatusLine().getStatusCode();
         return status >= HttpStatus.SC_OK
             && status != HttpStatus.SC_NO_CONTENT
             && status != HttpStatus.SC_NOT_MODIFIED
diff --git a/httpcore/src/main/java/org/apache/http/impl/DefaultHttpRequestFactory.java b/httpcore/src/main/java/org/apache/http/impl/DefaultHttpRequestFactory.java
index d134bf7..0f89ac9 100644
--- a/httpcore/src/main/java/org/apache/http/impl/DefaultHttpRequestFactory.java
+++ b/httpcore/src/main/java/org/apache/http/impl/DefaultHttpRequestFactory.java
@@ -34,6 +34,7 @@ import org.apache.http.RequestLine;
 import org.apache.http.annotation.Immutable;
 import org.apache.http.message.BasicHttpEntityEnclosingRequest;
 import org.apache.http.message.BasicHttpRequest;
+import org.apache.http.util.Args;
 
 /**
  * Default factory for creating {@link HttpRequest} objects.
@@ -43,6 +44,8 @@ import org.apache.http.message.BasicHttpRequest;
 @Immutable
 public class DefaultHttpRequestFactory implements HttpRequestFactory {
 
+    public static final DefaultHttpRequestFactory INSTANCE = new DefaultHttpRequestFactory();
+
     private static final String[] RFC2616_COMMON_METHODS = {
         "GET"
     };
@@ -66,8 +69,8 @@ public class DefaultHttpRequestFactory implements HttpRequestFactory {
     }
 
     private static boolean isOneOf(final String[] methods, final String method) {
-        for (int i = 0; i < methods.length; i++) {
-            if (methods[i].equalsIgnoreCase(method)) {
+        for (final String method2 : methods) {
+            if (method2.equalsIgnoreCase(method)) {
                 return true;
             }
         }
@@ -76,10 +79,8 @@ public class DefaultHttpRequestFactory implements HttpRequestFactory {
 
     public HttpRequest newHttpRequest(final RequestLine requestline)
             throws MethodNotSupportedException {
-        if (requestline == null) {
-            throw new IllegalArgumentException("Request line may not be null");
-        }
-        String method = requestline.getMethod();
+        Args.notNull(requestline, "Request line");
+        final String method = requestline.getMethod();
         if (isOneOf(RFC2616_COMMON_METHODS, method)) {
             return new BasicHttpRequest(requestline);
         } else if (isOneOf(RFC2616_ENTITY_ENC_METHODS, method)) {
diff --git a/httpcore/src/main/java/org/apache/http/impl/DefaultHttpResponseFactory.java b/httpcore/src/main/java/org/apache/http/impl/DefaultHttpResponseFactory.java
index 9519b5b..613d10d 100644
--- a/httpcore/src/main/java/org/apache/http/impl/DefaultHttpResponseFactory.java
+++ b/httpcore/src/main/java/org/apache/http/impl/DefaultHttpResponseFactory.java
@@ -32,13 +32,13 @@ import java.util.Locale;
 import org.apache.http.HttpResponse;
 import org.apache.http.HttpResponseFactory;
 import org.apache.http.ProtocolVersion;
+import org.apache.http.ReasonPhraseCatalog;
 import org.apache.http.StatusLine;
+import org.apache.http.annotation.Immutable;
 import org.apache.http.message.BasicHttpResponse;
 import org.apache.http.message.BasicStatusLine;
 import org.apache.http.protocol.HttpContext;
-import org.apache.http.ReasonPhraseCatalog;
-import org.apache.http.annotation.Immutable;
-import org.apache.http.impl.EnglishReasonPhraseCatalog;
+import org.apache.http.util.Args;
 
 /**
  * Default factory for creating {@link HttpResponse} objects.
@@ -48,6 +48,8 @@ import org.apache.http.impl.EnglishReasonPhraseCatalog;
 @Immutable
 public class DefaultHttpResponseFactory implements HttpResponseFactory {
 
+    public static final DefaultHttpResponseFactory INSTANCE = new DefaultHttpResponseFactory();
+
     /** The catalog for looking up reason phrases. */
     protected final ReasonPhraseCatalog reasonCatalog;
 
@@ -57,12 +59,8 @@ public class DefaultHttpResponseFactory implements HttpResponseFactory {
      *
      * @param catalog   the catalog of reason phrases
      */
-    public DefaultHttpResponseFactory(ReasonPhraseCatalog catalog) {
-        if (catalog == null) {
-            throw new IllegalArgumentException
-                ("Reason phrase catalog must not be null.");
-        }
-        this.reasonCatalog = catalog;
+    public DefaultHttpResponseFactory(final ReasonPhraseCatalog catalog) {
+        this.reasonCatalog = Args.notNull(catalog, "Reason phrase catalog");
     }
 
     /**
@@ -75,30 +73,26 @@ public class DefaultHttpResponseFactory implements HttpResponseFactory {
 
 
     // non-javadoc, see interface HttpResponseFactory
-    public HttpResponse newHttpResponse(final ProtocolVersion ver,
-                                        final int status,
-                                        HttpContext context) {
-        if (ver == null) {
-            throw new IllegalArgumentException("HTTP version may not be null");
-        }
-        final Locale loc      = determineLocale(context);
+    public HttpResponse newHttpResponse(
+            final ProtocolVersion ver,
+            final int status,
+            final HttpContext context) {
+        Args.notNull(ver, "HTTP version");
+        final Locale loc = determineLocale(context);
         final String reason   = reasonCatalog.getReason(status, loc);
-        StatusLine statusline = new BasicStatusLine(ver, status, reason);
-        return new BasicHttpResponse(statusline, reasonCatalog, loc);
+        final StatusLine statusline = new BasicStatusLine(ver, status, reason);
+        return new BasicHttpResponse(statusline);
     }
 
 
     // non-javadoc, see interface HttpResponseFactory
-    public HttpResponse newHttpResponse(final StatusLine statusline,
-                                        HttpContext context) {
-        if (statusline == null) {
-            throw new IllegalArgumentException("Status line may not be null");
-        }
-        final Locale loc = determineLocale(context);
-        return new BasicHttpResponse(statusline, reasonCatalog, loc);
+    public HttpResponse newHttpResponse(
+            final StatusLine statusline,
+            final HttpContext context) {
+        Args.notNull(statusline, "Status line");
+        return new BasicHttpResponse(statusline);
     }
 
-
     /**
      * Determines the locale of the response.
      * The implementation in this class always returns the default locale.
@@ -108,7 +102,8 @@ public class DefaultHttpResponseFactory implements HttpResponseFactory {
      *
      * @return  the locale for the response, never <code>null</code>
      */
-    protected Locale determineLocale(HttpContext context) {
+    protected Locale determineLocale(final HttpContext context) {
         return Locale.getDefault();
     }
+
 }
diff --git a/httpcore/src/main/java/org/apache/http/impl/EnglishReasonPhraseCatalog.java b/httpcore/src/main/java/org/apache/http/impl/EnglishReasonPhraseCatalog.java
index 402df72..1f590dc 100644
--- a/httpcore/src/main/java/org/apache/http/impl/EnglishReasonPhraseCatalog.java
+++ b/httpcore/src/main/java/org/apache/http/impl/EnglishReasonPhraseCatalog.java
@@ -32,6 +32,7 @@ import java.util.Locale;
 import org.apache.http.HttpStatus;
 import org.apache.http.ReasonPhraseCatalog;
 import org.apache.http.annotation.Immutable;
+import org.apache.http.util.Args;
 
 /**
  * English reason phrases for HTTP status codes.
@@ -71,18 +72,15 @@ public class EnglishReasonPhraseCatalog implements ReasonPhraseCatalog {
      *
      * @return  the reason phrase, or <code>null</code>
      */
-    public String getReason(int status, Locale loc) {
-        if ((status < 100) || (status >= 600)) {
-            throw new IllegalArgumentException
-                ("Unknown category for status code " + status + ".");
-        }
-
+    public String getReason(final int status, final Locale loc) {
+        Args.check(status >= 100 && status < 600, "Unknown category for status code " + status);
         final int category = status / 100;
         final int subcode  = status - 100*category;
 
         String reason = null;
-        if (REASON_PHRASES[category].length > subcode)
+        if (REASON_PHRASES[category].length > subcode) {
             reason = REASON_PHRASES[category][subcode];
+        }
 
         return reason;
     }
@@ -107,7 +105,7 @@ public class EnglishReasonPhraseCatalog implements ReasonPhraseCatalog {
      * @param status    the status code for which to define the phrase
      * @param reason    the reason phrase for this status code
      */
-    private static void setReason(int status, String reason) {
+    private static void setReason(final int status, final String reason) {
         final int category = status / 100;
         final int subcode  = status - 100*category;
         REASON_PHRASES[category][subcode] = reason;
diff --git a/httpcore/src/main/java/org/apache/http/impl/HttpConnectionMetricsImpl.java b/httpcore/src/main/java/org/apache/http/impl/HttpConnectionMetricsImpl.java
index bcc259a..7c794f8 100644
--- a/httpcore/src/main/java/org/apache/http/impl/HttpConnectionMetricsImpl.java
+++ b/httpcore/src/main/java/org/apache/http/impl/HttpConnectionMetricsImpl.java
@@ -106,18 +106,18 @@ public class HttpConnectionMetricsImpl implements HttpConnectionMetrics {
         }
         if (value == null) {
             if (REQUEST_COUNT.equals(metricName)) {
-                value = new Long(requestCount);
+                value = Long.valueOf(requestCount);
             } else if (RESPONSE_COUNT.equals(metricName)) {
-                value = new Long(responseCount);
+                value = Long.valueOf(responseCount);
             } else if (RECEIVED_BYTES_COUNT.equals(metricName)) {
                 if (this.inTransportMetric != null) {
-                    return new Long(this.inTransportMetric.getBytesTransferred());
+                    return Long.valueOf(this.inTransportMetric.getBytesTransferred());
                 } else {
                     return null;
                 }
             } else if (SENT_BYTES_COUNT.equals(metricName)) {
                 if (this.outTransportMetric != null) {
-                    return new Long(this.outTransportMetric.getBytesTransferred());
+                    return Long.valueOf(this.outTransportMetric.getBytesTransferred());
                 } else {
                     return null;
                 }
@@ -126,7 +126,7 @@ public class HttpConnectionMetricsImpl implements HttpConnectionMetrics {
         return value;
     }
 
-    public void setMetric(final String metricName, Object obj) {
+    public void setMetric(final String metricName, final Object obj) {
         if (this.metricsCache == null) {
             this.metricsCache = new HashMap<String, Object>();
         }
diff --git a/httpcore/src/main/java/org/apache/http/impl/NoConnectionReuseStrategy.java b/httpcore/src/main/java/org/apache/http/impl/NoConnectionReuseStrategy.java
index 1c8a321..cc7367c 100644
--- a/httpcore/src/main/java/org/apache/http/impl/NoConnectionReuseStrategy.java
+++ b/httpcore/src/main/java/org/apache/http/impl/NoConnectionReuseStrategy.java
@@ -40,18 +40,13 @@ import org.apache.http.protocol.HttpContext;
 @Immutable
 public class NoConnectionReuseStrategy implements ConnectionReuseStrategy {
 
-    // default constructor
+    public static final NoConnectionReuseStrategy INSTANCE = new NoConnectionReuseStrategy();
 
+    public NoConnectionReuseStrategy() {
+        super();
+    }
 
-    // non-JavaDoc, see interface ConnectionReuseStrategy
     public boolean keepAlive(final HttpResponse response, final HttpContext context) {
-        if (response == null) {
-            throw new IllegalArgumentException("HTTP response may not be null");
-        }
-        if (context == null) {
-            throw new IllegalArgumentException("HTTP context may not be null");
-        }
-
         return false;
     }
 
diff --git a/httpcore/src/main/java/org/apache/http/impl/entity/DisallowIdentityContentLengthStrategy.java b/httpcore/src/main/java/org/apache/http/impl/entity/DisallowIdentityContentLengthStrategy.java
index 9c6b989..33514b9 100644
--- a/httpcore/src/main/java/org/apache/http/impl/entity/DisallowIdentityContentLengthStrategy.java
+++ b/httpcore/src/main/java/org/apache/http/impl/entity/DisallowIdentityContentLengthStrategy.java
@@ -34,23 +34,26 @@ import org.apache.http.annotation.Immutable;
 import org.apache.http.entity.ContentLengthStrategy;
 
 /**
- * Decorator for  {@link ContentLengthStrategy} implementations that disallows the use of 
- * identity transfer encoding. 
+ * Decorator for  {@link ContentLengthStrategy} implementations that disallows the use of
+ * identity transfer encoding.
  *
  * @since 4.2
  */
 @Immutable
 public class DisallowIdentityContentLengthStrategy implements ContentLengthStrategy {
 
+    public static final DisallowIdentityContentLengthStrategy INSTANCE =
+        new DisallowIdentityContentLengthStrategy(new LaxContentLengthStrategy(0));
+
     private final ContentLengthStrategy contentLengthStrategy;
-    
+
     public DisallowIdentityContentLengthStrategy(final ContentLengthStrategy contentLengthStrategy) {
         super();
         this.contentLengthStrategy = contentLengthStrategy;
     }
 
     public long determineLength(final HttpMessage message) throws HttpException {
-        long result = this.contentLengthStrategy.determineLength(message);
+        final long result = this.contentLengthStrategy.determineLength(message);
         if (result == ContentLengthStrategy.IDENTITY) {
             throw new ProtocolException("Identity transfer encoding cannot be used");
         }
diff --git a/httpcore/src/main/java/org/apache/http/impl/entity/LaxContentLengthStrategy.java b/httpcore/src/main/java/org/apache/http/impl/entity/LaxContentLengthStrategy.java
index b9a40e4..2b143d9 100644
--- a/httpcore/src/main/java/org/apache/http/impl/entity/LaxContentLengthStrategy.java
+++ b/httpcore/src/main/java/org/apache/http/impl/entity/LaxContentLengthStrategy.java
@@ -35,45 +35,40 @@ import org.apache.http.ParseException;
 import org.apache.http.ProtocolException;
 import org.apache.http.annotation.Immutable;
 import org.apache.http.entity.ContentLengthStrategy;
-import org.apache.http.params.HttpParams;
-import org.apache.http.params.CoreProtocolPNames;
 import org.apache.http.protocol.HTTP;
+import org.apache.http.util.Args;
 
 /**
  * The lax implementation of the content length strategy. This class will ignore
  * unrecognized transfer encodings and malformed <code>Content-Length</code>
- * header values if the {@link CoreProtocolPNames#STRICT_TRANSFER_ENCODING}
- * parameter of the given message is not set or set to <code>false</code>.
- * <p>
+ * header values.
+ * <p/>
  * This class recognizes "chunked" and "identitiy" transfer-coding only.
- * <p>
- * The following parameters can be used to customize the behavior of this class:
- * <ul>
- *  <li>{@link org.apache.http.params.CoreProtocolPNames#STRICT_TRANSFER_ENCODING}</li>
- * </ul>
  *
  * @since 4.0
  */
 @Immutable
 public class LaxContentLengthStrategy implements ContentLengthStrategy {
 
+    public static final LaxContentLengthStrategy INSTANCE = new LaxContentLengthStrategy();
+
     private final int implicitLen;
-    
+
     /**
      * Creates <tt>LaxContentLengthStrategy</tt> instance with the given length used per default
      * when content length is not explicitly specified in the message.
-     * 
+     *
      * @param implicitLen implicit content length.
-     * 
+     *
      * @since 4.2
      */
-    public LaxContentLengthStrategy(int implicitLen) {
+    public LaxContentLengthStrategy(final int implicitLen) {
         super();
         this.implicitLen = implicitLen;
     }
 
     /**
-     * Creates <tt>LaxContentLengthStrategy</tt> instance. {@link ContentLengthStrategy#IDENTITY} 
+     * Creates <tt>LaxContentLengthStrategy</tt> instance. {@link ContentLengthStrategy#IDENTITY}
      * is used per default when content length is not explicitly specified in the message.
      */
     public LaxContentLengthStrategy() {
@@ -81,66 +76,41 @@ public class LaxContentLengthStrategy implements ContentLengthStrategy {
     }
 
     public long determineLength(final HttpMessage message) throws HttpException {
-        if (message == null) {
-            throw new IllegalArgumentException("HTTP message may not be null");
-        }
-
-        HttpParams params = message.getParams();
-        boolean strict = params.isParameterTrue(CoreProtocolPNames.STRICT_TRANSFER_ENCODING);
+        Args.notNull(message, "HTTP message");
 
-        Header transferEncodingHeader = message.getFirstHeader(HTTP.TRANSFER_ENCODING);
+        final Header transferEncodingHeader = message.getFirstHeader(HTTP.TRANSFER_ENCODING);
         // We use Transfer-Encoding if present and ignore Content-Length.
         // RFC2616, 4.4 item number 3
         if (transferEncodingHeader != null) {
-            HeaderElement[] encodings = null;
+            final HeaderElement[] encodings;
             try {
                 encodings = transferEncodingHeader.getElements();
-            } catch (ParseException px) {
+            } catch (final ParseException px) {
                 throw new ProtocolException
                     ("Invalid Transfer-Encoding header value: " +
                      transferEncodingHeader, px);
             }
-            if (strict) {
-                // Currently only chunk and identity are supported
-                for (int i = 0; i < encodings.length; i++) {
-                    String encoding = encodings[i].getName();
-                    if (encoding != null && encoding.length() > 0
-                        && !encoding.equalsIgnoreCase(HTTP.CHUNK_CODING)
-                        && !encoding.equalsIgnoreCase(HTTP.IDENTITY_CODING)) {
-                        throw new ProtocolException("Unsupported transfer encoding: " + encoding);
-                    }
-                }
-            }
             // The chunked encoding must be the last one applied RFC2616, 14.41
-            int len = encodings.length;
+            final int len = encodings.length;
             if (HTTP.IDENTITY_CODING.equalsIgnoreCase(transferEncodingHeader.getValue())) {
                 return IDENTITY;
             } else if ((len > 0) && (HTTP.CHUNK_CODING.equalsIgnoreCase(
                     encodings[len - 1].getName()))) {
                 return CHUNKED;
             } else {
-                if (strict) {
-                    throw new ProtocolException("Chunk-encoding must be the last one applied");
-                }
                 return IDENTITY;
             }
         }
-        Header contentLengthHeader = message.getFirstHeader(HTTP.CONTENT_LEN);
+        final Header contentLengthHeader = message.getFirstHeader(HTTP.CONTENT_LEN);
         if (contentLengthHeader != null) {
             long contentlen = -1;
-            Header[] headers = message.getHeaders(HTTP.CONTENT_LEN);
-            if (strict && headers.length > 1) {
-                throw new ProtocolException("Multiple content length headers");
-            }
+            final Header[] headers = message.getHeaders(HTTP.CONTENT_LEN);
             for (int i = headers.length - 1; i >= 0; i--) {
-                Header header = headers[i];
+                final Header header = headers[i];
                 try {
                     contentlen = Long.parseLong(header.getValue());
                     break;
-                } catch (NumberFormatException e) {
-                    if (strict) {
-                        throw new ProtocolException("Invalid content length: " + header.getValue());
-                    }
+                } catch (final NumberFormatException ignore) {
                 }
                 // See if we can have better luck with another header, if present
             }
diff --git a/httpcore/src/main/java/org/apache/http/impl/entity/StrictContentLengthStrategy.java b/httpcore/src/main/java/org/apache/http/impl/entity/StrictContentLengthStrategy.java
index 0ff81bf..49d129f 100644
--- a/httpcore/src/main/java/org/apache/http/impl/entity/StrictContentLengthStrategy.java
+++ b/httpcore/src/main/java/org/apache/http/impl/entity/StrictContentLengthStrategy.java
@@ -35,6 +35,7 @@ import org.apache.http.ProtocolException;
 import org.apache.http.annotation.Immutable;
 import org.apache.http.entity.ContentLengthStrategy;
 import org.apache.http.protocol.HTTP;
+import org.apache.http.util.Args;
 
 /**
  * The strict implementation of the content length strategy. This class
@@ -49,23 +50,25 @@ import org.apache.http.protocol.HTTP;
 @Immutable
 public class StrictContentLengthStrategy implements ContentLengthStrategy {
 
+    public static final StrictContentLengthStrategy INSTANCE = new StrictContentLengthStrategy();
+
     private final int implicitLen;
-    
+
     /**
      * Creates <tt>StrictContentLengthStrategy</tt> instance with the given length used per default
      * when content length is not explicitly specified in the message.
-     * 
+     *
      * @param implicitLen implicit content length.
-     * 
+     *
      * @since 4.2
      */
-    public StrictContentLengthStrategy(int implicitLen) {
+    public StrictContentLengthStrategy(final int implicitLen) {
         super();
         this.implicitLen = implicitLen;
     }
 
     /**
-     * Creates <tt>StrictContentLengthStrategy</tt> instance. {@link ContentLengthStrategy#IDENTITY} 
+     * Creates <tt>StrictContentLengthStrategy</tt> instance. {@link ContentLengthStrategy#IDENTITY}
      * is used per default when content length is not explicitly specified in the message.
      */
     public StrictContentLengthStrategy() {
@@ -73,15 +76,13 @@ public class StrictContentLengthStrategy implements ContentLengthStrategy {
     }
 
     public long determineLength(final HttpMessage message) throws HttpException {
-        if (message == null) {
-            throw new IllegalArgumentException("HTTP message may not be null");
-        }
+        Args.notNull(message, "HTTP message");
         // Although Transfer-Encoding is specified as a list, in practice
         // it is either missing or has the single value "chunked". So we
         // treat it as a single-valued header here.
-        Header transferEncodingHeader = message.getFirstHeader(HTTP.TRANSFER_ENCODING);
+        final Header transferEncodingHeader = message.getFirstHeader(HTTP.TRANSFER_ENCODING);
         if (transferEncodingHeader != null) {
-            String s = transferEncodingHeader.getValue();
+            final String s = transferEncodingHeader.getValue();
             if (HTTP.CHUNK_CODING.equalsIgnoreCase(s)) {
                 if (message.getProtocolVersion().lessEquals(HttpVersion.HTTP_1_0)) {
                     throw new ProtocolException(
@@ -96,16 +97,16 @@ public class StrictContentLengthStrategy implements ContentLengthStrategy {
                         "Unsupported transfer encoding: " + s);
             }
         }
-        Header contentLengthHeader = message.getFirstHeader(HTTP.CONTENT_LEN);
+        final Header contentLengthHeader = message.getFirstHeader(HTTP.CONTENT_LEN);
         if (contentLengthHeader != null) {
-            String s = contentLengthHeader.getValue();
+            final String s = contentLengthHeader.getValue();
             try {
-                long len = Long.parseLong(s);
+                final long len = Long.parseLong(s);
                 if (len < 0) {
                     throw new ProtocolException("Negative content length: " + s);
                 }
                 return len;
-            } catch (NumberFormatException e) {
+            } catch (final NumberFormatException e) {
                 throw new ProtocolException("Invalid content length: " + s);
             }
         }
diff --git a/httpcore/src/main/java/org/apache/http/impl/io/AbstractMessageParser.java b/httpcore/src/main/java/org/apache/http/impl/io/AbstractMessageParser.java
index 5c99545..1aa2821 100644
--- a/httpcore/src/main/java/org/apache/http/impl/io/AbstractMessageParser.java
+++ b/httpcore/src/main/java/org/apache/http/impl/io/AbstractMessageParser.java
@@ -34,30 +34,27 @@ import java.util.List;
 import org.apache.http.Header;
 import org.apache.http.HttpException;
 import org.apache.http.HttpMessage;
+import org.apache.http.MessageConstraintException;
 import org.apache.http.ParseException;
 import org.apache.http.ProtocolException;
 import org.apache.http.annotation.NotThreadSafe;
+import org.apache.http.config.MessageConstraints;
 import org.apache.http.io.HttpMessageParser;
 import org.apache.http.io.SessionInputBuffer;
-import org.apache.http.message.LineParser;
 import org.apache.http.message.BasicLineParser;
-import org.apache.http.params.CoreConnectionPNames;
+import org.apache.http.message.LineParser;
+import org.apache.http.params.HttpParamConfig;
 import org.apache.http.params.HttpParams;
+import org.apache.http.util.Args;
 import org.apache.http.util.CharArrayBuffer;
 
 /**
  * Abstract base class for HTTP message parsers that obtain input from
  * an instance of {@link SessionInputBuffer}.
- * <p>
- * The following parameters can be used to customize the behavior of this
- * class:
- * <ul>
- *  <li>{@link org.apache.http.params.CoreConnectionPNames#MAX_HEADER_COUNT}</li>
- *  <li>{@link org.apache.http.params.CoreConnectionPNames#MAX_LINE_LENGTH}</li>
- * </ul>
  *
  * @since 4.0
  */
+ at SuppressWarnings("deprecation")
 @NotThreadSafe
 public abstract class AbstractMessageParser<T extends HttpMessage> implements HttpMessageParser<T> {
 
@@ -65,8 +62,7 @@ public abstract class AbstractMessageParser<T extends HttpMessage> implements Ht
     private static final int HEADERS      = 1;
 
     private final SessionInputBuffer sessionBuffer;
-    private final int maxHeaderCount;
-    private final int maxLineLen;
+    private final MessageConstraints messageConstraints;
     private final List<CharArrayBuffer> headerLines;
     protected final LineParser lineParser;
 
@@ -74,29 +70,49 @@ public abstract class AbstractMessageParser<T extends HttpMessage> implements Ht
     private T message;
 
     /**
-     * Creates an instance of this class.
+     * Creates an instance of AbstractMessageParser.
      *
      * @param buffer the session input buffer.
      * @param parser the line parser.
      * @param params HTTP parameters.
+     *
+     * @deprecated (4.3) use {@link AbstractMessageParser#AbstractMessageParser(SessionInputBuffer,
+     *   LineParser, MessageConstraints)}
      */
+    @Deprecated
     public AbstractMessageParser(
             final SessionInputBuffer buffer,
             final LineParser parser,
             final HttpParams params) {
         super();
-        if (buffer == null) {
-            throw new IllegalArgumentException("Session input buffer may not be null");
-        }
-        if (params == null) {
-            throw new IllegalArgumentException("HTTP parameters may not be null");
-        }
+        Args.notNull(buffer, "Session input buffer");
+        Args.notNull(params, "HTTP parameters");
         this.sessionBuffer = buffer;
-        this.maxHeaderCount = params.getIntParameter(
-                CoreConnectionPNames.MAX_HEADER_COUNT, -1);
-        this.maxLineLen = params.getIntParameter(
-                CoreConnectionPNames.MAX_LINE_LENGTH, -1);
-        this.lineParser = (parser != null) ? parser : BasicLineParser.DEFAULT;
+        this.messageConstraints = HttpParamConfig.getMessageConstraints(params);
+        this.lineParser = (parser != null) ? parser : BasicLineParser.INSTANCE;
+        this.headerLines = new ArrayList<CharArrayBuffer>();
+        this.state = HEAD_LINE;
+    }
+
+    /**
+     * Creates new instance of AbstractMessageParser.
+     *
+     * @param buffer the session input buffer.
+     * @param lineParser the line parser. If <code>null</code> {@link BasicLineParser#INSTANCE}
+     *   will be used.
+     * @param constraints the message constraints. If <code>null</code>
+     *   {@link MessageConstraints#DEFAULT} will be used.
+     *
+     * @since 4.3
+     */
+    public AbstractMessageParser(
+            final SessionInputBuffer buffer,
+            final LineParser lineParser,
+            final MessageConstraints constraints) {
+        super();
+        this.sessionBuffer = Args.notNull(buffer, "Session input buffer");
+        this.lineParser = lineParser != null ? lineParser : BasicLineParser.INSTANCE;
+        this.messageConstraints = constraints != null ? constraints : MessageConstraints.DEFAULT;
         this.headerLines = new ArrayList<CharArrayBuffer>();
         this.state = HEAD_LINE;
     }
@@ -122,15 +138,13 @@ public abstract class AbstractMessageParser<T extends HttpMessage> implements Ht
      */
     public static Header[] parseHeaders(
             final SessionInputBuffer inbuffer,
-            int maxHeaderCount,
-            int maxLineLen,
-            LineParser parser)
-        throws HttpException, IOException {
-        if (parser == null) {
-            parser = BasicLineParser.DEFAULT;
-        }
-        List<CharArrayBuffer> headerLines = new ArrayList<CharArrayBuffer>();
-        return parseHeaders(inbuffer, maxHeaderCount, maxLineLen, parser, headerLines);
+            final int maxHeaderCount,
+            final int maxLineLen,
+            final LineParser parser) throws HttpException, IOException {
+        final List<CharArrayBuffer> headerLines = new ArrayList<CharArrayBuffer>();
+        return parseHeaders(inbuffer, maxHeaderCount, maxLineLen,
+                parser != null ? parser : BasicLineParser.INSTANCE,
+                headerLines);
     }
 
     /**
@@ -159,21 +173,13 @@ public abstract class AbstractMessageParser<T extends HttpMessage> implements Ht
      */
     public static Header[] parseHeaders(
             final SessionInputBuffer inbuffer,
-            int maxHeaderCount,
-            int maxLineLen,
+            final int maxHeaderCount,
+            final int maxLineLen,
             final LineParser parser,
-            final List<CharArrayBuffer> headerLines)
-        throws HttpException, IOException {
-
-        if (inbuffer == null) {
-            throw new IllegalArgumentException("Session input buffer may not be null");
-        }
-        if (parser == null) {
-            throw new IllegalArgumentException("Line parser may not be null");
-        }
-        if (headerLines == null) {
-            throw new IllegalArgumentException("Header line list may not be null");
-        }
+            final List<CharArrayBuffer> headerLines) throws HttpException, IOException {
+        Args.notNull(inbuffer, "Session input buffer");
+        Args.notNull(parser, "Line parser");
+        Args.notNull(headerLines, "Header line list");
 
         CharArrayBuffer current = null;
         CharArrayBuffer previous = null;
@@ -183,7 +189,7 @@ public abstract class AbstractMessageParser<T extends HttpMessage> implements Ht
             } else {
                 current.clear();
             }
-            int l = inbuffer.readLine(current);
+            final int l = inbuffer.readLine(current);
             if (l == -1 || current.length() < 1) {
                 break;
             }
@@ -196,7 +202,7 @@ public abstract class AbstractMessageParser<T extends HttpMessage> implements Ht
                 // so append value
                 int i = 0;
                 while (i < current.length()) {
-                    char ch = current.charAt(i);
+                    final char ch = current.charAt(i);
                     if (ch != ' ' && ch != '\t') {
                         break;
                     }
@@ -204,7 +210,7 @@ public abstract class AbstractMessageParser<T extends HttpMessage> implements Ht
                 }
                 if (maxLineLen > 0
                         && previous.length() + 1 + current.length() - i > maxLineLen) {
-                    throw new IOException("Maximum line length limit exceeded");
+                    throw new MessageConstraintException("Maximum line length limit exceeded");
                 }
                 previous.append(' ');
                 previous.append(current, i, current.length() - i);
@@ -214,15 +220,15 @@ public abstract class AbstractMessageParser<T extends HttpMessage> implements Ht
                 current = null;
             }
             if (maxHeaderCount > 0 && headerLines.size() >= maxHeaderCount) {
-                throw new IOException("Maximum header count exceeded");
+                throw new MessageConstraintException("Maximum header count exceeded");
             }
         }
-        Header[] headers = new Header[headerLines.size()];
+        final Header[] headers = new Header[headerLines.size()];
         for (int i = 0; i < headerLines.size(); i++) {
-            CharArrayBuffer buffer = headerLines.get(i);
+            final CharArrayBuffer buffer = headerLines.get(i);
             try {
                 headers[i] = parser.parseHeader(buffer);
-            } catch (ParseException ex) {
+            } catch (final ParseException ex) {
                 throw new ProtocolException(ex.getMessage());
             }
         }
@@ -247,25 +253,25 @@ public abstract class AbstractMessageParser<T extends HttpMessage> implements Ht
         throws IOException, HttpException, ParseException;
 
     public T parse() throws IOException, HttpException {
-        int st = this.state;
+        final int st = this.state;
         switch (st) {
         case HEAD_LINE:
             try {
                 this.message = parseHead(this.sessionBuffer);
-            } catch (ParseException px) {
+            } catch (final ParseException px) {
                 throw new ProtocolException(px.getMessage(), px);
             }
             this.state = HEADERS;
             //$FALL-THROUGH$
         case HEADERS:
-            Header[] headers = AbstractMessageParser.parseHeaders(
+            final Header[] headers = AbstractMessageParser.parseHeaders(
                     this.sessionBuffer,
-                    this.maxHeaderCount,
-                    this.maxLineLen,
+                    this.messageConstraints.getMaxHeaderCount(),
+                    this.messageConstraints.getMaxLineLength(),
                     this.lineParser,
                     this.headerLines);
             this.message.setHeaders(headers);
-            T result = this.message;
+            final T result = this.message;
             this.message = null;
             this.headerLines.clear();
             this.state = HEAD_LINE;
diff --git a/httpcore/src/main/java/org/apache/http/impl/io/AbstractMessageWriter.java b/httpcore/src/main/java/org/apache/http/impl/io/AbstractMessageWriter.java
index bedb443..914f1aa 100644
--- a/httpcore/src/main/java/org/apache/http/impl/io/AbstractMessageWriter.java
+++ b/httpcore/src/main/java/org/apache/http/impl/io/AbstractMessageWriter.java
@@ -36,9 +36,10 @@ import org.apache.http.HttpMessage;
 import org.apache.http.annotation.NotThreadSafe;
 import org.apache.http.io.HttpMessageWriter;
 import org.apache.http.io.SessionOutputBuffer;
-import org.apache.http.message.LineFormatter;
 import org.apache.http.message.BasicLineFormatter;
+import org.apache.http.message.LineFormatter;
 import org.apache.http.params.HttpParams;
+import org.apache.http.util.Args;
 import org.apache.http.util.CharArrayBuffer;
 
 /**
@@ -47,6 +48,7 @@ import org.apache.http.util.CharArrayBuffer;
  *
  * @since 4.0
  */
+ at SuppressWarnings("deprecation")
 @NotThreadSafe
 public abstract class AbstractMessageWriter<T extends HttpMessage> implements HttpMessageWriter<T> {
 
@@ -60,18 +62,37 @@ public abstract class AbstractMessageWriter<T extends HttpMessage> implements Ht
      * @param buffer the session output buffer.
      * @param formatter the line formatter.
      * @param params HTTP parameters.
+     *
+     * @deprecated (4.3) use
+     *   {@link AbstractMessageWriter#AbstractMessageWriter(SessionOutputBuffer, LineFormatter)}
      */
+    @Deprecated
     public AbstractMessageWriter(final SessionOutputBuffer buffer,
                                  final LineFormatter formatter,
                                  final HttpParams params) {
         super();
-        if (buffer == null) {
-            throw new IllegalArgumentException("Session input buffer may not be null");
-        }
+        Args.notNull(buffer, "Session input buffer");
         this.sessionBuffer = buffer;
         this.lineBuf = new CharArrayBuffer(128);
-        this.lineFormatter = (formatter != null) ?
-            formatter : BasicLineFormatter.DEFAULT;
+        this.lineFormatter = (formatter != null) ? formatter : BasicLineFormatter.INSTANCE;
+    }
+
+    /**
+     * Creates an instance of AbstractMessageWriter.
+     *
+     * @param buffer the session output buffer.
+     * @param formatter the line formatter If <code>null</code> {@link BasicLineFormatter#INSTANCE}
+     *   will be used.
+     *
+     * @since 4.3
+     */
+    public AbstractMessageWriter(
+            final SessionOutputBuffer buffer,
+            final LineFormatter formatter) {
+        super();
+        this.sessionBuffer = Args.notNull(buffer, "Session input buffer");
+        this.lineFormatter = (formatter != null) ? formatter : BasicLineFormatter.INSTANCE;
+        this.lineBuf = new CharArrayBuffer(128);
     }
 
     /**
@@ -84,12 +105,10 @@ public abstract class AbstractMessageWriter<T extends HttpMessage> implements Ht
     protected abstract void writeHeadLine(T message) throws IOException;
 
     public void write(final T message) throws IOException, HttpException {
-        if (message == null) {
-            throw new IllegalArgumentException("HTTP message may not be null");
-        }
+        Args.notNull(message, "HTTP message");
         writeHeadLine(message);
-        for (HeaderIterator it = message.headerIterator(); it.hasNext(); ) {
-            Header header = it.nextHeader();
+        for (final HeaderIterator it = message.headerIterator(); it.hasNext(); ) {
+            final Header header = it.nextHeader();
             this.sessionBuffer.writeLine
                 (lineFormatter.formatHeader(this.lineBuf, header));
         }
diff --git a/httpcore/src/main/java/org/apache/http/impl/io/ChunkedInputStream.java b/httpcore/src/main/java/org/apache/http/impl/io/ChunkedInputStream.java
index debbae8..3a5455b 100644
--- a/httpcore/src/main/java/org/apache/http/impl/io/ChunkedInputStream.java
+++ b/httpcore/src/main/java/org/apache/http/impl/io/ChunkedInputStream.java
@@ -37,6 +37,7 @@ import org.apache.http.TruncatedChunkException;
 import org.apache.http.annotation.NotThreadSafe;
 import org.apache.http.io.BufferInfo;
 import org.apache.http.io.SessionInputBuffer;
+import org.apache.http.util.Args;
 import org.apache.http.util.CharArrayBuffer;
 
 /**
@@ -92,10 +93,7 @@ public class ChunkedInputStream extends InputStream {
      */
     public ChunkedInputStream(final SessionInputBuffer in) {
         super();
-        if (in == null) {
-            throw new IllegalArgumentException("Session input buffer may not be null");
-        }
-        this.in = in;
+        this.in = Args.notNull(in, "Session input buffer");
         this.pos = 0;
         this.buffer = new CharArrayBuffer(16);
         this.state = CHUNK_LEN;
@@ -104,7 +102,7 @@ public class ChunkedInputStream extends InputStream {
     @Override
     public int available() throws IOException {
         if (this.in instanceof BufferInfo) {
-            int len = ((BufferInfo) this.in).length();
+            final int len = ((BufferInfo) this.in).length();
             return Math.min(len, this.chunkSize - this.pos);
         } else {
             return 0;
@@ -137,7 +135,7 @@ public class ChunkedInputStream extends InputStream {
                 return -1;
             }
         }
-        int b = in.read();
+        final int b = in.read();
         if (b != -1) {
             pos++;
             if (pos >= chunkSize) {
@@ -158,7 +156,7 @@ public class ChunkedInputStream extends InputStream {
      * @throws IOException in case of an I/O error
      */
     @Override
-    public int read (byte[] b, int off, int len) throws IOException {
+    public int read (final byte[] b, final int off, final int len) throws IOException {
 
         if (closed) {
             throw new IOException("Attempted read from closed stream.");
@@ -173,8 +171,7 @@ public class ChunkedInputStream extends InputStream {
                 return -1;
             }
         }
-        len = Math.min(len, chunkSize - pos);
-        int bytesRead = in.read(b, off, len);
+        final int bytesRead = in.read(b, off, Math.min(len, chunkSize - pos));
         if (bytesRead != -1) {
             pos += bytesRead;
             if (pos >= chunkSize) {
@@ -197,7 +194,7 @@ public class ChunkedInputStream extends InputStream {
      * @throws IOException in case of an I/O error
      */
     @Override
-    public int read (byte[] b) throws IOException {
+    public int read (final byte[] b) throws IOException {
         return read(b, 0, b.length);
     }
 
@@ -222,22 +219,14 @@ public class ChunkedInputStream extends InputStream {
      * Expects the stream to start with a chunksize in hex with optional
      * comments after a semicolon. The line must end with a CRLF: "a3; some
      * comment\r\n" Positions the stream at the start of the next line.
-     *
-     * @param in The new input stream.
-     * @param required <tt>true<tt/> if a valid chunk must be present,
-     *                 <tt>false<tt/> otherwise.
-     *
-     * @return the chunk size as integer
-     *
-     * @throws IOException when the chunk size could not be parsed
      */
     private int getChunkSize() throws IOException {
-        int st = this.state;
+        final int st = this.state;
         switch (st) {
         case CHUNK_CRLF:
             this.buffer.clear();
-            int i = this.in.readLine(this.buffer);
-            if (i == -1) {
+            final int bytesRead1 = this.in.readLine(this.buffer);
+            if (bytesRead1 == -1) {
                 return 0;
             }
             if (!this.buffer.isEmpty()) {
@@ -248,8 +237,8 @@ public class ChunkedInputStream extends InputStream {
             //$FALL-THROUGH$
         case CHUNK_LEN:
             this.buffer.clear();
-            i = this.in.readLine(this.buffer);
-            if (i == -1) {
+            final int bytesRead2 = this.in.readLine(this.buffer);
+            if (bytesRead2 == -1) {
                 return 0;
             }
             int separator = this.buffer.indexOf(';');
@@ -258,7 +247,7 @@ public class ChunkedInputStream extends InputStream {
             }
             try {
                 return Integer.parseInt(this.buffer.substringTrimmed(0, separator), 16);
-            } catch (NumberFormatException e) {
+            } catch (final NumberFormatException e) {
                 throw new MalformedChunkCodingException("Bad chunk header");
             }
         default:
@@ -274,8 +263,8 @@ public class ChunkedInputStream extends InputStream {
         try {
             this.footers = AbstractMessageParser.parseHeaders
                 (in, -1, -1, null);
-        } catch (HttpException ex) {
-            IOException ioe = new MalformedChunkCodingException("Invalid footer: "
+        } catch (final HttpException ex) {
+            final IOException ioe = new MalformedChunkCodingException("Invalid footer: "
                     + ex.getMessage());
             ioe.initCause(ex);
             throw ioe;
@@ -294,7 +283,7 @@ public class ChunkedInputStream extends InputStream {
             try {
                 if (!eof) {
                     // read and discard the remainder of the message
-                    byte buffer[] = new byte[BUFFER_SIZE];
+                    final byte buffer[] = new byte[BUFFER_SIZE];
                     while (read(buffer) >= 0) {
                     }
                 }
diff --git a/httpcore/src/main/java/org/apache/http/impl/io/ChunkedOutputStream.java b/httpcore/src/main/java/org/apache/http/impl/io/ChunkedOutputStream.java
index ff78b52..f9dfa84 100644
--- a/httpcore/src/main/java/org/apache/http/impl/io/ChunkedOutputStream.java
+++ b/httpcore/src/main/java/org/apache/http/impl/io/ChunkedOutputStream.java
@@ -51,7 +51,7 @@ public class ChunkedOutputStream extends OutputStream {
     // ----------------------------------------------------- Instance Variables
     private final SessionOutputBuffer out;
 
-    private byte[] cache;
+    private final byte[] cache;
 
     private int cachePosition = 0;
 
@@ -60,19 +60,19 @@ public class ChunkedOutputStream extends OutputStream {
     /** True if the stream is closed. */
     private boolean closed = false;
 
-    // ----------------------------------------------------------- Constructors
     /**
      * Wraps a session output buffer and chunk-encodes the output.
      *
      * @param out The session output buffer
      * @param bufferSize The minimum chunk size (excluding last chunk)
-     * @throws IOException in case of an I/O error
+     * @throws IOException not thrown
+     *
+     * @deprecated (4.3) use {@link ChunkedOutputStream#ChunkedOutputStream(int, SessionOutputBuffer)}
      */
-    public ChunkedOutputStream(final SessionOutputBuffer out, int bufferSize)
+    @Deprecated
+    public ChunkedOutputStream(final SessionOutputBuffer out, final int bufferSize)
             throws IOException {
-        super();
-        this.cache = new byte[bufferSize];
-        this.out = out;
+        this(bufferSize, out);
     }
 
     /**
@@ -80,14 +80,28 @@ public class ChunkedOutputStream extends OutputStream {
      * size of 2048 was chosen because the chunk overhead is less than 0.5%
      *
      * @param out       the output buffer to wrap
-     * @throws IOException in case of an I/O error
+     * @throws IOException not thrown
+     *
+     * @deprecated (4.3) use {@link ChunkedOutputStream#ChunkedOutputStream(int, SessionOutputBuffer)}
      */
+    @Deprecated
     public ChunkedOutputStream(final SessionOutputBuffer out)
             throws IOException {
-        this(out, 2048);
+        this(2048, out);
+    }
+
+    /**
+     * Wraps a session output buffer and chunk-encodes the output.
+     *
+     * @param bufferSize The minimum chunk size (excluding last chunk)
+     * @param out The session output buffer
+     */
+    public ChunkedOutputStream(final int bufferSize, final SessionOutputBuffer out) {
+        super();
+        this.cache = new byte[bufferSize];
+        this.out = out;
     }
 
-    // ----------------------------------------------------------- Internal methods
     /**
      * Writes the cache out onto the underlying stream
      */
@@ -104,7 +118,7 @@ public class ChunkedOutputStream extends OutputStream {
      * Writes the cache and bufferToAppend to the underlying stream
      * as one large chunk
      */
-    protected void flushCacheWithAppend(byte bufferToAppend[], int off, int len) throws IOException {
+    protected void flushCacheWithAppend(final byte bufferToAppend[], final int off, final int len) throws IOException {
         this.out.writeLine(Integer.toHexString(this.cachePosition + len));
         this.out.write(this.cache, 0, this.cachePosition);
         this.out.write(bufferToAppend, off, len);
@@ -134,13 +148,15 @@ public class ChunkedOutputStream extends OutputStream {
 
     // -------------------------------------------- OutputStream Methods
     @Override
-    public void write(int b) throws IOException {
+    public void write(final int b) throws IOException {
         if (this.closed) {
             throw new IOException("Attempted write to closed stream.");
         }
         this.cache[this.cachePosition] = (byte) b;
         this.cachePosition++;
-        if (this.cachePosition == this.cache.length) flushCache();
+        if (this.cachePosition == this.cache.length) {
+            flushCache();
+        }
     }
 
     /**
@@ -148,7 +164,7 @@ public class ChunkedOutputStream extends OutputStream {
      * not split, but rather written out as one large chunk.
      */
     @Override
-    public void write(byte b[]) throws IOException {
+    public void write(final byte b[]) throws IOException {
         write(b, 0, b.length);
     }
 
@@ -157,7 +173,7 @@ public class ChunkedOutputStream extends OutputStream {
      * not split, but rather written out as one large chunk.
      */
     @Override
-    public void write(byte src[], int off, int len) throws IOException {
+    public void write(final byte src[], final int off, final int len) throws IOException {
         if (this.closed) {
             throw new IOException("Attempted write to closed stream.");
         }
diff --git a/httpcore/src/main/java/org/apache/http/impl/io/ContentLengthInputStream.java b/httpcore/src/main/java/org/apache/http/impl/io/ContentLengthInputStream.java
index 5b76464..8b73bdf 100644
--- a/httpcore/src/main/java/org/apache/http/impl/io/ContentLengthInputStream.java
+++ b/httpcore/src/main/java/org/apache/http/impl/io/ContentLengthInputStream.java
@@ -34,6 +34,7 @@ import org.apache.http.ConnectionClosedException;
 import org.apache.http.annotation.NotThreadSafe;
 import org.apache.http.io.BufferInfo;
 import org.apache.http.io.SessionInputBuffer;
+import org.apache.http.util.Args;
 
 /**
  * Input stream that cuts off after a defined number of bytes. This class
@@ -59,7 +60,7 @@ public class ContentLengthInputStream extends InputStream {
      * The maximum number of bytes that can be read from the stream. Subsequent
      * read operations will return -1.
      */
-    private long contentLength;
+    private final long contentLength;
 
     /** The current position */
     private long pos = 0;
@@ -80,16 +81,10 @@ public class ContentLengthInputStream extends InputStream {
      * @param contentLength The maximum number of bytes that can be read from
      * the stream. Subsequent read operations will return -1.
      */
-    public ContentLengthInputStream(final SessionInputBuffer in, long contentLength) {
+    public ContentLengthInputStream(final SessionInputBuffer in, final long contentLength) {
         super();
-        if (in == null) {
-            throw new IllegalArgumentException("Input stream may not be null");
-        }
-        if (contentLength < 0) {
-            throw new IllegalArgumentException("Content length may not be negative");
-        }
-        this.in = in;
-        this.contentLength = contentLength;
+        this.in = Args.notNull(in, "Session input buffer");
+        this.contentLength = Args.notNegative(contentLength, "Content length");
     }
 
     /**
@@ -104,7 +99,7 @@ public class ContentLengthInputStream extends InputStream {
         if (!closed) {
             try {
                 if (pos < contentLength) {
-                    byte buffer[] = new byte[BUFFER_SIZE];
+                    final byte buffer[] = new byte[BUFFER_SIZE];
                     while (read(buffer) >= 0) {
                     }
                 }
@@ -119,7 +114,7 @@ public class ContentLengthInputStream extends InputStream {
     @Override
     public int available() throws IOException {
         if (this.in instanceof BufferInfo) {
-            int len = ((BufferInfo) this.in).length();
+            final int len = ((BufferInfo) this.in).length();
             return Math.min(len, (int) (this.contentLength - this.pos));
         } else {
             return 0;
@@ -141,7 +136,7 @@ public class ContentLengthInputStream extends InputStream {
         if (pos >= contentLength) {
             return -1;
         }
-        int b = this.in.read();
+        final int b = this.in.read();
         if (b == -1) {
             if (pos < contentLength) {
                 throw new ConnectionClosedException(
@@ -167,7 +162,7 @@ public class ContentLengthInputStream extends InputStream {
      * @throws java.io.IOException Should an error occur on the wrapped stream.
      */
     @Override
-    public int read (byte[] b, int off, int len) throws java.io.IOException {
+    public int read (final byte[] b, final int off, final int len) throws java.io.IOException {
         if (closed) {
             throw new IOException("Attempted read from closed stream.");
         }
@@ -176,10 +171,11 @@ public class ContentLengthInputStream extends InputStream {
             return -1;
         }
 
+        int chunk = len;
         if (pos + len > contentLength) {
-            len = (int) (contentLength - pos);
+            chunk = (int) (contentLength - pos);
         }
-        int count = this.in.read(b, off, len);
+        final int count = this.in.read(b, off, chunk);
         if (count == -1 && pos < contentLength) {
             throw new ConnectionClosedException(
                     "Premature end of Content-Length delimited message body (expected: "
@@ -200,7 +196,7 @@ public class ContentLengthInputStream extends InputStream {
      * @see java.io.InputStream#read(byte[])
      */
     @Override
-    public int read(byte[] b) throws IOException {
+    public int read(final byte[] b) throws IOException {
         return read(b, 0, b.length);
     }
 
@@ -213,18 +209,18 @@ public class ContentLengthInputStream extends InputStream {
      * @see InputStream#skip(long)
      */
     @Override
-    public long skip(long n) throws IOException {
+    public long skip(final long n) throws IOException {
         if (n <= 0) {
             return 0;
         }
-        byte[] buffer = new byte[BUFFER_SIZE];
+        final byte[] buffer = new byte[BUFFER_SIZE];
         // make sure we don't skip more bytes than are
         // still available
         long remaining = Math.min(n, this.contentLength - this.pos);
         // skip and keep track of the bytes actually skipped
         long count = 0;
         while (remaining > 0) {
-            int l = read(buffer, 0, (int)Math.min(BUFFER_SIZE, remaining));
+            final int l = read(buffer, 0, (int)Math.min(BUFFER_SIZE, remaining));
             if (l == -1) {
                 break;
             }
diff --git a/httpcore/src/main/java/org/apache/http/impl/io/ContentLengthOutputStream.java b/httpcore/src/main/java/org/apache/http/impl/io/ContentLengthOutputStream.java
index 0bdd45a..66b919c 100644
--- a/httpcore/src/main/java/org/apache/http/impl/io/ContentLengthOutputStream.java
+++ b/httpcore/src/main/java/org/apache/http/impl/io/ContentLengthOutputStream.java
@@ -32,6 +32,7 @@ import java.io.OutputStream;
 
 import org.apache.http.annotation.NotThreadSafe;
 import org.apache.http.io.SessionOutputBuffer;
+import org.apache.http.util.Args;
 
 /**
  * Output stream that cuts off after a defined number of bytes. This class
@@ -76,16 +77,10 @@ public class ContentLengthOutputStream extends OutputStream {
      *
      * @since 4.0
      */
-    public ContentLengthOutputStream(final SessionOutputBuffer out, long contentLength) {
+    public ContentLengthOutputStream(final SessionOutputBuffer out, final long contentLength) {
         super();
-        if (out == null) {
-            throw new IllegalArgumentException("Session output buffer may not be null");
-        }
-        if (contentLength < 0) {
-            throw new IllegalArgumentException("Content length may not be negative");
-        }
-        this.out = out;
-        this.contentLength = contentLength;
+        this.out = Args.notNull(out, "Session output buffer");
+        this.contentLength = Args.notNegative(contentLength, "Content length");
     }
 
     /**
@@ -107,27 +102,28 @@ public class ContentLengthOutputStream extends OutputStream {
     }
 
     @Override
-    public void write(byte[] b, int off, int len) throws IOException {
+    public void write(final byte[] b, final int off, final int len) throws IOException {
         if (this.closed) {
             throw new IOException("Attempted write to closed stream.");
         }
         if (this.total < this.contentLength) {
-            long max = this.contentLength - this.total;
-            if (len > max) {
-                len = (int) max;
+            final long max = this.contentLength - this.total;
+            int chunk = len;
+            if (chunk > max) {
+                chunk = (int) max;
             }
-            this.out.write(b, off, len);
-            this.total += len;
+            this.out.write(b, off, chunk);
+            this.total += chunk;
         }
     }
 
     @Override
-    public void write(byte[] b) throws IOException {
+    public void write(final byte[] b) throws IOException {
         write(b, 0, b.length);
     }
 
     @Override
-    public void write(int b) throws IOException {
+    public void write(final int b) throws IOException {
         if (this.closed) {
             throw new IOException("Attempted write to closed stream.");
         }
diff --git a/httpcore/src/main/java/org/apache/http/impl/io/DefaultHttpRequestParser.java b/httpcore/src/main/java/org/apache/http/impl/io/DefaultHttpRequestParser.java
index ff3e469..3b7e134 100644
--- a/httpcore/src/main/java/org/apache/http/impl/io/DefaultHttpRequestParser.java
+++ b/httpcore/src/main/java/org/apache/http/impl/io/DefaultHttpRequestParser.java
@@ -33,28 +33,25 @@ import org.apache.http.ConnectionClosedException;
 import org.apache.http.HttpException;
 import org.apache.http.HttpRequest;
 import org.apache.http.HttpRequestFactory;
-import org.apache.http.RequestLine;
 import org.apache.http.ParseException;
+import org.apache.http.RequestLine;
 import org.apache.http.annotation.NotThreadSafe;
+import org.apache.http.config.MessageConstraints;
+import org.apache.http.impl.DefaultHttpRequestFactory;
 import org.apache.http.io.SessionInputBuffer;
 import org.apache.http.message.LineParser;
 import org.apache.http.message.ParserCursor;
 import org.apache.http.params.HttpParams;
+import org.apache.http.util.Args;
 import org.apache.http.util.CharArrayBuffer;
 
 /**
  * HTTP request parser that obtain its input from an instance
  * of {@link SessionInputBuffer}.
- * <p>
- * The following parameters can be used to customize the behavior of this
- * class:
- * <ul>
- *  <li>{@link org.apache.http.params.CoreConnectionPNames#MAX_HEADER_COUNT}</li>
- *  <li>{@link org.apache.http.params.CoreConnectionPNames#MAX_LINE_LENGTH}</li>
- * </ul>
  *
  * @since 4.2
  */
+ at SuppressWarnings("deprecation")
 @NotThreadSafe
 public class DefaultHttpRequestParser extends AbstractMessageParser<HttpRequest> {
 
@@ -65,36 +62,78 @@ public class DefaultHttpRequestParser extends AbstractMessageParser<HttpRequest>
      * Creates an instance of this class.
      *
      * @param buffer the session input buffer.
-     * @param parser the line parser.
+     * @param lineParser the line parser.
      * @param requestFactory the factory to use to create
      *    {@link HttpRequest}s.
      * @param params HTTP parameters.
+     *
+     * @deprecated (4.3) use
+     *   {@link DefaultHttpRequestParser#DefaultHttpRequestParser(SessionInputBuffer, LineParser,
+     *     HttpRequestFactory, MessageConstraints)}
      */
+    @Deprecated
     public DefaultHttpRequestParser(
             final SessionInputBuffer buffer,
-            final LineParser parser,
+            final LineParser lineParser,
             final HttpRequestFactory requestFactory,
             final HttpParams params) {
-        super(buffer, parser, params);
-        if (requestFactory == null) {
-            throw new IllegalArgumentException("Request factory may not be null");
-        }
-        this.requestFactory = requestFactory;
+        super(buffer, lineParser, params);
+        this.requestFactory = Args.notNull(requestFactory, "Request factory");
         this.lineBuf = new CharArrayBuffer(128);
     }
 
+    /**
+     * Creates new instance of DefaultHttpRequestParser.
+     *
+     * @param buffer the session input buffer.
+     * @param lineParser the line parser. If <code>null</code>
+     *   {@link org.apache.http.message.BasicLineParser#INSTANCE} will be used.
+     * @param requestFactory the response factory. If <code>null</code>
+     *   {@link DefaultHttpRequestFactory#INSTANCE} will be used.
+     * @param constraints the message constraints. If <code>null</code>
+     *   {@link MessageConstraints#DEFAULT} will be used.
+     *
+     * @since 4.3
+     */
+    public DefaultHttpRequestParser(
+            final SessionInputBuffer buffer,
+            final LineParser lineParser,
+            final HttpRequestFactory requestFactory,
+            final MessageConstraints constraints) {
+        super(buffer, lineParser, constraints);
+        this.requestFactory = requestFactory != null ? requestFactory :
+            DefaultHttpRequestFactory.INSTANCE;
+        this.lineBuf = new CharArrayBuffer(128);
+    }
+
+    /**
+     * @since 4.3
+     */
+    public DefaultHttpRequestParser(
+            final SessionInputBuffer buffer,
+            final MessageConstraints constraints) {
+        this(buffer, null, null, constraints);
+    }
+
+    /**
+     * @since 4.3
+     */
+    public DefaultHttpRequestParser(final SessionInputBuffer buffer) {
+        this(buffer, null, null, MessageConstraints.DEFAULT);
+    }
+
     @Override
     protected HttpRequest parseHead(
             final SessionInputBuffer sessionBuffer)
         throws IOException, HttpException, ParseException {
 
         this.lineBuf.clear();
-        int i = sessionBuffer.readLine(this.lineBuf);
+        final int i = sessionBuffer.readLine(this.lineBuf);
         if (i == -1) {
             throw new ConnectionClosedException("Client closed connection");
         }
-        ParserCursor cursor = new ParserCursor(0, this.lineBuf.length());
-        RequestLine requestline = this.lineParser.parseRequestLine(this.lineBuf, cursor);
+        final ParserCursor cursor = new ParserCursor(0, this.lineBuf.length());
+        final RequestLine requestline = this.lineParser.parseRequestLine(this.lineBuf, cursor);
         return this.requestFactory.newHttpRequest(requestline);
     }
 
diff --git a/httpcore/src/main/java/org/apache/http/impl/io/DefaultHttpRequestParserFactory.java b/httpcore/src/main/java/org/apache/http/impl/io/DefaultHttpRequestParserFactory.java
new file mode 100644
index 0000000..fb37080
--- /dev/null
+++ b/httpcore/src/main/java/org/apache/http/impl/io/DefaultHttpRequestParserFactory.java
@@ -0,0 +1,71 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+
+package org.apache.http.impl.io;
+
+import org.apache.http.HttpRequest;
+import org.apache.http.HttpRequestFactory;
+import org.apache.http.annotation.Immutable;
+import org.apache.http.config.MessageConstraints;
+import org.apache.http.impl.DefaultHttpRequestFactory;
+import org.apache.http.io.HttpMessageParser;
+import org.apache.http.io.HttpMessageParserFactory;
+import org.apache.http.io.SessionInputBuffer;
+import org.apache.http.message.BasicLineParser;
+import org.apache.http.message.LineParser;
+
+/**
+ * Default factory for request message parsers.
+ *
+ * @since 4.3
+ */
+ at Immutable
+public class DefaultHttpRequestParserFactory implements HttpMessageParserFactory<HttpRequest> {
+
+    public static final DefaultHttpRequestParserFactory INSTANCE = new DefaultHttpRequestParserFactory();
+
+    private final LineParser lineParser;
+    private final HttpRequestFactory requestFactory;
+
+    public DefaultHttpRequestParserFactory(final LineParser lineParser,
+            final HttpRequestFactory requestFactory) {
+        super();
+        this.lineParser = lineParser != null ? lineParser : BasicLineParser.INSTANCE;
+        this.requestFactory = requestFactory != null ? requestFactory
+                : DefaultHttpRequestFactory.INSTANCE;
+    }
+
+    public DefaultHttpRequestParserFactory() {
+        this(null, null);
+    }
+
+    public HttpMessageParser<HttpRequest> create(final SessionInputBuffer buffer,
+            final MessageConstraints constraints) {
+        return new DefaultHttpRequestParser(buffer, lineParser, requestFactory, constraints);
+    }
+
+}
diff --git a/httpcore/src/main/java/org/apache/http/impl/io/HttpRequestWriter.java b/httpcore/src/main/java/org/apache/http/impl/io/DefaultHttpRequestWriter.java
similarity index 72%
copy from httpcore/src/main/java/org/apache/http/impl/io/HttpRequestWriter.java
copy to httpcore/src/main/java/org/apache/http/impl/io/DefaultHttpRequestWriter.java
index af57be2..2bb2990 100644
--- a/httpcore/src/main/java/org/apache/http/impl/io/HttpRequestWriter.java
+++ b/httpcore/src/main/java/org/apache/http/impl/io/DefaultHttpRequestWriter.java
@@ -33,21 +33,31 @@ import org.apache.http.HttpRequest;
 import org.apache.http.annotation.NotThreadSafe;
 import org.apache.http.io.SessionOutputBuffer;
 import org.apache.http.message.LineFormatter;
-import org.apache.http.params.HttpParams;
 
 /**
- * HTTP request writer that serializes its output to an instance
- * of {@link SessionOutputBuffer}.
+ * HTTP request writer that serializes its output to an instance of {@link SessionOutputBuffer}.
  *
- * @since 4.0
+ * @since 4.3
  */
 @NotThreadSafe
-public class HttpRequestWriter extends AbstractMessageWriter<HttpRequest> {
+public class DefaultHttpRequestWriter extends AbstractMessageWriter<HttpRequest> {
 
-    public HttpRequestWriter(final SessionOutputBuffer buffer,
-                             final LineFormatter formatter,
-                             final HttpParams params) {
-        super(buffer, formatter, params);
+    /**
+     * Creates an instance of DefaultHttpRequestWriter.
+     *
+     * @param buffer the session output buffer.
+     * @param formatter the line formatter If <code>null</code>
+     *   {@link org.apache.http.message.BasicLineFormatter#INSTANCE}
+     *   will be used.
+     */
+    public DefaultHttpRequestWriter(
+            final SessionOutputBuffer buffer,
+            final LineFormatter formatter) {
+        super(buffer, formatter);
+    }
+
+    public DefaultHttpRequestWriter(final SessionOutputBuffer buffer) {
+        this(buffer, null);
     }
 
     @Override
diff --git a/httpcore/src/main/java/org/apache/http/impl/io/HttpRequestWriter.java b/httpcore/src/main/java/org/apache/http/impl/io/DefaultHttpRequestWriterFactory.java
similarity index 59%
rename from httpcore/src/main/java/org/apache/http/impl/io/HttpRequestWriter.java
rename to httpcore/src/main/java/org/apache/http/impl/io/DefaultHttpRequestWriterFactory.java
index af57be2..a1bac76 100644
--- a/httpcore/src/main/java/org/apache/http/impl/io/HttpRequestWriter.java
+++ b/httpcore/src/main/java/org/apache/http/impl/io/DefaultHttpRequestWriterFactory.java
@@ -27,33 +27,37 @@
 
 package org.apache.http.impl.io;
 
-import java.io.IOException;
-
 import org.apache.http.HttpRequest;
-import org.apache.http.annotation.NotThreadSafe;
+import org.apache.http.annotation.Immutable;
+import org.apache.http.io.HttpMessageWriter;
+import org.apache.http.io.HttpMessageWriterFactory;
 import org.apache.http.io.SessionOutputBuffer;
+import org.apache.http.message.BasicLineFormatter;
 import org.apache.http.message.LineFormatter;
-import org.apache.http.params.HttpParams;
 
 /**
- * HTTP request writer that serializes its output to an instance
- * of {@link SessionOutputBuffer}.
+ * Default factory for request message writers.
  *
- * @since 4.0
+ * @since 4.3
  */
- at NotThreadSafe
-public class HttpRequestWriter extends AbstractMessageWriter<HttpRequest> {
+ at Immutable
+public class DefaultHttpRequestWriterFactory implements HttpMessageWriterFactory<HttpRequest> {
+
+    public static final DefaultHttpRequestWriterFactory INSTANCE = new DefaultHttpRequestWriterFactory();
+
+    private final LineFormatter lineFormatter;
+
+    public DefaultHttpRequestWriterFactory(final LineFormatter lineFormatter) {
+        super();
+        this.lineFormatter = lineFormatter != null ? lineFormatter : BasicLineFormatter.INSTANCE;
+    }
 
-    public HttpRequestWriter(final SessionOutputBuffer buffer,
-                             final LineFormatter formatter,
-                             final HttpParams params) {
-        super(buffer, formatter, params);
+    public DefaultHttpRequestWriterFactory() {
+        this(null);
     }
 
-    @Override
-    protected void writeHeadLine(final HttpRequest message) throws IOException {
-        lineFormatter.formatRequestLine(this.lineBuf, message.getRequestLine());
-        this.sessionBuffer.writeLine(this.lineBuf);
+    public HttpMessageWriter<HttpRequest> create(final SessionOutputBuffer buffer) {
+        return new DefaultHttpRequestWriter(buffer, lineFormatter);
     }
 
 }
diff --git a/httpcore/src/main/java/org/apache/http/impl/io/DefaultHttpResponseParser.java b/httpcore/src/main/java/org/apache/http/impl/io/DefaultHttpResponseParser.java
index fab7769..a11b97b 100644
--- a/httpcore/src/main/java/org/apache/http/impl/io/DefaultHttpResponseParser.java
+++ b/httpcore/src/main/java/org/apache/http/impl/io/DefaultHttpResponseParser.java
@@ -33,28 +33,25 @@ import org.apache.http.HttpException;
 import org.apache.http.HttpResponse;
 import org.apache.http.HttpResponseFactory;
 import org.apache.http.NoHttpResponseException;
-import org.apache.http.StatusLine;
 import org.apache.http.ParseException;
+import org.apache.http.StatusLine;
 import org.apache.http.annotation.NotThreadSafe;
+import org.apache.http.config.MessageConstraints;
+import org.apache.http.impl.DefaultHttpResponseFactory;
 import org.apache.http.io.SessionInputBuffer;
 import org.apache.http.message.LineParser;
 import org.apache.http.message.ParserCursor;
 import org.apache.http.params.HttpParams;
+import org.apache.http.util.Args;
 import org.apache.http.util.CharArrayBuffer;
 
 /**
  * HTTP response parser that obtain its input from an instance
  * of {@link SessionInputBuffer}.
- * <p>
- * The following parameters can be used to customize the behavior of this
- * class:
- * <ul>
- *  <li>{@link org.apache.http.params.CoreConnectionPNames#MAX_HEADER_COUNT}</li>
- *  <li>{@link org.apache.http.params.CoreConnectionPNames#MAX_LINE_LENGTH}</li>
- * </ul>
  *
  * @since 4.2
  */
+ at SuppressWarnings("deprecation")
 @NotThreadSafe
 public class DefaultHttpResponseParser extends AbstractMessageParser<HttpResponse> {
 
@@ -65,37 +62,79 @@ public class DefaultHttpResponseParser extends AbstractMessageParser<HttpRespons
      * Creates an instance of this class.
      *
      * @param buffer the session input buffer.
-     * @param parser the line parser.
+     * @param lineParser the line parser.
      * @param responseFactory the factory to use to create
      *    {@link HttpResponse}s.
      * @param params HTTP parameters.
+     *
+     * @deprecated (4.3) use
+     *   {@link DefaultHttpResponseParser#DefaultHttpResponseParser(SessionInputBuffer, LineParser,
+     *     HttpResponseFactory, MessageConstraints)}
      */
+    @Deprecated
     public DefaultHttpResponseParser(
             final SessionInputBuffer buffer,
-            final LineParser parser,
+            final LineParser lineParser,
             final HttpResponseFactory responseFactory,
             final HttpParams params) {
-        super(buffer, parser, params);
-        if (responseFactory == null) {
-            throw new IllegalArgumentException("Response factory may not be null");
-        }
-        this.responseFactory = responseFactory;
+        super(buffer, lineParser, params);
+        this.responseFactory = Args.notNull(responseFactory, "Response factory");
         this.lineBuf = new CharArrayBuffer(128);
     }
 
+    /**
+     * Creates new instance of DefaultHttpResponseParser.
+     *
+     * @param buffer the session input buffer.
+     * @param lineParser the line parser. If <code>null</code>
+     *   {@link org.apache.http.message.BasicLineParser#INSTANCE} will be used
+     * @param responseFactory the response factory. If <code>null</code>
+     *   {@link DefaultHttpResponseFactory#INSTANCE} will be used.
+     * @param constraints the message constraints. If <code>null</code>
+     *   {@link MessageConstraints#DEFAULT} will be used.
+     *
+     * @since 4.3
+     */
+    public DefaultHttpResponseParser(
+            final SessionInputBuffer buffer,
+            final LineParser lineParser,
+            final HttpResponseFactory responseFactory,
+            final MessageConstraints constraints) {
+        super(buffer, lineParser, constraints);
+        this.responseFactory = responseFactory != null ? responseFactory :
+            DefaultHttpResponseFactory.INSTANCE;
+        this.lineBuf = new CharArrayBuffer(128);
+    }
+
+    /**
+     * @since 4.3
+     */
+    public DefaultHttpResponseParser(
+            final SessionInputBuffer buffer,
+            final MessageConstraints constraints) {
+        this(buffer, null, null, constraints);
+    }
+
+    /**
+     * @since 4.3
+     */
+    public DefaultHttpResponseParser(final SessionInputBuffer buffer) {
+        this(buffer, null, null, MessageConstraints.DEFAULT);
+    }
+
     @Override
     protected HttpResponse parseHead(
             final SessionInputBuffer sessionBuffer)
         throws IOException, HttpException, ParseException {
 
         this.lineBuf.clear();
-        int i = sessionBuffer.readLine(this.lineBuf);
+        final int i = sessionBuffer.readLine(this.lineBuf);
         if (i == -1) {
             throw new NoHttpResponseException("The target server failed to respond");
         }
         //create the status line from the status string
-        ParserCursor cursor = new ParserCursor(0, this.lineBuf.length());
-        StatusLine statusline = lineParser.parseStatusLine(this.lineBuf, cursor);
+        final ParserCursor cursor = new ParserCursor(0, this.lineBuf.length());
+        final StatusLine statusline = lineParser.parseStatusLine(this.lineBuf, cursor);
         return this.responseFactory.newHttpResponse(statusline, null);
     }
 
diff --git a/httpcore/src/main/java/org/apache/http/impl/io/DefaultHttpResponseParserFactory.java b/httpcore/src/main/java/org/apache/http/impl/io/DefaultHttpResponseParserFactory.java
new file mode 100644
index 0000000..8a0b2c7
--- /dev/null
+++ b/httpcore/src/main/java/org/apache/http/impl/io/DefaultHttpResponseParserFactory.java
@@ -0,0 +1,71 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+
+package org.apache.http.impl.io;
+
+import org.apache.http.HttpResponse;
+import org.apache.http.HttpResponseFactory;
+import org.apache.http.annotation.Immutable;
+import org.apache.http.config.MessageConstraints;
+import org.apache.http.impl.DefaultHttpResponseFactory;
+import org.apache.http.io.HttpMessageParser;
+import org.apache.http.io.HttpMessageParserFactory;
+import org.apache.http.io.SessionInputBuffer;
+import org.apache.http.message.BasicLineParser;
+import org.apache.http.message.LineParser;
+
+/**
+ * Default factory for response message parsers.
+ *
+ * @since 4.3
+ */
+ at Immutable
+public class DefaultHttpResponseParserFactory implements HttpMessageParserFactory<HttpResponse> {
+
+    public static final DefaultHttpResponseParserFactory INSTANCE = new DefaultHttpResponseParserFactory();
+
+    private final LineParser lineParser;
+    private final HttpResponseFactory responseFactory;
+
+    public DefaultHttpResponseParserFactory(final LineParser lineParser,
+            final HttpResponseFactory responseFactory) {
+        super();
+        this.lineParser = lineParser != null ? lineParser : BasicLineParser.INSTANCE;
+        this.responseFactory = responseFactory != null ? responseFactory
+                : DefaultHttpResponseFactory.INSTANCE;
+    }
+
+    public DefaultHttpResponseParserFactory() {
+        this(null, null);
+    }
+
+    public HttpMessageParser<HttpResponse> create(final SessionInputBuffer buffer,
+            final MessageConstraints constraints) {
+        return new DefaultHttpResponseParser(buffer, lineParser, responseFactory, constraints);
+    }
+
+}
diff --git a/httpcore/src/main/java/org/apache/http/impl/io/HttpResponseWriter.java b/httpcore/src/main/java/org/apache/http/impl/io/DefaultHttpResponseWriter.java
similarity index 71%
copy from httpcore/src/main/java/org/apache/http/impl/io/HttpResponseWriter.java
copy to httpcore/src/main/java/org/apache/http/impl/io/DefaultHttpResponseWriter.java
index bcefdb4..38b05bd 100644
--- a/httpcore/src/main/java/org/apache/http/impl/io/HttpResponseWriter.java
+++ b/httpcore/src/main/java/org/apache/http/impl/io/DefaultHttpResponseWriter.java
@@ -33,21 +33,31 @@ import org.apache.http.HttpResponse;
 import org.apache.http.annotation.NotThreadSafe;
 import org.apache.http.io.SessionOutputBuffer;
 import org.apache.http.message.LineFormatter;
-import org.apache.http.params.HttpParams;
 
 /**
- * HTTP response writer that serializes its output to an instance
- * of {@link SessionOutputBuffer}.
+ * HTTP response writer that serializes its output to an instance of {@link SessionOutputBuffer}.
  *
- * @since 4.0
+ * @since 4.3
  */
 @NotThreadSafe
-public class HttpResponseWriter extends AbstractMessageWriter<HttpResponse> {
+public class DefaultHttpResponseWriter extends AbstractMessageWriter<HttpResponse> {
 
-    public HttpResponseWriter(final SessionOutputBuffer buffer,
-                              final LineFormatter formatter,
-                              final HttpParams params) {
-        super(buffer, formatter, params);
+    /**
+     * Creates an instance of DefaultHttpResponseWriter.
+     *
+     * @param buffer the session output buffer.
+     * @param formatter the line formatter If <code>null</code>
+     *  {@link org.apache.http.message.BasicLineFormatter#INSTANCE}
+     *   will be used.
+     */
+    public DefaultHttpResponseWriter(
+            final SessionOutputBuffer buffer,
+            final LineFormatter formatter) {
+        super(buffer, formatter);
+    }
+
+    public DefaultHttpResponseWriter(final SessionOutputBuffer buffer) {
+        super(buffer, null);
     }
 
     @Override
diff --git a/httpcore/src/main/java/org/apache/http/impl/io/HttpResponseWriter.java b/httpcore/src/main/java/org/apache/http/impl/io/DefaultHttpResponseWriterFactory.java
similarity index 59%
rename from httpcore/src/main/java/org/apache/http/impl/io/HttpResponseWriter.java
rename to httpcore/src/main/java/org/apache/http/impl/io/DefaultHttpResponseWriterFactory.java
index bcefdb4..f54d13b 100644
--- a/httpcore/src/main/java/org/apache/http/impl/io/HttpResponseWriter.java
+++ b/httpcore/src/main/java/org/apache/http/impl/io/DefaultHttpResponseWriterFactory.java
@@ -27,33 +27,37 @@
 
 package org.apache.http.impl.io;
 
-import java.io.IOException;
-
 import org.apache.http.HttpResponse;
-import org.apache.http.annotation.NotThreadSafe;
+import org.apache.http.annotation.Immutable;
+import org.apache.http.io.HttpMessageWriter;
+import org.apache.http.io.HttpMessageWriterFactory;
 import org.apache.http.io.SessionOutputBuffer;
+import org.apache.http.message.BasicLineFormatter;
 import org.apache.http.message.LineFormatter;
-import org.apache.http.params.HttpParams;
 
 /**
- * HTTP response writer that serializes its output to an instance
- * of {@link SessionOutputBuffer}.
+ * Default factory for response message writers.
  *
- * @since 4.0
+ * @since 4.3
  */
- at NotThreadSafe
-public class HttpResponseWriter extends AbstractMessageWriter<HttpResponse> {
+ at Immutable
+public class DefaultHttpResponseWriterFactory implements HttpMessageWriterFactory<HttpResponse> {
+
+    public static final DefaultHttpResponseWriterFactory INSTANCE = new DefaultHttpResponseWriterFactory();
+
+    private final LineFormatter lineFormatter;
+
+    public DefaultHttpResponseWriterFactory(final LineFormatter lineFormatter) {
+        super();
+        this.lineFormatter = lineFormatter != null ? lineFormatter : BasicLineFormatter.INSTANCE;
+    }
 
-    public HttpResponseWriter(final SessionOutputBuffer buffer,
-                              final LineFormatter formatter,
-                              final HttpParams params) {
-        super(buffer, formatter, params);
+    public DefaultHttpResponseWriterFactory() {
+        this(null);
     }
 
-    @Override
-    protected void writeHeadLine(final HttpResponse message) throws IOException {
-        lineFormatter.formatStatusLine(this.lineBuf, message.getStatusLine());
-        this.sessionBuffer.writeLine(this.lineBuf);
+    public HttpMessageWriter<HttpResponse> create(final SessionOutputBuffer buffer) {
+        return new DefaultHttpResponseWriter(buffer, lineFormatter);
     }
 
 }
diff --git a/httpcore/src/main/java/org/apache/http/impl/io/HttpTransportMetricsImpl.java b/httpcore/src/main/java/org/apache/http/impl/io/HttpTransportMetricsImpl.java
index 9e8f55b..f982765 100644
--- a/httpcore/src/main/java/org/apache/http/impl/io/HttpTransportMetricsImpl.java
+++ b/httpcore/src/main/java/org/apache/http/impl/io/HttpTransportMetricsImpl.java
@@ -48,11 +48,11 @@ public class HttpTransportMetricsImpl implements HttpTransportMetrics {
         return this.bytesTransferred;
     }
 
-    public void setBytesTransferred(long count) {
+    public void setBytesTransferred(final long count) {
         this.bytesTransferred = count;
     }
 
-    public void incrementBytesTransferred(long count) {
+    public void incrementBytesTransferred(final long count) {
         this.bytesTransferred += count;
     }
 
diff --git a/httpcore/src/main/java/org/apache/http/impl/io/IdentityInputStream.java b/httpcore/src/main/java/org/apache/http/impl/io/IdentityInputStream.java
index cb7bb97..e593b35 100644
--- a/httpcore/src/main/java/org/apache/http/impl/io/IdentityInputStream.java
+++ b/httpcore/src/main/java/org/apache/http/impl/io/IdentityInputStream.java
@@ -33,6 +33,7 @@ import java.io.InputStream;
 import org.apache.http.annotation.NotThreadSafe;
 import org.apache.http.io.BufferInfo;
 import org.apache.http.io.SessionInputBuffer;
+import org.apache.http.util.Args;
 
 /**
  * Input stream that reads data without any transformation. The end of the
@@ -60,10 +61,7 @@ public class IdentityInputStream extends InputStream {
      */
     public IdentityInputStream(final SessionInputBuffer in) {
         super();
-        if (in == null) {
-            throw new IllegalArgumentException("Session input buffer may not be null");
-        }
-        this.in = in;
+        this.in = Args.notNull(in, "Session input buffer");
     }
 
     @Override
@@ -90,7 +88,7 @@ public class IdentityInputStream extends InputStream {
     }
 
     @Override
-    public int read(final byte[] b, int off, int len) throws IOException {
+    public int read(final byte[] b, final int off, final int len) throws IOException {
         if (this.closed) {
             return -1;
         } else {
diff --git a/httpcore/src/main/java/org/apache/http/impl/io/IdentityOutputStream.java b/httpcore/src/main/java/org/apache/http/impl/io/IdentityOutputStream.java
index 56ee27f..103e28e 100644
--- a/httpcore/src/main/java/org/apache/http/impl/io/IdentityOutputStream.java
+++ b/httpcore/src/main/java/org/apache/http/impl/io/IdentityOutputStream.java
@@ -32,6 +32,7 @@ import java.io.OutputStream;
 
 import org.apache.http.annotation.NotThreadSafe;
 import org.apache.http.io.SessionOutputBuffer;
+import org.apache.http.util.Args;
 
 /**
  * Output stream that writes data without any transformation. The end of
@@ -58,10 +59,7 @@ public class IdentityOutputStream extends OutputStream {
 
     public IdentityOutputStream(final SessionOutputBuffer out) {
         super();
-        if (out == null) {
-            throw new IllegalArgumentException("Session output buffer may not be null");
-        }
-        this.out = out;
+        this.out = Args.notNull(out, "Session output buffer");
     }
 
     /**
@@ -83,7 +81,7 @@ public class IdentityOutputStream extends OutputStream {
     }
 
     @Override
-    public void write(byte[] b, int off, int len) throws IOException {
+    public void write(final byte[] b, final int off, final int len) throws IOException {
         if (this.closed) {
             throw new IOException("Attempted write to closed stream.");
         }
@@ -91,12 +89,12 @@ public class IdentityOutputStream extends OutputStream {
     }
 
     @Override
-    public void write(byte[] b) throws IOException {
+    public void write(final byte[] b) throws IOException {
         write(b, 0, b.length);
     }
 
     @Override
-    public void write(int b) throws IOException {
+    public void write(final int b) throws IOException {
         if (this.closed) {
             throw new IOException("Attempted write to closed stream.");
         }
diff --git a/httpcore/src/main/java/org/apache/http/impl/io/AbstractSessionInputBuffer.java b/httpcore/src/main/java/org/apache/http/impl/io/SessionInputBufferImpl.java
similarity index 68%
rename from httpcore/src/main/java/org/apache/http/impl/io/AbstractSessionInputBuffer.java
rename to httpcore/src/main/java/org/apache/http/impl/io/SessionInputBufferImpl.java
index b160164..801c221 100644
--- a/httpcore/src/main/java/org/apache/http/impl/io/AbstractSessionInputBuffer.java
+++ b/httpcore/src/main/java/org/apache/http/impl/io/SessionInputBufferImpl.java
@@ -31,19 +31,18 @@ import java.io.IOException;
 import java.io.InputStream;
 import java.nio.ByteBuffer;
 import java.nio.CharBuffer;
-import java.nio.charset.Charset;
 import java.nio.charset.CharsetDecoder;
 import java.nio.charset.CoderResult;
-import java.nio.charset.CodingErrorAction;
 
+import org.apache.http.MessageConstraintException;
 import org.apache.http.annotation.NotThreadSafe;
+import org.apache.http.config.MessageConstraints;
 import org.apache.http.io.BufferInfo;
-import org.apache.http.io.SessionInputBuffer;
 import org.apache.http.io.HttpTransportMetrics;
-import org.apache.http.params.CoreConnectionPNames;
-import org.apache.http.params.HttpParams;
-import org.apache.http.params.HttpProtocolParams;
+import org.apache.http.io.SessionInputBuffer;
 import org.apache.http.protocol.HTTP;
+import org.apache.http.util.Args;
+import org.apache.http.util.Asserts;
 import org.apache.http.util.ByteArrayBuffer;
 import org.apache.http.util.CharArrayBuffer;
 
@@ -51,119 +50,106 @@ import org.apache.http.util.CharArrayBuffer;
  * Abstract base class for session input buffers that stream data from
  * an arbitrary {@link InputStream}. This class buffers input data in
  * an internal byte array for optimal input performance.
- * <p>
+ * <p/>
  * {@link #readLine(CharArrayBuffer)} and {@link #readLine()} methods of this
  * class treat a lone LF as valid line delimiters in addition to CR-LF required
  * by the HTTP specification.
  *
- * <p>
- * The following parameters can be used to customize the behavior of this
- * class:
- * <ul>
- *  <li>{@link org.apache.http.params.CoreProtocolPNames#HTTP_ELEMENT_CHARSET}</li>
- *  <li>{@link org.apache.http.params.CoreConnectionPNames#MAX_LINE_LENGTH}</li>
- *  <li>{@link org.apache.http.params.CoreConnectionPNames#MIN_CHUNK_LIMIT}</li>
- * </ul>
- * @since 4.0
+ * @since 4.3
  */
 @NotThreadSafe
-public abstract class AbstractSessionInputBuffer implements SessionInputBuffer, BufferInfo {
+public class SessionInputBufferImpl implements SessionInputBuffer, BufferInfo {
 
-    private static final Charset ASCII = Charset.forName("US-ASCII");
+    private final HttpTransportMetricsImpl metrics;
+    private final byte[] buffer;
+    private final ByteArrayBuffer linebuffer;
+    private final int minChunkLimit;
+    private final MessageConstraints constraints;
+    private final CharsetDecoder decoder;
 
     private InputStream instream;
-    private byte[] buffer;
     private int bufferpos;
     private int bufferlen;
-
-    private ByteArrayBuffer linebuffer = null;
-
-    private Charset charset;
-    private CharsetDecoder decoder;
     private CharBuffer cbuf;
-    private boolean ascii = true;
-    private int maxLineLen = -1;
-    private int minChunkLimit = 512;
-
-    private HttpTransportMetricsImpl metrics;
-
-    private CodingErrorAction onMalformedInputAction;
-    private CodingErrorAction onUnMappableInputAction;
 
     /**
-     * Initializes this session input buffer.
+     * Creates new instance of SessionInputBufferImpl.
      *
-     * @param instream the source input stream.
-     * @param buffersize the size of the internal buffer.
-     * @param params HTTP parameters.
+     * @param metrics HTTP transport metrics.
+     * @param buffersize buffer size. Must be a positive number.
+     * @param minChunkLimit size limit below which data chunks should be buffered in memory
+     *   in order to minimize native method invocations on the underlying network socket.
+     *   The optimal value of this parameter can be platform specific and defines a trade-off
+     *   between performance of memory copy operations and that of native method invocation.
+     *   If negative default chunk limited will be used.
+     * @param constraints Message constraints. If <code>null</code>
+     *   {@link MessageConstraints#DEFAULT} will be used.
+     * @param chardecoder chardecoder to be used for decoding HTTP protocol elements.
+     *   If <code>null</code> simple type cast will be used for byte to char conversion.
      */
-    protected void init(final InputStream instream, int buffersize, final HttpParams params) {
-        if (instream == null) {
-            throw new IllegalArgumentException("Input stream may not be null");
-        }
-        if (buffersize <= 0) {
-            throw new IllegalArgumentException("Buffer size may not be negative or zero");
-        }
-        if (params == null) {
-            throw new IllegalArgumentException("HTTP parameters may not be null");
-        }
-        this.instream = instream;
+    public SessionInputBufferImpl(
+            final HttpTransportMetricsImpl metrics,
+            final int buffersize,
+            final int minChunkLimit,
+            final MessageConstraints constraints,
+            final CharsetDecoder chardecoder) {
+        Args.notNull(metrics, "HTTP transport metrcis");
+        Args.positive(buffersize, "Buffer size");
+        this.metrics = metrics;
         this.buffer = new byte[buffersize];
         this.bufferpos = 0;
         this.bufferlen = 0;
+        this.minChunkLimit = minChunkLimit >= 0 ? minChunkLimit : 512;
+        this.constraints = constraints != null ? constraints : MessageConstraints.DEFAULT;
         this.linebuffer = new ByteArrayBuffer(buffersize);
-        this.charset = Charset.forName(HttpProtocolParams.getHttpElementCharset(params));
-        this.ascii = this.charset.equals(ASCII);
-        this.decoder = null;
-        this.maxLineLen = params.getIntParameter(CoreConnectionPNames.MAX_LINE_LENGTH, -1);
-        this.minChunkLimit = params.getIntParameter(CoreConnectionPNames.MIN_CHUNK_LIMIT, 512);
-        this.metrics = createTransportMetrics();
-        this.onMalformedInputAction = HttpProtocolParams.getMalformedInputAction(params);
-        this.onUnMappableInputAction = HttpProtocolParams.getUnmappableInputAction(params);
+        this.decoder = chardecoder;
     }
 
-    /**
-     * @since 4.1
-     */
-    protected HttpTransportMetricsImpl createTransportMetrics() {
-        return new HttpTransportMetricsImpl();
+    public SessionInputBufferImpl(
+            final HttpTransportMetricsImpl metrics,
+            final int buffersize) {
+        this(metrics, buffersize, buffersize, null, null);
+    }
+
+    public void bind(final InputStream instream) {
+        this.instream = instream;
+    }
+
+    public boolean isBound() {
+        return this.instream != null;
     }
 
-    /**
-     * @since 4.1
-     */
     public int capacity() {
         return this.buffer.length;
     }
 
-    /**
-     * @since 4.1
-     */
     public int length() {
         return this.bufferlen - this.bufferpos;
     }
 
-    /**
-     * @since 4.1
-     */
     public int available() {
         return capacity() - length();
     }
 
-    protected int fillBuffer() throws IOException {
+    private int streamRead(final byte[] b, final int off, final int len) throws IOException {
+        Asserts.notNull(this.instream, "Input stream");
+        return this.instream.read(b, off, len);
+    }
+
+    public int fillBuffer() throws IOException {
         // compact the buffer if necessary
         if (this.bufferpos > 0) {
-            int len = this.bufferlen - this.bufferpos;
+            final int len = this.bufferlen - this.bufferpos;
             if (len > 0) {
                 System.arraycopy(this.buffer, this.bufferpos, this.buffer, 0, len);
             }
             this.bufferpos = 0;
             this.bufferlen = len;
         }
-        int l;
-        int off = this.bufferlen;
-        int len = this.buffer.length - off;
-        l = this.instream.read(this.buffer, off, len);
+        final int l;
+        final int off = this.bufferlen;
+        final int len = this.buffer.length - off;
+        l = streamRead(this.buffer, off, len);
         if (l == -1) {
             return -1;
         } else {
@@ -173,12 +159,17 @@ public abstract class AbstractSessionInputBuffer implements SessionInputBuffer,
         }
     }
 
-    protected boolean hasBufferedData() {
+    public boolean hasBufferedData() {
         return this.bufferpos < this.bufferlen;
     }
 
+    public void clear() {
+        this.bufferpos = 0;
+        this.bufferlen = 0;
+    }
+
     public int read() throws IOException {
-        int noRead = 0;
+        int noRead;
         while (!hasBufferedData()) {
             noRead = fillBuffer();
             if (noRead == -1) {
@@ -188,12 +179,12 @@ public abstract class AbstractSessionInputBuffer implements SessionInputBuffer,
         return this.buffer[this.bufferpos++] & 0xff;
     }
 
-    public int read(final byte[] b, int off, int len) throws IOException {
+    public int read(final byte[] b, final int off, final int len) throws IOException {
         if (b == null) {
             return 0;
         }
         if (hasBufferedData()) {
-            int chunk = Math.min(len, this.bufferlen - this.bufferpos);
+            final int chunk = Math.min(len, this.bufferlen - this.bufferpos);
             System.arraycopy(this.buffer, this.bufferpos, b, off, chunk);
             this.bufferpos += chunk;
             return chunk;
@@ -201,7 +192,7 @@ public abstract class AbstractSessionInputBuffer implements SessionInputBuffer,
         // If the remaining capacity is big enough, read directly from the
         // underlying input stream bypassing the buffer.
         if (len > this.minChunkLimit) {
-            int read = this.instream.read(b, off, len);
+            final int read = streamRead(b, off, len);
             if (read > 0) {
                 this.metrics.incrementBytesTransferred(read);
             }
@@ -209,12 +200,12 @@ public abstract class AbstractSessionInputBuffer implements SessionInputBuffer,
         } else {
             // otherwise read to the buffer first
             while (!hasBufferedData()) {
-                int noRead = fillBuffer();
+                final int noRead = fillBuffer();
                 if (noRead == -1) {
                     return -1;
                 }
             }
-            int chunk = Math.min(len, this.bufferlen - this.bufferpos);
+            final int chunk = Math.min(len, this.bufferlen - this.bufferpos);
             System.arraycopy(this.buffer, this.bufferpos, b, off, chunk);
             this.bufferpos += chunk;
             return chunk;
@@ -253,14 +244,12 @@ public abstract class AbstractSessionInputBuffer implements SessionInputBuffer,
      * @exception  IOException  if an I/O error occurs.
      */
     public int readLine(final CharArrayBuffer charbuffer) throws IOException {
-        if (charbuffer == null) {
-            throw new IllegalArgumentException("Char array buffer may not be null");
-        }
+        Args.notNull(charbuffer, "Char array buffer");
         int noRead = 0;
         boolean retry = true;
         while (retry) {
             // attempt to find end of line (LF)
-            int i = locateLF();
+            final int i = locateLF();
             if (i != -1) {
                 // end of line found.
                 if (this.linebuffer.isEmpty()) {
@@ -268,13 +257,13 @@ public abstract class AbstractSessionInputBuffer implements SessionInputBuffer,
                     return lineFromReadBuffer(charbuffer, i);
                 }
                 retry = false;
-                int len = i + 1 - this.bufferpos;
+                final int len = i + 1 - this.bufferpos;
                 this.linebuffer.append(this.buffer, this.bufferpos, len);
                 this.bufferpos = i + 1;
             } else {
                 // end of line not found
                 if (hasBufferedData()) {
-                    int len = this.bufferlen - this.bufferpos;
+                    final int len = this.bufferlen - this.bufferpos;
                     this.linebuffer.append(this.buffer, this.bufferpos, len);
                     this.bufferpos = this.bufferlen;
                 }
@@ -283,8 +272,9 @@ public abstract class AbstractSessionInputBuffer implements SessionInputBuffer,
                     retry = false;
                 }
             }
-            if (this.maxLineLen > 0 && this.linebuffer.length() >= this.maxLineLen) {
-                throw new IOException("Maximum line length limit exceeded");
+            final int maxLineLen = this.constraints.getMaxLineLength();
+            if (maxLineLen > 0 && this.linebuffer.length() >= maxLineLen) {
+                throw new MessageConstraintException("Maximum line length limit exceeded");
             }
         }
         if (noRead == -1 && this.linebuffer.isEmpty()) {
@@ -322,19 +312,20 @@ public abstract class AbstractSessionInputBuffer implements SessionInputBuffer,
                 }
             }
         }
-        if (this.ascii) {
+        if (this.decoder == null) {
             charbuffer.append(this.linebuffer, 0, len);
         } else {
-            ByteBuffer bbuf =  ByteBuffer.wrap(this.linebuffer.buffer(), 0, len);
+            final ByteBuffer bbuf =  ByteBuffer.wrap(this.linebuffer.buffer(), 0, len);
             len = appendDecoded(charbuffer, bbuf);
         }
         this.linebuffer.clear();
         return len;
     }
 
-    private int lineFromReadBuffer(final CharArrayBuffer charbuffer, int pos)
+    private int lineFromReadBuffer(final CharArrayBuffer charbuffer, final int position)
             throws IOException {
-        int off = this.bufferpos;
+        int pos = position;
+        final int off = this.bufferpos;
         int len;
         this.bufferpos = pos + 1;
         if (pos > off && this.buffer[pos - 1] == HTTP.CR) {
@@ -342,10 +333,10 @@ public abstract class AbstractSessionInputBuffer implements SessionInputBuffer,
             pos--;
         }
         len = pos - off;
-        if (this.ascii) {
+        if (this.decoder == null) {
             charbuffer.append(this.buffer, off, len);
         } else {
-            ByteBuffer bbuf =  ByteBuffer.wrap(this.buffer, off, len);
+            final ByteBuffer bbuf =  ByteBuffer.wrap(this.buffer, off, len);
             len = appendDecoded(charbuffer, bbuf);
         }
         return len;
@@ -356,21 +347,16 @@ public abstract class AbstractSessionInputBuffer implements SessionInputBuffer,
         if (!bbuf.hasRemaining()) {
             return 0;
         }
-        if (this.decoder == null) {
-            this.decoder = this.charset.newDecoder();
-            this.decoder.onMalformedInput(this.onMalformedInputAction);
-            this.decoder.onUnmappableCharacter(this.onUnMappableInputAction);
-        }
         if (this.cbuf == null) {
             this.cbuf = CharBuffer.allocate(1024);
         }
         this.decoder.reset();
         int len = 0;
         while (bbuf.hasRemaining()) {
-            CoderResult result = this.decoder.decode(bbuf, this.cbuf, true);
+            final CoderResult result = this.decoder.decode(bbuf, this.cbuf, true);
             len += handleDecodingResult(result, charbuffer, bbuf);
         }
-        CoderResult result = this.decoder.flush(this.cbuf);
+        final CoderResult result = this.decoder.flush(this.cbuf);
         len += handleDecodingResult(result, charbuffer, bbuf);
         this.cbuf.clear();
         return len;
@@ -384,7 +370,7 @@ public abstract class AbstractSessionInputBuffer implements SessionInputBuffer,
             result.throwException();
         }
         this.cbuf.flip();
-        int len = this.cbuf.remaining();
+        final int len = this.cbuf.remaining();
         while (this.cbuf.hasRemaining()) {
             charbuffer.append(this.cbuf.get());
         }
@@ -393,8 +379,8 @@ public abstract class AbstractSessionInputBuffer implements SessionInputBuffer,
     }
 
     public String readLine() throws IOException {
-        CharArrayBuffer charbuffer = new CharArrayBuffer(64);
-        int l = readLine(charbuffer);
+        final CharArrayBuffer charbuffer = new CharArrayBuffer(64);
+        final int l = readLine(charbuffer);
         if (l != -1) {
             return charbuffer.toString();
         } else {
@@ -402,6 +388,10 @@ public abstract class AbstractSessionInputBuffer implements SessionInputBuffer,
         }
     }
 
+    public boolean isDataAvailable(final int timeout) throws IOException {
+        return hasBufferedData();
+    }
+
     public HttpTransportMetrics getMetrics() {
         return this.metrics;
     }
diff --git a/httpcore/src/main/java/org/apache/http/impl/io/AbstractSessionOutputBuffer.java b/httpcore/src/main/java/org/apache/http/impl/io/SessionOutputBufferImpl.java
similarity index 63%
rename from httpcore/src/main/java/org/apache/http/impl/io/AbstractSessionOutputBuffer.java
rename to httpcore/src/main/java/org/apache/http/impl/io/SessionOutputBufferImpl.java
index 492704d..708b492 100644
--- a/httpcore/src/main/java/org/apache/http/impl/io/AbstractSessionOutputBuffer.java
+++ b/httpcore/src/main/java/org/apache/http/impl/io/SessionOutputBufferImpl.java
@@ -31,19 +31,16 @@ import java.io.IOException;
 import java.io.OutputStream;
 import java.nio.ByteBuffer;
 import java.nio.CharBuffer;
-import java.nio.charset.Charset;
 import java.nio.charset.CharsetEncoder;
 import java.nio.charset.CoderResult;
-import java.nio.charset.CodingErrorAction;
 
 import org.apache.http.annotation.NotThreadSafe;
 import org.apache.http.io.BufferInfo;
-import org.apache.http.io.SessionOutputBuffer;
 import org.apache.http.io.HttpTransportMetrics;
-import org.apache.http.params.CoreConnectionPNames;
-import org.apache.http.params.HttpParams;
-import org.apache.http.params.HttpProtocolParams;
+import org.apache.http.io.SessionOutputBuffer;
 import org.apache.http.protocol.HTTP;
+import org.apache.http.util.Args;
+import org.apache.http.util.Asserts;
 import org.apache.http.util.ByteArrayBuffer;
 import org.apache.http.util.CharArrayBuffer;
 
@@ -51,100 +48,91 @@ import org.apache.http.util.CharArrayBuffer;
  * Abstract base class for session output buffers that stream data to
  * an arbitrary {@link OutputStream}. This class buffers small chunks of
  * output data in an internal byte array for optimal output performance.
- * <p>
+ * </p>
  * {@link #writeLine(CharArrayBuffer)} and {@link #writeLine(String)} methods
  * of this class use CR-LF as a line delimiter.
- * <p>
- * The following parameters can be used to customize the behavior of this
- * class:
- * <ul>
- *  <li>{@link org.apache.http.params.CoreProtocolPNames#HTTP_ELEMENT_CHARSET}</li>
- *  <li>{@link org.apache.http.params.CoreConnectionPNames#MIN_CHUNK_LIMIT}</li>
- * </ul>
- * <p>
  *
- * @since 4.0
+ * @since 4.3
  */
 @NotThreadSafe
-public abstract class AbstractSessionOutputBuffer implements SessionOutputBuffer, BufferInfo {
+public class SessionOutputBufferImpl implements SessionOutputBuffer, BufferInfo {
 
-    private static final Charset ASCII = Charset.forName("US-ASCII");
     private static final byte[] CRLF = new byte[] {HTTP.CR, HTTP.LF};
 
-    private OutputStream outstream;
-    private ByteArrayBuffer buffer;
+    private final HttpTransportMetricsImpl metrics;
+    private final ByteArrayBuffer buffer;
+    private final int fragementSizeHint;
+    private final CharsetEncoder encoder;
 
-    private Charset charset;
-    private CharsetEncoder encoder;
+    private OutputStream outstream;
     private ByteBuffer bbuf;
-    private boolean ascii = true;
-    private int minChunkLimit = 512;
-
-    private HttpTransportMetricsImpl metrics;
-
-    private CodingErrorAction onMalformedInputAction;
-    private CodingErrorAction onUnMappableInputAction;
 
     /**
-     * Initializes this session output buffer.
+     * Creates new instance of SessionOutputBufferImpl.
      *
-     * @param outstream the destination output stream.
-     * @param buffersize the size of the internal buffer.
-     * @param params HTTP parameters.
+     * @param metrics HTTP transport metrics.
+     * @param buffersize buffer size. Must be a positive number.
+     * @param fragementSizeHint fragment size hint defining a minimal size of a fragment
+     *   that should be written out directly to the socket bypassing the session buffer.
+     *   Value <code>0</code> disables fragment buffering.
+     * @param charencoder charencoder to be used for encoding HTTP protocol elements.
+     *   If <code>null</code> simple type cast will be used for char to byte conversion.
      */
-    protected void init(final OutputStream outstream, int buffersize, final HttpParams params) {
-        if (outstream == null) {
-            throw new IllegalArgumentException("Input stream may not be null");
-        }
-        if (buffersize <= 0) {
-            throw new IllegalArgumentException("Buffer size may not be negative or zero");
-        }
-        if (params == null) {
-            throw new IllegalArgumentException("HTTP parameters may not be null");
-        }
-        this.outstream = outstream;
+    public SessionOutputBufferImpl(
+            final HttpTransportMetricsImpl metrics,
+            final int buffersize,
+            final int fragementSizeHint,
+            final CharsetEncoder charencoder) {
+        super();
+        Args.positive(buffersize, "Buffer size");
+        Args.notNull(metrics, "HTTP transport metrcis");
+        this.metrics = metrics;
         this.buffer = new ByteArrayBuffer(buffersize);
-        this.charset = Charset.forName(HttpProtocolParams.getHttpElementCharset(params));
-        this.ascii = this.charset.equals(ASCII);
-        this.encoder = null;
-        this.minChunkLimit = params.getIntParameter(CoreConnectionPNames.MIN_CHUNK_LIMIT, 512);
-        this.metrics = createTransportMetrics();
-        this.onMalformedInputAction = HttpProtocolParams.getMalformedInputAction(params);
-        this.onUnMappableInputAction = HttpProtocolParams.getUnmappableInputAction(params);
+        this.fragementSizeHint = fragementSizeHint >= 0 ? fragementSizeHint : 0;
+        this.encoder = charencoder;
     }
 
-    /**
-     * @since 4.1
-     */
-    protected HttpTransportMetricsImpl createTransportMetrics() {
-        return new HttpTransportMetricsImpl();
+    public SessionOutputBufferImpl(
+            final HttpTransportMetricsImpl metrics,
+            final int buffersize) {
+        this(metrics, buffersize, buffersize, null);
+    }
+
+    public void bind(final OutputStream outstream) {
+        this.outstream = outstream;
+    }
+
+    public boolean isBound() {
+        return this.outstream != null;
     }
 
-    /**
-     * @since 4.1
-     */
     public int capacity() {
         return this.buffer.capacity();
     }
 
-    /**
-     * @since 4.1
-     */
     public int length() {
         return this.buffer.length();
     }
 
-    /**
-     * @since 4.1
-     */
     public int available() {
         return capacity() - length();
     }
 
-    protected void flushBuffer() throws IOException {
-        int len = this.buffer.length();
+    private void streamWrite(final byte[] b, final int off, final int len) throws IOException {
+        Asserts.notNull(outstream, "Output stream");
+        this.outstream.write(b, off, len);
+    }
+
+    private void flushStream() throws IOException {
+        if (this.outstream != null) {
+            this.outstream.flush();
+        }
+    }
+
+    private void flushBuffer() throws IOException {
+        final int len = this.buffer.length();
         if (len > 0) {
-            this.outstream.write(this.buffer.buffer(), 0, len);
+            streamWrite(this.buffer.buffer(), 0, len);
             this.buffer.clear();
             this.metrics.incrementBytesTransferred(len);
         }
@@ -152,25 +140,25 @@ public abstract class AbstractSessionOutputBuffer implements SessionOutputBuffer
 
     public void flush() throws IOException {
         flushBuffer();
-        this.outstream.flush();
+        flushStream();
     }
 
-    public void write(final byte[] b, int off, int len) throws IOException {
+    public void write(final byte[] b, final int off, final int len) throws IOException {
         if (b == null) {
             return;
         }
         // Do not want to buffer large-ish chunks
         // if the byte array is larger then MIN_CHUNK_LIMIT
         // write it directly to the output stream
-        if (len > this.minChunkLimit || len > this.buffer.capacity()) {
+        if (len > this.fragementSizeHint || len > this.buffer.capacity()) {
             // flush the buffer
             flushBuffer();
             // write directly to the out stream
-            this.outstream.write(b, off, len);
+            streamWrite(b, off, len);
             this.metrics.incrementBytesTransferred(len);
         } else {
             // Do not let the buffer grow unnecessarily
-            int freecapacity = this.buffer.capacity() - this.buffer.length();
+            final int freecapacity = this.buffer.capacity() - this.buffer.length();
             if (len > freecapacity) {
                 // flush the buffer
                 flushBuffer();
@@ -187,11 +175,16 @@ public abstract class AbstractSessionOutputBuffer implements SessionOutputBuffer
         write(b, 0, b.length);
     }
 
-    public void write(int b) throws IOException {
-        if (this.buffer.isFull()) {
+    public void write(final int b) throws IOException {
+        if (this.fragementSizeHint > 0) {
+            if (this.buffer.isFull()) {
+                flushBuffer();
+            }
+            this.buffer.append(b);
+        } else {
             flushBuffer();
+            this.outstream.write(b);
         }
-        this.buffer.append(b);
     }
 
     /**
@@ -208,12 +201,12 @@ public abstract class AbstractSessionOutputBuffer implements SessionOutputBuffer
             return;
         }
         if (s.length() > 0) {
-            if (this.ascii) {
+            if (this.encoder == null) {
                 for (int i = 0; i < s.length(); i++) {
                     write(s.charAt(i));
                 }
             } else {
-                CharBuffer cbuf = CharBuffer.wrap(s);
+                final CharBuffer cbuf = CharBuffer.wrap(s);
                 writeEncoded(cbuf);
             }
         }
@@ -233,7 +226,7 @@ public abstract class AbstractSessionOutputBuffer implements SessionOutputBuffer
         if (charbuffer == null) {
             return;
         }
-        if (this.ascii) {
+        if (this.encoder == null) {
             int off = 0;
             int remaining = charbuffer.length();
             while (remaining > 0) {
@@ -249,7 +242,7 @@ public abstract class AbstractSessionOutputBuffer implements SessionOutputBuffer
                 remaining -= chunk;
             }
         } else {
-            CharBuffer cbuf = CharBuffer.wrap(charbuffer.buffer(), 0, charbuffer.length());
+            final CharBuffer cbuf = CharBuffer.wrap(charbuffer.buffer(), 0, charbuffer.length());
             writeEncoded(cbuf);
         }
         write(CRLF);
@@ -259,20 +252,15 @@ public abstract class AbstractSessionOutputBuffer implements SessionOutputBuffer
         if (!cbuf.hasRemaining()) {
             return;
         }
-        if (this.encoder == null) {
-            this.encoder = this.charset.newEncoder();
-            this.encoder.onMalformedInput(this.onMalformedInputAction);
-            this.encoder.onUnmappableCharacter(this.onUnMappableInputAction);
-        }
         if (this.bbuf == null) {
             this.bbuf = ByteBuffer.allocate(1024);
         }
         this.encoder.reset();
         while (cbuf.hasRemaining()) {
-            CoderResult result = this.encoder.encode(cbuf, this.bbuf, true);
+            final CoderResult result = this.encoder.encode(cbuf, this.bbuf, true);
             handleEncodingResult(result);
         }
-        CoderResult result = this.encoder.flush(this.bbuf);
+        final CoderResult result = this.encoder.flush(this.bbuf);
         handleEncodingResult(result);
         this.bbuf.clear();
     }
diff --git a/httpcore/src/main/java/org/apache/http/impl/pool/BasicConnFactory.java b/httpcore/src/main/java/org/apache/http/impl/pool/BasicConnFactory.java
index 43ba68d..5c67aed 100644
--- a/httpcore/src/main/java/org/apache/http/impl/pool/BasicConnFactory.java
+++ b/httpcore/src/main/java/org/apache/http/impl/pool/BasicConnFactory.java
@@ -30,78 +30,147 @@ import java.io.IOException;
 import java.net.InetSocketAddress;
 import java.net.Socket;
 
+import javax.net.SocketFactory;
 import javax.net.ssl.SSLSocketFactory;
 
 import org.apache.http.HttpClientConnection;
+import org.apache.http.HttpConnectionFactory;
 import org.apache.http.HttpHost;
 import org.apache.http.annotation.Immutable;
-import org.apache.http.impl.DefaultHttpClientConnection;
-import org.apache.http.params.HttpConnectionParams;
+import org.apache.http.config.ConnectionConfig;
+import org.apache.http.config.SocketConfig;
+import org.apache.http.impl.DefaultBHttpClientConnection;
+import org.apache.http.impl.DefaultBHttpClientConnectionFactory;
+import org.apache.http.params.CoreConnectionPNames;
+import org.apache.http.params.HttpParamConfig;
 import org.apache.http.params.HttpParams;
 import org.apache.http.pool.ConnFactory;
+import org.apache.http.util.Args;
 
 /**
  * A very basic {@link ConnFactory} implementation that creates
  * {@link HttpClientConnection} instances given a {@link HttpHost} instance.
- * <p/>
- * The following parameters can be used to customize the behavior of this
- * class:
- * <ul>
- *  <li>{@link org.apache.http.params.CoreProtocolPNames#HTTP_ELEMENT_CHARSET}</li>
- *  <li>{@link org.apache.http.params.CoreConnectionPNames#TCP_NODELAY}</li>
- *  <li>{@link org.apache.http.params.CoreConnectionPNames#SO_TIMEOUT}</li>
- *  <li>{@link org.apache.http.params.CoreConnectionPNames#SO_LINGER}</li>
- *  <li>{@link org.apache.http.params.CoreConnectionPNames#SOCKET_BUFFER_SIZE}</li>
- *  <li>{@link org.apache.http.params.CoreConnectionPNames#MAX_LINE_LENGTH}</li>
- * </ul>
  *
  * @see HttpHost
  * @since 4.2
  */
+ at SuppressWarnings("deprecation")
 @Immutable
 public class BasicConnFactory implements ConnFactory<HttpHost, HttpClientConnection> {
 
+    private final SocketFactory plainfactory;
     private final SSLSocketFactory sslfactory;
-    private final HttpParams params;
+    private final int connectTimeout;
+    private final SocketConfig sconfig;
+    private final HttpConnectionFactory<? extends HttpClientConnection> connFactory;
 
+    /**
+     * @deprecated (4.3) use
+     *   {@link BasicConnFactory#BasicConnFactory(SocketFactory, SSLSocketFactory, int,
+     *     SocketConfig, ConnectionConfig)}.
+     */
+    @Deprecated
     public BasicConnFactory(final SSLSocketFactory sslfactory, final HttpParams params) {
         super();
-        if (params == null) {
-            throw new IllegalArgumentException("HTTP params may not be null");
-        }
+        Args.notNull(params, "HTTP params");
+        this.plainfactory = null;
         this.sslfactory = sslfactory;
-        this.params = params;
+        this.connectTimeout = params.getIntParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 0);
+        this.sconfig = HttpParamConfig.getSocketConfig(params);
+        this.connFactory = new DefaultBHttpClientConnectionFactory(
+                HttpParamConfig.getConnectionConfig(params));
     }
 
+    /**
+     * @deprecated (4.3) use
+     *   {@link BasicConnFactory#BasicConnFactory(int, SocketConfig, ConnectionConfig)}.
+     */
+    @Deprecated
     public BasicConnFactory(final HttpParams params) {
         this(null, params);
     }
 
+    /**
+     * @since 4.3
+     */
+    public BasicConnFactory(
+            final SocketFactory plainfactory,
+            final SSLSocketFactory sslfactory,
+            final int connectTimeout,
+            final SocketConfig sconfig,
+            final ConnectionConfig cconfig) {
+        super();
+        this.plainfactory = plainfactory;
+        this.sslfactory = sslfactory;
+        this.connectTimeout = connectTimeout;
+        this.sconfig = sconfig != null ? sconfig : SocketConfig.DEFAULT;
+        this.connFactory = new DefaultBHttpClientConnectionFactory(
+                cconfig != null ? cconfig : ConnectionConfig.DEFAULT);
+    }
+
+    /**
+     * @since 4.3
+     */
+    public BasicConnFactory(
+            final int connectTimeout, final SocketConfig sconfig, final ConnectionConfig cconfig) {
+        this(null, null, connectTimeout, sconfig, cconfig);
+    }
+
+    /**
+     * @since 4.3
+     */
+    public BasicConnFactory(final SocketConfig sconfig, final ConnectionConfig cconfig) {
+        this(null, null, 0, sconfig, cconfig);
+    }
+
+    /**
+     * @since 4.3
+     */
+    public BasicConnFactory() {
+        this(null, null, 0, SocketConfig.DEFAULT, ConnectionConfig.DEFAULT);
+    }
+
+    /**
+     * @deprecated (4.3) no longer used.
+     */
+    @Deprecated
     protected HttpClientConnection create(final Socket socket, final HttpParams params) throws IOException {
-        DefaultHttpClientConnection conn = new DefaultHttpClientConnection();
-        conn.bind(socket, params);
+        final int bufsize = params.getIntParameter(CoreConnectionPNames.SOCKET_BUFFER_SIZE, 8 * 1024);
+        final DefaultBHttpClientConnection conn = new DefaultBHttpClientConnection(bufsize);
+        conn.bind(socket);
         return conn;
     }
 
     public HttpClientConnection create(final HttpHost host) throws IOException {
-        String scheme = host.getSchemeName();
+        final String scheme = host.getSchemeName();
         Socket socket = null;
         if ("http".equalsIgnoreCase(scheme)) {
-            socket = new Socket();
+            socket = this.plainfactory != null ? this.plainfactory.createSocket() :
+                    new Socket();
         } if ("https".equalsIgnoreCase(scheme)) {
-            if (this.sslfactory != null) {
-                socket = this.sslfactory.createSocket();
-            }
+            socket = (this.sslfactory != null ? this.sslfactory :
+                    SSLSocketFactory.getDefault()).createSocket();
         }
         if (socket == null) {
             throw new IOException(scheme + " scheme is not supported");
         }
-        int connectTimeout = HttpConnectionParams.getConnectionTimeout(this.params);
-        int soTimeout = HttpConnectionParams.getSoTimeout(this.params);
-
-        socket.setSoTimeout(soTimeout);
-        socket.connect(new InetSocketAddress(host.getHostName(), host.getPort()), connectTimeout);
-        return create(socket, this.params);
+        final String hostname = host.getHostName();
+        int port = host.getPort();
+        if (port == -1) {
+            if (host.getSchemeName().equalsIgnoreCase("http")) {
+                port = 80;
+            } else if (host.getSchemeName().equalsIgnoreCase("https")) {
+                port = 443;
+            }
+        }
+        socket.setSoTimeout(this.sconfig.getSoTimeout());
+        socket.connect(new InetSocketAddress(hostname, port), this.connectTimeout);
+        socket.setTcpNoDelay(this.sconfig.isTcpNoDelay());
+        final int linger = this.sconfig.getSoLinger();
+        if (linger >= 0) {
+            socket.setSoLinger(linger > 0, linger);
+        }
+        return this.connFactory.createConnection(socket);
     }
 
 }
diff --git a/httpcore/src/main/java/org/apache/http/impl/pool/BasicConnPool.java b/httpcore/src/main/java/org/apache/http/impl/pool/BasicConnPool.java
index 1dbfd72..fa1f4eb 100644
--- a/httpcore/src/main/java/org/apache/http/impl/pool/BasicConnPool.java
+++ b/httpcore/src/main/java/org/apache/http/impl/pool/BasicConnPool.java
@@ -31,45 +31,54 @@ import java.util.concurrent.atomic.AtomicLong;
 import org.apache.http.HttpClientConnection;
 import org.apache.http.HttpHost;
 import org.apache.http.annotation.ThreadSafe;
+import org.apache.http.config.ConnectionConfig;
+import org.apache.http.config.SocketConfig;
 import org.apache.http.params.HttpParams;
 import org.apache.http.pool.AbstractConnPool;
 import org.apache.http.pool.ConnFactory;
-import org.apache.http.pool.ConnPool;
 
 /**
- * A very basic {@link ConnPool} implementation that represents a pool
- * of blocking {@link HttpClientConnection} connections identified by
- * an {@link HttpHost} instance. Please note this pool implementation
- * does not support complex routes via a proxy cannot differentiate between
- * direct and proxied connections.
- * <p/>
- * The following parameters can be used to customize the behavior of this
- * class:
- * <ul>
- *  <li>{@link org.apache.http.params.CoreProtocolPNames#HTTP_ELEMENT_CHARSET}</li>
- *  <li>{@link org.apache.http.params.CoreConnectionPNames#TCP_NODELAY}</li>
- *  <li>{@link org.apache.http.params.CoreConnectionPNames#SO_TIMEOUT}</li>
- *  <li>{@link org.apache.http.params.CoreConnectionPNames#SO_LINGER}</li>
- *  <li>{@link org.apache.http.params.CoreConnectionPNames#SOCKET_BUFFER_SIZE}</li>
- *  <li>{@link org.apache.http.params.CoreConnectionPNames#MAX_LINE_LENGTH}</li>
- * </ul>
+ * A very basic {@link org.apache.http.pool.ConnPool} implementation that
+ * represents a pool of blocking {@link HttpClientConnection} connections
+ * identified by an {@link HttpHost} instance. Please note this pool
+ * implementation does not support complex routes via a proxy cannot
+ * differentiate between direct and proxied connections.
  *
  * @see HttpHost
  * @since 4.2
  */
+ at SuppressWarnings("deprecation")
 @ThreadSafe
 public class BasicConnPool extends AbstractConnPool<HttpHost, HttpClientConnection, BasicPoolEntry> {
 
-    private static AtomicLong COUNTER = new AtomicLong();
+    private static final AtomicLong COUNTER = new AtomicLong();
 
     public BasicConnPool(final ConnFactory<HttpHost, HttpClientConnection> connFactory) {
         super(connFactory, 2, 20);
     }
 
+    /**
+     * @deprecated (4.3) use {@link BasicConnPool#BasicConnPool(SocketConfig, ConnectionConfig)}
+     */
+    @Deprecated
     public BasicConnPool(final HttpParams params) {
         super(new BasicConnFactory(params), 2, 20);
     }
 
+    /**
+     * @since 4.3
+     */
+    public BasicConnPool(final SocketConfig sconfig, final ConnectionConfig cconfig) {
+        super(new BasicConnFactory(sconfig, cconfig), 2, 20);
+    }
+
+    /**
+     * @since 4.3
+     */
+    public BasicConnPool() {
+        super(new BasicConnFactory(SocketConfig.DEFAULT, ConnectionConfig.DEFAULT), 2, 20);
+    }
+
     @Override
     protected BasicPoolEntry createEntry(
             final HttpHost host,
diff --git a/httpcore/src/main/java/org/apache/http/impl/pool/BasicPoolEntry.java b/httpcore/src/main/java/org/apache/http/impl/pool/BasicPoolEntry.java
index ad6b173..521d1d3 100644
--- a/httpcore/src/main/java/org/apache/http/impl/pool/BasicPoolEntry.java
+++ b/httpcore/src/main/java/org/apache/http/impl/pool/BasicPoolEntry.java
@@ -52,7 +52,7 @@ public class BasicPoolEntry extends PoolEntry<HttpHost, HttpClientConnection> {
     public void close() {
         try {
             this.getConnection().close();
-        } catch (IOException ignore) {
+        } catch (final IOException ignore) {
         }
     }
 
diff --git a/httpcore/src/main/java/org/apache/http/io/EofSensor.java b/httpcore/src/main/java/org/apache/http/io/EofSensor.java
index b1ec82e..105939e 100644
--- a/httpcore/src/main/java/org/apache/http/io/EofSensor.java
+++ b/httpcore/src/main/java/org/apache/http/io/EofSensor.java
@@ -31,7 +31,10 @@ package org.apache.http.io;
  * EOF sensor.
  *
  * @since 4.0
+ *
+ * @deprecated (4.3) no longer used.
  */
+ at Deprecated
 public interface EofSensor {
 
     boolean isEof();
diff --git a/httpcore/src/main/java/org/apache/http/io/HttpMessageParser.java b/httpcore/src/main/java/org/apache/http/io/HttpMessageParser.java
index d25412d..8339f78 100644
--- a/httpcore/src/main/java/org/apache/http/io/HttpMessageParser.java
+++ b/httpcore/src/main/java/org/apache/http/io/HttpMessageParser.java
@@ -33,8 +33,10 @@ import org.apache.http.HttpException;
 import org.apache.http.HttpMessage;
 
 /**
- * Abstract message parser intended to build HTTP messages from an arbitrary
- * data source.
+ * Abstract message parser intended to build HTTP messages from an arbitrary data source.
+ *
+ * @param <T>
+ *            {@link HttpMessage} or a subclass
  *
  * @since 4.0
  */
diff --git a/httpcore/src/main/java/org/apache/http/io/EofSensor.java b/httpcore/src/main/java/org/apache/http/io/HttpMessageParserFactory.java
similarity index 79%
copy from httpcore/src/main/java/org/apache/http/io/EofSensor.java
copy to httpcore/src/main/java/org/apache/http/io/HttpMessageParserFactory.java
index b1ec82e..45b6ee2 100644
--- a/httpcore/src/main/java/org/apache/http/io/EofSensor.java
+++ b/httpcore/src/main/java/org/apache/http/io/HttpMessageParserFactory.java
@@ -27,13 +27,16 @@
 
 package org.apache.http.io;
 
+import org.apache.http.HttpMessage;
+import org.apache.http.config.MessageConstraints;
+
 /**
- * EOF sensor.
+ * Factory for {@link HttpMessageParser} instances.
  *
- * @since 4.0
+ * @since 4.3
  */
-public interface EofSensor {
+public interface HttpMessageParserFactory<T extends HttpMessage> {
 
-    boolean isEof();
+    HttpMessageParser<T> create(SessionInputBuffer buffer, MessageConstraints constraints);
 
 }
diff --git a/httpcore/src/main/java/org/apache/http/io/HttpMessageWriter.java b/httpcore/src/main/java/org/apache/http/io/HttpMessageWriter.java
index 39df3de..71833c8 100644
--- a/httpcore/src/main/java/org/apache/http/io/HttpMessageWriter.java
+++ b/httpcore/src/main/java/org/apache/http/io/HttpMessageWriter.java
@@ -44,7 +44,7 @@ public interface HttpMessageWriter<T extends HttpMessage> {
      * Serializes an instance of {@link HttpMessage} to the underlying data
      * sink.
      *
-     * @param message
+     * @param message HTTP message
      * @throws IOException in case of an I/O error
      * @throws HttpException in case of HTTP protocol violation
      */
diff --git a/httpcore-benchmark/src/main/java/org/apache/http/benchmark/HttpServer.java b/httpcore/src/main/java/org/apache/http/io/HttpMessageWriterFactory.java
similarity index 81%
rename from httpcore-benchmark/src/main/java/org/apache/http/benchmark/HttpServer.java
rename to httpcore/src/main/java/org/apache/http/io/HttpMessageWriterFactory.java
index b5aa75d..6c26f47 100644
--- a/httpcore-benchmark/src/main/java/org/apache/http/benchmark/HttpServer.java
+++ b/httpcore/src/main/java/org/apache/http/io/HttpMessageWriterFactory.java
@@ -25,16 +25,17 @@
  *
  */
 
-package org.apache.http.benchmark;
+package org.apache.http.io;
 
-public interface HttpServer {
+import org.apache.http.HttpMessage;
 
-    String getName();
-
-    String getVersion();
-
-    void start() throws Exception;
+/**
+ * Factory for {@link HttpMessageWriter} instances.
+ *
+ * @since 4.3
+ */
+public interface HttpMessageWriterFactory<T extends HttpMessage> {
 
-    void shutdown();
+    HttpMessageWriter<T> create(SessionOutputBuffer buffer);
 
 }
diff --git a/httpcore/src/main/java/org/apache/http/io/SessionInputBuffer.java b/httpcore/src/main/java/org/apache/http/io/SessionInputBuffer.java
index 59f8e48..4cd4de3 100644
--- a/httpcore/src/main/java/org/apache/http/io/SessionInputBuffer.java
+++ b/httpcore/src/main/java/org/apache/http/io/SessionInputBuffer.java
@@ -135,7 +135,11 @@ public interface SessionInputBuffer {
      * @return <code>true</code> if some data is available in the session
      *   buffer or <code>false</code> otherwise.
      * @exception  IOException  if an I/O error occurs.
+     *
+     * @deprecated (4.3) do not use. This function should be provided at the
+     *   connection level
      */
+    @Deprecated
     boolean isDataAvailable(int timeout) throws IOException;
 
     /**
diff --git a/httpcore/src/main/java/org/apache/http/message/AbstractHttpMessage.java b/httpcore/src/main/java/org/apache/http/message/AbstractHttpMessage.java
index 48d2046..4a59872 100644
--- a/httpcore/src/main/java/org/apache/http/message/AbstractHttpMessage.java
+++ b/httpcore/src/main/java/org/apache/http/message/AbstractHttpMessage.java
@@ -31,21 +31,28 @@ import org.apache.http.Header;
 import org.apache.http.HeaderIterator;
 import org.apache.http.HttpMessage;
 import org.apache.http.annotation.NotThreadSafe;
-import org.apache.http.params.HttpParams;
 import org.apache.http.params.BasicHttpParams;
+import org.apache.http.params.HttpParams;
+import org.apache.http.util.Args;
 
 /**
  * Basic implementation of {@link HttpMessage}.
  *
  * @since 4.0
  */
+ at SuppressWarnings("deprecation")
 @NotThreadSafe
 public abstract class AbstractHttpMessage implements HttpMessage {
 
     protected HeaderGroup headergroup;
 
+    @Deprecated
     protected HttpParams params;
 
+    /**
+     * @deprecated (4.3) use {@link AbstractHttpMessage#AbstractHttpMessage()}
+     */
+    @Deprecated
     protected AbstractHttpMessage(final HttpParams params) {
         super();
         this.headergroup = new HeaderGroup();
@@ -57,7 +64,7 @@ public abstract class AbstractHttpMessage implements HttpMessage {
     }
 
     // non-javadoc, see interface HttpMessage
-    public boolean containsHeader(String name) {
+    public boolean containsHeader(final String name) {
         return this.headergroup.containsHeader(name);
     }
 
@@ -88,9 +95,7 @@ public abstract class AbstractHttpMessage implements HttpMessage {
 
     // non-javadoc, see interface HttpMessage
     public void addHeader(final String name, final String value) {
-        if (name == null) {
-            throw new IllegalArgumentException("Header name may not be null");
-        }
+        Args.notNull(name, "Header name");
         this.headergroup.addHeader(new BasicHeader(name, value));
     }
 
@@ -101,9 +106,7 @@ public abstract class AbstractHttpMessage implements HttpMessage {
 
     // non-javadoc, see interface HttpMessage
     public void setHeader(final String name, final String value) {
-        if (name == null) {
-            throw new IllegalArgumentException("Header name may not be null");
-        }
+        Args.notNull(name, "Header name");
         this.headergroup.updateHeader(new BasicHeader(name, value));
     }
 
@@ -122,8 +125,8 @@ public abstract class AbstractHttpMessage implements HttpMessage {
         if (name == null) {
             return;
         }
-        for (HeaderIterator i = this.headergroup.iterator(); i.hasNext(); ) {
-            Header header = i.nextHeader();
+        for (final HeaderIterator i = this.headergroup.iterator(); i.hasNext(); ) {
+            final Header header = i.nextHeader();
             if (name.equalsIgnoreCase(header.getName())) {
                 i.remove();
             }
@@ -136,11 +139,14 @@ public abstract class AbstractHttpMessage implements HttpMessage {
     }
 
     // non-javadoc, see interface HttpMessage
-    public HeaderIterator headerIterator(String name) {
+    public HeaderIterator headerIterator(final String name) {
         return this.headergroup.iterator(name);
     }
 
-    // non-javadoc, see interface HttpMessage
+    /**
+     * @deprecated (4.3) use constructor parameters of configuration API provided by HttpClient
+     */
+    @Deprecated
     public HttpParams getParams() {
         if (this.params == null) {
             this.params = new BasicHttpParams();
@@ -148,11 +154,11 @@ public abstract class AbstractHttpMessage implements HttpMessage {
         return this.params;
     }
 
-    // non-javadoc, see interface HttpMessage
+    /**
+     * @deprecated (4.3) use constructor parameters of configuration API provided by HttpClient
+     */
+    @Deprecated
     public void setParams(final HttpParams params) {
-        if (params == null) {
-            throw new IllegalArgumentException("HTTP parameters may not be null");
-        }
-        this.params = params;
+        this.params = Args.notNull(params, "HTTP parameters");
     }
 }
diff --git a/httpcore/src/main/java/org/apache/http/message/BasicHeader.java b/httpcore/src/main/java/org/apache/http/message/BasicHeader.java
index 0fe5bec..4c99d6d 100644
--- a/httpcore/src/main/java/org/apache/http/message/BasicHeader.java
+++ b/httpcore/src/main/java/org/apache/http/message/BasicHeader.java
@@ -33,6 +33,7 @@ import org.apache.http.Header;
 import org.apache.http.HeaderElement;
 import org.apache.http.ParseException;
 import org.apache.http.annotation.Immutable;
+import org.apache.http.util.Args;
 
 /**
  * Basic implementation of {@link Header}.
@@ -55,10 +56,7 @@ public class BasicHeader implements Header, Cloneable, Serializable {
      */
     public BasicHeader(final String name, final String value) {
         super();
-        if (name == null) {
-            throw new IllegalArgumentException("Name may not be null");
-        }
-        this.name = name;
+        this.name = Args.notNull(name, "Name");
         this.value = value;
     }
 
@@ -73,7 +71,7 @@ public class BasicHeader implements Header, Cloneable, Serializable {
     @Override
     public String toString() {
         // no need for non-default formatting in toString()
-        return BasicLineFormatter.DEFAULT.formatHeader(null, this).toString();
+        return BasicLineFormatter.INSTANCE.formatHeader(null, this).toString();
     }
 
     public HeaderElement[] getElements() throws ParseException {
diff --git a/httpcore/src/main/java/org/apache/http/message/BasicHeaderElement.java b/httpcore/src/main/java/org/apache/http/message/BasicHeaderElement.java
index b82b056..590e923 100644
--- a/httpcore/src/main/java/org/apache/http/message/BasicHeaderElement.java
+++ b/httpcore/src/main/java/org/apache/http/message/BasicHeaderElement.java
@@ -30,6 +30,7 @@ package org.apache.http.message;
 import org.apache.http.HeaderElement;
 import org.apache.http.NameValuePair;
 import org.apache.http.annotation.NotThreadSafe;
+import org.apache.http.util.Args;
 import org.apache.http.util.LangUtils;
 
 /**
@@ -57,10 +58,7 @@ public class BasicHeaderElement implements HeaderElement, Cloneable {
             final String value,
             final NameValuePair[] parameters) {
         super();
-        if (name == null) {
-            throw new IllegalArgumentException("Name may not be null");
-        }
-        this.name = name;
+        this.name = Args.notNull(name, "Name");
         this.value = value;
         if (parameters != null) {
             this.parameters = parameters;
@@ -95,18 +93,15 @@ public class BasicHeaderElement implements HeaderElement, Cloneable {
         return this.parameters.length;
     }
 
-    public NameValuePair getParameter(int index) {
+    public NameValuePair getParameter(final int index) {
         // ArrayIndexOutOfBoundsException is appropriate
         return this.parameters[index];
     }
 
     public NameValuePair getParameterByName(final String name) {
-        if (name == null) {
-            throw new IllegalArgumentException("Name may not be null");
-        }
+        Args.notNull(name, "Name");
         NameValuePair found = null;
-        for (int i = 0; i < this.parameters.length; i++) {
-            NameValuePair current = this.parameters[ i ];
+        for (final NameValuePair current : this.parameters) {
             if (current.getName().equalsIgnoreCase(name)) {
                 found = current;
                 break;
@@ -117,9 +112,11 @@ public class BasicHeaderElement implements HeaderElement, Cloneable {
 
     @Override
     public boolean equals(final Object object) {
-        if (this == object) return true;
+        if (this == object) {
+            return true;
+        }
         if (object instanceof HeaderElement) {
-            BasicHeaderElement that = (BasicHeaderElement) object;
+            final BasicHeaderElement that = (BasicHeaderElement) object;
             return this.name.equals(that.name)
                 && LangUtils.equals(this.value, that.value)
                 && LangUtils.equals(this.parameters, that.parameters);
@@ -133,23 +130,23 @@ public class BasicHeaderElement implements HeaderElement, Cloneable {
         int hash = LangUtils.HASH_SEED;
         hash = LangUtils.hashCode(hash, this.name);
         hash = LangUtils.hashCode(hash, this.value);
-        for (int i = 0; i < this.parameters.length; i++) {
-            hash = LangUtils.hashCode(hash, this.parameters[i]);
+        for (final NameValuePair parameter : this.parameters) {
+            hash = LangUtils.hashCode(hash, parameter);
         }
         return hash;
     }
 
     @Override
     public String toString() {
-        StringBuilder buffer = new StringBuilder();
+        final StringBuilder buffer = new StringBuilder();
         buffer.append(this.name);
         if (this.value != null) {
             buffer.append("=");
             buffer.append(this.value);
         }
-        for (int i = 0; i < this.parameters.length; i++) {
+        for (final NameValuePair parameter : this.parameters) {
             buffer.append("; ");
-            buffer.append(this.parameters[i]);
+            buffer.append(parameter);
         }
         return buffer.toString();
     }
diff --git a/httpcore/src/main/java/org/apache/http/message/BasicHeaderElementIterator.java b/httpcore/src/main/java/org/apache/http/message/BasicHeaderElementIterator.java
index 0a9d4aa..b2c5e06 100644
--- a/httpcore/src/main/java/org/apache/http/message/BasicHeaderElementIterator.java
+++ b/httpcore/src/main/java/org/apache/http/message/BasicHeaderElementIterator.java
@@ -35,6 +35,7 @@ import org.apache.http.HeaderElement;
 import org.apache.http.HeaderElementIterator;
 import org.apache.http.HeaderIterator;
 import org.apache.http.annotation.NotThreadSafe;
+import org.apache.http.util.Args;
 import org.apache.http.util.CharArrayBuffer;
 
 /**
@@ -58,19 +59,13 @@ public class BasicHeaderElementIterator implements HeaderElementIterator {
     public BasicHeaderElementIterator(
             final HeaderIterator headerIterator,
             final HeaderValueParser parser) {
-        if (headerIterator == null) {
-            throw new IllegalArgumentException("Header iterator may not be null");
-        }
-        if (parser == null) {
-            throw new IllegalArgumentException("Parser may not be null");
-        }
-        this.headerIt = headerIterator;
-        this.parser = parser;
+        this.headerIt = Args.notNull(headerIterator, "Header iterator");
+        this.parser = Args.notNull(parser, "Parser");
     }
 
 
     public BasicHeaderElementIterator(final HeaderIterator headerIterator) {
-        this(headerIterator, BasicHeaderValueParser.DEFAULT);
+        this(headerIterator, BasicHeaderValueParser.INSTANCE);
     }
 
 
@@ -78,14 +73,14 @@ public class BasicHeaderElementIterator implements HeaderElementIterator {
         this.cursor = null;
         this.buffer = null;
         while (this.headerIt.hasNext()) {
-            Header h = this.headerIt.nextHeader();
+            final Header h = this.headerIt.nextHeader();
             if (h instanceof FormattedHeader) {
                 this.buffer = ((FormattedHeader) h).getBuffer();
                 this.cursor = new ParserCursor(0, this.buffer.length());
                 this.cursor.updatePos(((FormattedHeader) h).getValuePos());
                 break;
             } else {
-                String value = h.getValue();
+                final String value = h.getValue();
                 if (value != null) {
                     this.buffer = new CharArrayBuffer(value.length());
                     this.buffer.append(value);
@@ -107,7 +102,7 @@ public class BasicHeaderElementIterator implements HeaderElementIterator {
             if (this.cursor != null) {
                 // loop while there is data in the buffer
                 while (!this.cursor.atEnd()) {
-                    HeaderElement e = this.parser.parseHeaderElement(this.buffer, this.cursor);
+                    final HeaderElement e = this.parser.parseHeaderElement(this.buffer, this.cursor);
                     if (!(e.getName().length() == 0 && e.getValue() == null)) {
                         // Found something
                         this.currentElement = e;
@@ -140,7 +135,7 @@ public class BasicHeaderElementIterator implements HeaderElementIterator {
             throw new NoSuchElementException("No more header elements available");
         }
 
-        HeaderElement element = this.currentElement;
+        final HeaderElement element = this.currentElement;
         this.currentElement = null;
         return element;
     }
diff --git a/httpcore/src/main/java/org/apache/http/message/BasicHeaderIterator.java b/httpcore/src/main/java/org/apache/http/message/BasicHeaderIterator.java
index 151ce8b..35100eb 100644
--- a/httpcore/src/main/java/org/apache/http/message/BasicHeaderIterator.java
+++ b/httpcore/src/main/java/org/apache/http/message/BasicHeaderIterator.java
@@ -32,6 +32,7 @@ import java.util.NoSuchElementException;
 import org.apache.http.Header;
 import org.apache.http.HeaderIterator;
 import org.apache.http.annotation.NotThreadSafe;
+import org.apache.http.util.Args;
 
 /**
  * Basic implementation of a {@link HeaderIterator}.
@@ -72,13 +73,9 @@ public class BasicHeaderIterator implements HeaderIterator {
      * @param name      the name of the headers over which to iterate, or
      *                  <code>null</code> for any
      */
-    public BasicHeaderIterator(Header[] headers, String name) {
-        if (headers == null) {
-            throw new IllegalArgumentException
-                ("Header array must not be null.");
-        }
-
-        this.allHeaders = headers;
+    public BasicHeaderIterator(final Header[] headers, final String name) {
+        super();
+        this.allHeaders = Args.notNull(headers, "Header array");
         this.headerName = name;
         this.currentIndex = findNext(-1);
     }
@@ -87,15 +84,17 @@ public class BasicHeaderIterator implements HeaderIterator {
     /**
      * Determines the index of the next header.
      *
-     * @param from      one less than the index to consider first,
+     * @param pos      one less than the index to consider first,
      *                  -1 to search for the first header
      *
      * @return  the index of the next header that matches the filter name,
      *          or negative if there are no more headers
      */
-    protected int findNext(int from) {
-        if (from < -1)
+    protected int findNext(final int pos) {
+        int from = pos;
+        if (from < -1) {
             return -1;
+        }
 
         final int to = this.allHeaders.length-1;
         boolean found = false;
@@ -115,7 +114,7 @@ public class BasicHeaderIterator implements HeaderIterator {
      * @return  <code>true</code> if the header should be part of the
      *          iteration, <code>false</code> to skip
      */
-    protected boolean filterHeader(int index) {
+    protected boolean filterHeader(final int index) {
         return (this.headerName == null) ||
             this.headerName.equalsIgnoreCase(this.allHeaders[index].getName());
     }
diff --git a/httpcore/src/main/java/org/apache/http/message/BasicHeaderValueFormatter.java b/httpcore/src/main/java/org/apache/http/message/BasicHeaderValueFormatter.java
index 5ff998b..e37a0b3 100644
--- a/httpcore/src/main/java/org/apache/http/message/BasicHeaderValueFormatter.java
+++ b/httpcore/src/main/java/org/apache/http/message/BasicHeaderValueFormatter.java
@@ -30,6 +30,7 @@ package org.apache.http.message;
 import org.apache.http.HeaderElement;
 import org.apache.http.NameValuePair;
 import org.apache.http.annotation.Immutable;
+import org.apache.http.util.Args;
 import org.apache.http.util.CharArrayBuffer;
 
 /**
@@ -47,10 +48,14 @@ public class BasicHeaderValueFormatter implements HeaderValueFormatter {
      * Note that {@link BasicHeaderValueFormatter} is not a singleton, there
      * can be many instances of the class itself and of derived classes.
      * The instance here provides non-customized, default behavior.
+     *
+     * @deprecated (4.3) use {@link #INSTANCE}
      */
+    @Deprecated
     public final static
         BasicHeaderValueFormatter DEFAULT = new BasicHeaderValueFormatter();
 
+    public final static BasicHeaderValueFormatter INSTANCE = new BasicHeaderValueFormatter();
 
     /**
      * Special characters that can be used as separators in HTTP parameters.
@@ -59,18 +64,15 @@ public class BasicHeaderValueFormatter implements HeaderValueFormatter {
      */
     public final static String SEPARATORS = " ;,:@()<>\\\"/[]?={}\t";
 
-
     /**
      * Unsafe special characters that must be escaped using the backslash
      * character
      */
     public final static String UNSAFE_CHARS = "\"\\";
 
-
-
-    // public default constructor
-
-
+    public BasicHeaderValueFormatter() {
+        super();
+    }
 
     /**
      * Formats an array of header elements.
@@ -79,30 +81,26 @@ public class BasicHeaderValueFormatter implements HeaderValueFormatter {
      * @param quote     <code>true</code> to always format with quoted values,
      *                  <code>false</code> to use quotes only when necessary
      * @param formatter         the formatter to use, or <code>null</code>
-     *                          for the {@link #DEFAULT default}
+     *                          for the {@link #INSTANCE default}
      *
      * @return  the formatted header elements
      */
-    public final static
+    public static
         String formatElements(final HeaderElement[] elems,
                               final boolean quote,
-                              HeaderValueFormatter formatter) {
-        if (formatter == null)
-            formatter = BasicHeaderValueFormatter.DEFAULT;
-        return formatter.formatElements(null, elems, quote).toString();
+                              final HeaderValueFormatter formatter) {
+        return (formatter != null ? formatter : BasicHeaderValueFormatter.INSTANCE)
+                .formatElements(null, elems, quote).toString();
     }
 
 
     // non-javadoc, see interface HeaderValueFormatter
-    public CharArrayBuffer formatElements(CharArrayBuffer buffer,
+    public CharArrayBuffer formatElements(final CharArrayBuffer charBuffer,
                                           final HeaderElement[] elems,
                                           final boolean quote) {
-        if (elems == null) {
-            throw new IllegalArgumentException
-                ("Header element array must not be null.");
-        }
-
-        int len = estimateElementsLen(elems);
+        Args.notNull(elems, "Header element array");
+        final int len = estimateElementsLen(elems);
+        CharArrayBuffer buffer = charBuffer;
         if (buffer == null) {
             buffer = new CharArrayBuffer(len);
         } else {
@@ -128,12 +126,13 @@ public class BasicHeaderValueFormatter implements HeaderValueFormatter {
      * @return  a length estimate, in number of characters
      */
     protected int estimateElementsLen(final HeaderElement[] elems) {
-        if ((elems == null) || (elems.length < 1))
+        if ((elems == null) || (elems.length < 1)) {
             return 0;
+        }
 
         int result = (elems.length-1) * 2; // elements separated by ", "
-        for (int i=0; i<elems.length; i++) {
-            result += estimateHeaderElementLen(elems[i]);
+        for (final HeaderElement elem : elems) {
+            result += estimateHeaderElementLen(elem);
         }
 
         return result;
@@ -148,30 +147,26 @@ public class BasicHeaderValueFormatter implements HeaderValueFormatter {
      * @param quote     <code>true</code> to always format with quoted values,
      *                  <code>false</code> to use quotes only when necessary
      * @param formatter         the formatter to use, or <code>null</code>
-     *                          for the {@link #DEFAULT default}
+     *                          for the {@link #INSTANCE default}
      *
      * @return  the formatted header element
      */
-    public final static
+    public static
         String formatHeaderElement(final HeaderElement elem,
-                                   boolean quote,
-                                   HeaderValueFormatter formatter) {
-        if (formatter == null)
-            formatter = BasicHeaderValueFormatter.DEFAULT;
-        return formatter.formatHeaderElement(null, elem, quote).toString();
+                                   final boolean quote,
+                                   final HeaderValueFormatter formatter) {
+        return (formatter != null ? formatter : BasicHeaderValueFormatter.INSTANCE)
+                .formatHeaderElement(null, elem, quote).toString();
     }
 
 
     // non-javadoc, see interface HeaderValueFormatter
-    public CharArrayBuffer formatHeaderElement(CharArrayBuffer buffer,
+    public CharArrayBuffer formatHeaderElement(final CharArrayBuffer charBuffer,
                                                final HeaderElement elem,
                                                final boolean quote) {
-        if (elem == null) {
-            throw new IllegalArgumentException
-                ("Header element must not be null.");
-        }
-
-        int len = estimateHeaderElementLen(elem);
+        Args.notNull(elem, "Header element");
+        final int len = estimateHeaderElementLen(elem);
+        CharArrayBuffer buffer = charBuffer;
         if (buffer == null) {
             buffer = new CharArrayBuffer(len);
         } else {
@@ -205,8 +200,9 @@ public class BasicHeaderValueFormatter implements HeaderValueFormatter {
      * @return  a length estimate, in number of characters
      */
     protected int estimateHeaderElementLen(final HeaderElement elem) {
-        if (elem == null)
+        if (elem == null) {
             return 0;
+        }
 
         int result = elem.getName().length(); // name
         final String value = elem.getValue();
@@ -236,30 +232,26 @@ public class BasicHeaderValueFormatter implements HeaderValueFormatter {
      * @param quote     <code>true</code> to always format with quoted values,
      *                  <code>false</code> to use quotes only when necessary
      * @param formatter         the formatter to use, or <code>null</code>
-     *                          for the {@link #DEFAULT default}
+     *                          for the {@link #INSTANCE default}
      *
      * @return  the formatted parameters
      */
-    public final static
+    public static
         String formatParameters(final NameValuePair[] nvps,
                                 final boolean quote,
-                                HeaderValueFormatter formatter) {
-        if (formatter == null)
-            formatter = BasicHeaderValueFormatter.DEFAULT;
-        return formatter.formatParameters(null, nvps, quote).toString();
+                                final HeaderValueFormatter formatter) {
+        return (formatter != null ? formatter : BasicHeaderValueFormatter.INSTANCE)
+                .formatParameters(null, nvps, quote).toString();
     }
 
 
     // non-javadoc, see interface HeaderValueFormatter
-    public CharArrayBuffer formatParameters(CharArrayBuffer buffer,
-                                            NameValuePair[] nvps,
-                                            boolean quote) {
-        if (nvps == null) {
-            throw new IllegalArgumentException
-                ("Parameters must not be null.");
-        }
-
-        int len = estimateParametersLen(nvps);
+    public CharArrayBuffer formatParameters(final CharArrayBuffer charBuffer,
+                                            final NameValuePair[] nvps,
+                                            final boolean quote) {
+        Args.notNull(nvps, "Header parameter array");
+        final int len = estimateParametersLen(nvps);
+        CharArrayBuffer buffer = charBuffer;
         if (buffer == null) {
             buffer = new CharArrayBuffer(len);
         } else {
@@ -285,12 +277,13 @@ public class BasicHeaderValueFormatter implements HeaderValueFormatter {
      * @return  a length estimate, in number of characters
      */
     protected int estimateParametersLen(final NameValuePair[] nvps) {
-        if ((nvps == null) || (nvps.length < 1))
+        if ((nvps == null) || (nvps.length < 1)) {
             return 0;
+        }
 
         int result = (nvps.length-1) * 2; // "; " between the parameters
-        for (int i=0; i<nvps.length; i++) {
-            result += estimateNameValuePairLen(nvps[i]);
+        for (final NameValuePair nvp : nvps) {
+            result += estimateNameValuePairLen(nvp);
         }
 
         return result;
@@ -304,30 +297,26 @@ public class BasicHeaderValueFormatter implements HeaderValueFormatter {
      * @param quote     <code>true</code> to always format with a quoted value,
      *                  <code>false</code> to use quotes only when necessary
      * @param formatter         the formatter to use, or <code>null</code>
-     *                          for the {@link #DEFAULT default}
+     *                          for the {@link #INSTANCE default}
      *
      * @return  the formatted name-value pair
      */
-    public final static
+    public static
         String formatNameValuePair(final NameValuePair nvp,
                                    final boolean quote,
-                                   HeaderValueFormatter formatter) {
-        if (formatter == null)
-            formatter = BasicHeaderValueFormatter.DEFAULT;
-        return formatter.formatNameValuePair(null, nvp, quote).toString();
+                                   final HeaderValueFormatter formatter) {
+        return (formatter != null ? formatter : BasicHeaderValueFormatter.INSTANCE)
+                .formatNameValuePair(null, nvp, quote).toString();
     }
 
 
     // non-javadoc, see interface HeaderValueFormatter
-    public CharArrayBuffer formatNameValuePair(CharArrayBuffer buffer,
+    public CharArrayBuffer formatNameValuePair(final CharArrayBuffer charBuffer,
                                                final NameValuePair nvp,
                                                final boolean quote) {
-        if (nvp == null) {
-            throw new IllegalArgumentException
-                ("NameValuePair must not be null.");
-        }
-
-        int len = estimateNameValuePairLen(nvp);
+        Args.notNull(nvp, "Name / value pair");
+        final int len = estimateNameValuePairLen(nvp);
+        CharArrayBuffer buffer = charBuffer;
         if (buffer == null) {
             buffer = new CharArrayBuffer(len);
         } else {
@@ -353,8 +342,9 @@ public class BasicHeaderValueFormatter implements HeaderValueFormatter {
      * @return  a length estimate, in number of characters
      */
     protected int estimateNameValuePairLen(final NameValuePair nvp) {
-        if (nvp == null)
+        if (nvp == null) {
             return 0;
+        }
 
         int result = nvp.getName().length(); // name
         final String value = nvp.getValue();
@@ -378,25 +368,26 @@ public class BasicHeaderValueFormatter implements HeaderValueFormatter {
      */
     protected void doFormatValue(final CharArrayBuffer buffer,
                                  final String value,
-                                 boolean quote) {
+                                 final boolean quote) {
 
-        if (!quote) {
-            for (int i = 0; (i < value.length()) && !quote; i++) {
-                quote = isSeparator(value.charAt(i));
+        boolean quoteFlag = quote;
+        if (!quoteFlag) {
+            for (int i = 0; (i < value.length()) && !quoteFlag; i++) {
+                quoteFlag = isSeparator(value.charAt(i));
             }
         }
 
-        if (quote) {
+        if (quoteFlag) {
             buffer.append('"');
         }
         for (int i = 0; i < value.length(); i++) {
-            char ch = value.charAt(i);
+            final char ch = value.charAt(i);
             if (isUnsafe(ch)) {
                 buffer.append('\\');
             }
             buffer.append(ch);
         }
-        if (quote) {
+        if (quoteFlag) {
             buffer.append('"');
         }
     }
@@ -410,7 +401,7 @@ public class BasicHeaderValueFormatter implements HeaderValueFormatter {
      * @return  <code>true</code> if the character is a separator,
      *          <code>false</code> otherwise
      */
-    protected boolean isSeparator(char ch) {
+    protected boolean isSeparator(final char ch) {
         return SEPARATORS.indexOf(ch) >= 0;
     }
 
@@ -423,7 +414,7 @@ public class BasicHeaderValueFormatter implements HeaderValueFormatter {
      * @return  <code>true</code> if the character is unsafe,
      *          <code>false</code> otherwise
      */
-    protected boolean isUnsafe(char ch) {
+    protected boolean isUnsafe(final char ch) {
         return UNSAFE_CHARS.indexOf(ch) >= 0;
     }
 
diff --git a/httpcore/src/main/java/org/apache/http/message/BasicHeaderValueParser.java b/httpcore/src/main/java/org/apache/http/message/BasicHeaderValueParser.java
index e9aa919..5fb305e 100644
--- a/httpcore/src/main/java/org/apache/http/message/BasicHeaderValueParser.java
+++ b/httpcore/src/main/java/org/apache/http/message/BasicHeaderValueParser.java
@@ -27,14 +27,15 @@
 
 package org.apache.http.message;
 
-import java.util.List;
 import java.util.ArrayList;
+import java.util.List;
 
 import org.apache.http.HeaderElement;
 import org.apache.http.NameValuePair;
 import org.apache.http.ParseException;
 import org.apache.http.annotation.Immutable;
 import org.apache.http.protocol.HTTP;
+import org.apache.http.util.Args;
 import org.apache.http.util.CharArrayBuffer;
 
 /**
@@ -52,10 +53,15 @@ public class BasicHeaderValueParser implements HeaderValueParser {
      * Note that {@link BasicHeaderValueParser} is not a singleton, there
      * can be many instances of the class itself and of derived classes.
      * The instance here provides non-customized, default behavior.
+     *
+     * @deprecated (4.3) use {@link #INSTANCE}
      */
+    @Deprecated
     public final static
         BasicHeaderValueParser DEFAULT = new BasicHeaderValueParser();
 
+    public final static BasicHeaderValueParser INSTANCE = new BasicHeaderValueParser();
+
     private final static char PARAM_DELIMITER                = ';';
     private final static char ELEM_DELIMITER                 = ',';
     private final static char[] ALL_DELIMITERS               = new char[] {
@@ -63,8 +69,9 @@ public class BasicHeaderValueParser implements HeaderValueParser {
                                                                 ELEM_DELIMITER
                                                                 };
 
-    // public default constructor
-
+    public BasicHeaderValueParser() {
+        super();
+    }
 
     /**
      * Parses elements with the given parser.
@@ -74,40 +81,27 @@ public class BasicHeaderValueParser implements HeaderValueParser {
      *
      * @return  array holding the header elements, never <code>null</code>
      */
-    public final static
+    public static
         HeaderElement[] parseElements(final String value,
-                                      HeaderValueParser parser)
-        throws ParseException {
-
-        if (value == null) {
-            throw new IllegalArgumentException
-                ("Value to parse may not be null");
-        }
-
-        if (parser == null)
-            parser = BasicHeaderValueParser.DEFAULT;
+                                      final HeaderValueParser parser) throws ParseException {
+        Args.notNull(value, "Value");
 
-        CharArrayBuffer buffer = new CharArrayBuffer(value.length());
+        final CharArrayBuffer buffer = new CharArrayBuffer(value.length());
         buffer.append(value);
-        ParserCursor cursor = new ParserCursor(0, value.length());
-        return parser.parseElements(buffer, cursor);
+        final ParserCursor cursor = new ParserCursor(0, value.length());
+        return (parser != null ? parser : BasicHeaderValueParser.INSTANCE)
+            .parseElements(buffer, cursor);
     }
 
 
     // non-javadoc, see interface HeaderValueParser
     public HeaderElement[] parseElements(final CharArrayBuffer buffer,
                                          final ParserCursor cursor) {
-
-        if (buffer == null) {
-            throw new IllegalArgumentException("Char array buffer may not be null");
-        }
-        if (cursor == null) {
-            throw new IllegalArgumentException("Parser cursor may not be null");
-        }
-
-        List<HeaderElement> elements = new ArrayList<HeaderElement>();
+        Args.notNull(buffer, "Char array buffer");
+        Args.notNull(cursor, "Parser cursor");
+        final List<HeaderElement> elements = new ArrayList<HeaderElement>();
         while (!cursor.atEnd()) {
-            HeaderElement element = parseHeaderElement(buffer, cursor);
+            final HeaderElement element = parseHeaderElement(buffer, cursor);
             if (!(element.getName().length() == 0 && element.getValue() == null)) {
                 elements.add(element);
             }
@@ -124,41 +118,28 @@ public class BasicHeaderValueParser implements HeaderValueParser {
      *
      * @return  the parsed header element
      */
-    public final static
+    public static
         HeaderElement parseHeaderElement(final String value,
-                                         HeaderValueParser parser)
-        throws ParseException {
+                                         final HeaderValueParser parser) throws ParseException {
+        Args.notNull(value, "Value");
 
-        if (value == null) {
-            throw new IllegalArgumentException
-                ("Value to parse may not be null");
-        }
-
-        if (parser == null)
-            parser = BasicHeaderValueParser.DEFAULT;
-
-        CharArrayBuffer buffer = new CharArrayBuffer(value.length());
+        final CharArrayBuffer buffer = new CharArrayBuffer(value.length());
         buffer.append(value);
-        ParserCursor cursor = new ParserCursor(0, value.length());
-        return parser.parseHeaderElement(buffer, cursor);
+        final ParserCursor cursor = new ParserCursor(0, value.length());
+        return (parser != null ? parser : BasicHeaderValueParser.INSTANCE)
+                .parseHeaderElement(buffer, cursor);
     }
 
 
     // non-javadoc, see interface HeaderValueParser
     public HeaderElement parseHeaderElement(final CharArrayBuffer buffer,
                                             final ParserCursor cursor) {
-
-        if (buffer == null) {
-            throw new IllegalArgumentException("Char array buffer may not be null");
-        }
-        if (cursor == null) {
-            throw new IllegalArgumentException("Parser cursor may not be null");
-        }
-
-        NameValuePair nvp = parseNameValuePair(buffer, cursor);
+        Args.notNull(buffer, "Char array buffer");
+        Args.notNull(cursor, "Parser cursor");
+        final NameValuePair nvp = parseNameValuePair(buffer, cursor);
         NameValuePair[] params = null;
         if (!cursor.atEnd()) {
-            char ch = buffer.charAt(cursor.getPos() - 1);
+            final char ch = buffer.charAt(cursor.getPos() - 1);
             if (ch != ELEM_DELIMITER) {
                 params = parseParameters(buffer, cursor);
             }
@@ -189,23 +170,16 @@ public class BasicHeaderValueParser implements HeaderValueParser {
      *
      * @return  array holding the parameters, never <code>null</code>
      */
-    public final static
+    public static
         NameValuePair[] parseParameters(final String value,
-                                        HeaderValueParser parser)
-        throws ParseException {
+                                        final HeaderValueParser parser) throws ParseException {
+        Args.notNull(value, "Value");
 
-        if (value == null) {
-            throw new IllegalArgumentException
-                ("Value to parse may not be null");
-        }
-
-        if (parser == null)
-            parser = BasicHeaderValueParser.DEFAULT;
-
-        CharArrayBuffer buffer = new CharArrayBuffer(value.length());
+        final CharArrayBuffer buffer = new CharArrayBuffer(value.length());
         buffer.append(value);
-        ParserCursor cursor = new ParserCursor(0, value.length());
-        return parser.parseParameters(buffer, cursor);
+        final ParserCursor cursor = new ParserCursor(0, value.length());
+        return (parser != null ? parser : BasicHeaderValueParser.INSTANCE)
+                .parseParameters(buffer, cursor);
     }
 
 
@@ -213,19 +187,13 @@ public class BasicHeaderValueParser implements HeaderValueParser {
     // non-javadoc, see interface HeaderValueParser
     public NameValuePair[] parseParameters(final CharArrayBuffer buffer,
                                            final ParserCursor cursor) {
-
-        if (buffer == null) {
-            throw new IllegalArgumentException("Char array buffer may not be null");
-        }
-        if (cursor == null) {
-            throw new IllegalArgumentException("Parser cursor may not be null");
-        }
-
+        Args.notNull(buffer, "Char array buffer");
+        Args.notNull(cursor, "Parser cursor");
         int pos = cursor.getPos();
-        int indexTo = cursor.getUpperBound();
+        final int indexTo = cursor.getUpperBound();
 
         while (pos < indexTo) {
-            char ch = buffer.charAt(pos);
+            final char ch = buffer.charAt(pos);
             if (HTTP.isWhitespace(ch)) {
                 pos++;
             } else {
@@ -237,11 +205,11 @@ public class BasicHeaderValueParser implements HeaderValueParser {
             return new NameValuePair[] {};
         }
 
-        List<NameValuePair> params = new ArrayList<NameValuePair>();
+        final List<NameValuePair> params = new ArrayList<NameValuePair>();
         while (!cursor.atEnd()) {
-            NameValuePair param = parseNameValuePair(buffer, cursor);
+            final NameValuePair param = parseNameValuePair(buffer, cursor);
             params.add(param);
-            char ch = buffer.charAt(cursor.getPos() - 1);
+            final char ch = buffer.charAt(cursor.getPos() - 1);
             if (ch == ELEM_DELIMITER) {
                 break;
             }
@@ -258,23 +226,16 @@ public class BasicHeaderValueParser implements HeaderValueParser {
      *
      * @return  the parsed name-value pair
      */
-    public final static
+    public static
        NameValuePair parseNameValuePair(final String value,
-                                        HeaderValueParser parser)
-        throws ParseException {
-
-        if (value == null) {
-            throw new IllegalArgumentException
-                ("Value to parse may not be null");
-        }
+                                        final HeaderValueParser parser) throws ParseException {
+        Args.notNull(value, "Value");
 
-        if (parser == null)
-            parser = BasicHeaderValueParser.DEFAULT;
-
-        CharArrayBuffer buffer = new CharArrayBuffer(value.length());
+        final CharArrayBuffer buffer = new CharArrayBuffer(value.length());
         buffer.append(value);
-        ParserCursor cursor = new ParserCursor(0, value.length());
-        return parser.parseNameValuePair(buffer, cursor);
+        final ParserCursor cursor = new ParserCursor(0, value.length());
+        return (parser != null ? parser : BasicHeaderValueParser.INSTANCE)
+                .parseNameValuePair(buffer, cursor);
     }
 
 
@@ -286,8 +247,8 @@ public class BasicHeaderValueParser implements HeaderValueParser {
 
     private static boolean isOneOf(final char ch, final char[] chs) {
         if (chs != null) {
-            for (int i = 0; i < chs.length; i++) {
-                if (ch == chs[i]) {
+            for (final char ch2 : chs) {
+                if (ch == ch2) {
                     return true;
                 }
             }
@@ -298,24 +259,19 @@ public class BasicHeaderValueParser implements HeaderValueParser {
     public NameValuePair parseNameValuePair(final CharArrayBuffer buffer,
                                             final ParserCursor cursor,
                                             final char[] delimiters) {
-
-        if (buffer == null) {
-            throw new IllegalArgumentException("Char array buffer may not be null");
-        }
-        if (cursor == null) {
-            throw new IllegalArgumentException("Parser cursor may not be null");
-        }
+        Args.notNull(buffer, "Char array buffer");
+        Args.notNull(cursor, "Parser cursor");
 
         boolean terminated = false;
 
         int pos = cursor.getPos();
-        int indexFrom = cursor.getPos();
-        int indexTo = cursor.getUpperBound();
+        final int indexFrom = cursor.getPos();
+        final int indexTo = cursor.getUpperBound();
 
         // Find name
-        String name = null;
+        final String name;
         while (pos < indexTo) {
-            char ch = buffer.charAt(pos);
+            final char ch = buffer.charAt(pos);
             if (ch == '=') {
                 break;
             }
@@ -340,13 +296,13 @@ public class BasicHeaderValueParser implements HeaderValueParser {
         }
 
         // Find value
-        String value = null;
+        final String value;
         int i1 = pos;
 
         boolean qouted = false;
         boolean escaped = false;
         while (pos < indexTo) {
-            char ch = buffer.charAt(pos);
+            final char ch = buffer.charAt(pos);
             if (ch == '"' && !escaped) {
                 qouted = !qouted;
             }
diff --git a/httpcore/src/main/java/org/apache/http/message/BasicHttpEntityEnclosingRequest.java b/httpcore/src/main/java/org/apache/http/message/BasicHttpEntityEnclosingRequest.java
index abbb1e3..90bf9d4 100644
--- a/httpcore/src/main/java/org/apache/http/message/BasicHttpEntityEnclosingRequest.java
+++ b/httpcore/src/main/java/org/apache/http/message/BasicHttpEntityEnclosingRequest.java
@@ -68,7 +68,7 @@ public class BasicHttpEntityEnclosingRequest
     }
 
     public boolean expectContinue() {
-        Header expect = getFirstHeader(HTTP.EXPECT_DIRECTIVE);
+        final Header expect = getFirstHeader(HTTP.EXPECT_DIRECTIVE);
         return expect != null && HTTP.EXPECT_CONTINUE.equalsIgnoreCase(expect.getValue());
     }
 
diff --git a/httpcore/src/main/java/org/apache/http/message/BasicHttpRequest.java b/httpcore/src/main/java/org/apache/http/message/BasicHttpRequest.java
index 6dba70d..22867dc 100644
--- a/httpcore/src/main/java/org/apache/http/message/BasicHttpRequest.java
+++ b/httpcore/src/main/java/org/apache/http/message/BasicHttpRequest.java
@@ -28,19 +28,14 @@
 package org.apache.http.message;
 
 import org.apache.http.HttpRequest;
+import org.apache.http.HttpVersion;
 import org.apache.http.ProtocolVersion;
 import org.apache.http.RequestLine;
 import org.apache.http.annotation.NotThreadSafe;
-import org.apache.http.params.HttpParams;
-import org.apache.http.params.HttpProtocolParams;
+import org.apache.http.util.Args;
 
 /**
  * Basic implementation of {@link HttpRequest}.
- * <p>
- * The following parameters can be used to customize the behavior of this class:
- * <ul>
- *  <li>{@link org.apache.http.params.CoreProtocolPNames#PROTOCOL_VERSION}</li>
- * </ul>
  *
  * @since 4.0
  */
@@ -54,24 +49,15 @@ public class BasicHttpRequest extends AbstractHttpMessage implements HttpRequest
 
     /**
      * Creates an instance of this class using the given request method
-     * and URI. The HTTP protocol version will be obtained from the
-     * {@link HttpParams} instance associated with the object.
-     * The initialization will be deferred
-     * until {@link #getRequestLine()} is accessed for the first time.
+     * and URI.
      *
      * @param method request method.
      * @param uri request URI.
      */
     public BasicHttpRequest(final String method, final String uri) {
         super();
-        if (method == null) {
-            throw new IllegalArgumentException("Method name may not be null");
-        }
-        if (uri == null) {
-            throw new IllegalArgumentException("Request URI may not be null");
-        }
-        this.method = method;
-        this.uri = uri;
+        this.method = Args.notNull(method, "Method name");
+        this.uri = Args.notNull(uri, "Request URI");
         this.requestline = null;
     }
 
@@ -94,19 +80,13 @@ public class BasicHttpRequest extends AbstractHttpMessage implements HttpRequest
      */
     public BasicHttpRequest(final RequestLine requestline) {
         super();
-        if (requestline == null) {
-            throw new IllegalArgumentException("Request line may not be null");
-        }
-        this.requestline = requestline;
+        this.requestline = Args.notNull(requestline, "Request line");
         this.method = requestline.getMethod();
         this.uri = requestline.getUri();
     }
 
     /**
-     * Returns the HTTP protocol version to be used for this request. If an
-     * HTTP protocol version was not explicitly set at the construction time,
-     * this method will obtain it from the {@link HttpParams} instance
-     * associated with the object.
+     * Returns the HTTP protocol version to be used for this request.
      *
      * @see #BasicHttpRequest(String, String)
      */
@@ -115,16 +95,13 @@ public class BasicHttpRequest extends AbstractHttpMessage implements HttpRequest
     }
 
     /**
-     * Returns the request line of this request. If an HTTP protocol version
-     * was not explicitly set at the construction time, this method will obtain
-     * it from the {@link HttpParams} instance associated with the object.
+     * Returns the request line of this request.
      *
      * @see #BasicHttpRequest(String, String)
      */
     public RequestLine getRequestLine() {
         if (this.requestline == null) {
-            ProtocolVersion ver = HttpProtocolParams.getVersion(getParams());
-            this.requestline = new BasicRequestLine(this.method, this.uri, ver);
+            this.requestline = new BasicRequestLine(this.method, this.uri, HttpVersion.HTTP_1_1);
         }
         return this.requestline;
     }
diff --git a/httpcore/src/main/java/org/apache/http/message/BasicHttpResponse.java b/httpcore/src/main/java/org/apache/http/message/BasicHttpResponse.java
index 6bd4af6..5421658 100644
--- a/httpcore/src/main/java/org/apache/http/message/BasicHttpResponse.java
+++ b/httpcore/src/main/java/org/apache/http/message/BasicHttpResponse.java
@@ -31,26 +31,31 @@ import java.util.Locale;
 
 import org.apache.http.HttpEntity;
 import org.apache.http.HttpResponse;
+import org.apache.http.HttpVersion;
 import org.apache.http.ProtocolVersion;
-import org.apache.http.StatusLine;
 import org.apache.http.ReasonPhraseCatalog;
+import org.apache.http.StatusLine;
 import org.apache.http.annotation.NotThreadSafe;
+import org.apache.http.util.Args;
 
 /**
  * Basic implementation of {@link HttpResponse}.
  *
+ * @see org.apache.http.impl.DefaultHttpResponseFactory
+ *
  * @since 4.0
  */
 @NotThreadSafe
-public class BasicHttpResponse extends AbstractHttpMessage
-    implements HttpResponse {
+public class BasicHttpResponse extends AbstractHttpMessage implements HttpResponse {
 
     private StatusLine          statusline;
+    private ProtocolVersion     ver;
+    private int                 code;
+    private String              reasonPhrase;
     private HttpEntity          entity;
-    private ReasonPhraseCatalog reasonCatalog;
+    private final ReasonPhraseCatalog reasonCatalog;
     private Locale              locale;
 
-
     /**
      * Creates a new response.
      * This is the constructor to which all others map.
@@ -61,17 +66,20 @@ public class BasicHttpResponse extends AbstractHttpMessage
      *                          reason phrase lookup
      * @param locale            the locale for looking up reason phrases, or
      *                          <code>null</code> for the system locale
+     *
+     * @deprecated (4.3) use {@link org.apache.http.impl.DefaultHttpRequestFactory}
      */
+    @Deprecated
     public BasicHttpResponse(final StatusLine statusline,
                              final ReasonPhraseCatalog catalog,
                              final Locale locale) {
         super();
-        if (statusline == null) {
-            throw new IllegalArgumentException("Status line may not be null.");
-        }
-        this.statusline    = statusline;
+        this.statusline = Args.notNull(statusline, "Status line");
+        this.ver = statusline.getProtocolVersion();
+        this.code = statusline.getStatusCode();
+        this.reasonPhrase = statusline.getReasonPhrase();
         this.reasonCatalog = catalog;
-        this.locale        = (locale != null) ? locale : Locale.getDefault();
+        this.locale = locale;
     }
 
     /**
@@ -82,7 +90,13 @@ public class BasicHttpResponse extends AbstractHttpMessage
      * @param statusline        the status line
      */
     public BasicHttpResponse(final StatusLine statusline) {
-        this(statusline, null, null);
+        super();
+        this.statusline = Args.notNull(statusline, "Status line");
+        this.ver = statusline.getProtocolVersion();
+        this.code = statusline.getStatusCode();
+        this.reasonPhrase = statusline.getReasonPhrase();
+        this.reasonCatalog = null;
+        this.locale = null;
     }
 
     /**
@@ -98,17 +112,30 @@ public class BasicHttpResponse extends AbstractHttpMessage
     public BasicHttpResponse(final ProtocolVersion ver,
                              final int code,
                              final String reason) {
-        this(new BasicStatusLine(ver, code, reason), null, null);
+        super();
+        Args.notNegative(code, "Status code");
+        this.statusline = null;
+        this.ver = ver;
+        this.code = code;
+        this.reasonPhrase = reason;
+        this.reasonCatalog = null;
+        this.locale = null;
     }
 
 
     // non-javadoc, see interface HttpMessage
     public ProtocolVersion getProtocolVersion() {
-        return this.statusline.getProtocolVersion();
+        return this.ver;
     }
 
     // non-javadoc, see interface HttpResponse
     public StatusLine getStatusLine() {
+        if (this.statusline == null) {
+            this.statusline = new BasicStatusLine(
+                    this.ver != null ? this.ver : HttpVersion.HTTP_1_1,
+                    this.code,
+                    this.reasonPhrase);
+        }
         return this.statusline;
     }
 
@@ -117,50 +144,52 @@ public class BasicHttpResponse extends AbstractHttpMessage
         return this.entity;
     }
 
-    // non-javadoc, see interface HttpResponse
+    /**
+     * @deprecated (4.3) use {@link org.apache.http.impl.DefaultHttpRequestFactory}
+     */
+    @Deprecated
     public Locale getLocale() {
         return this.locale;
     }
 
     // non-javadoc, see interface HttpResponse
     public void setStatusLine(final StatusLine statusline) {
-        if (statusline == null) {
-            throw new IllegalArgumentException("Status line may not be null");
-        }
-        this.statusline = statusline;
+        this.statusline = Args.notNull(statusline, "Status line");
+        this.ver = statusline.getProtocolVersion();
+        this.code = statusline.getStatusCode();
+        this.reasonPhrase = statusline.getReasonPhrase();
     }
 
     // non-javadoc, see interface HttpResponse
     public void setStatusLine(final ProtocolVersion ver, final int code) {
-        // arguments checked in BasicStatusLine constructor
-        this.statusline = new BasicStatusLine(ver, code, getReason(code));
+        Args.notNegative(code, "Status code");
+        this.statusline = null;
+        this.ver = ver;
+        this.code = code;
+        this.reasonPhrase = null;
     }
 
     // non-javadoc, see interface HttpResponse
-    public void setStatusLine(final ProtocolVersion ver, final int code,
-                              final String reason) {
-        // arguments checked in BasicStatusLine constructor
-        this.statusline = new BasicStatusLine(ver, code, reason);
+    public void setStatusLine(
+            final ProtocolVersion ver, final int code, final String reason) {
+        Args.notNegative(code, "Status code");
+        this.statusline = null;
+        this.ver = ver;
+        this.code = code;
+        this.reasonPhrase = reason;
     }
 
     // non-javadoc, see interface HttpResponse
-    public void setStatusCode(int code) {
-        // argument checked in BasicStatusLine constructor
-        ProtocolVersion ver = this.statusline.getProtocolVersion();
-        this.statusline = new BasicStatusLine(ver, code, getReason(code));
+    public void setStatusCode(final int code) {
+        Args.notNegative(code, "Status code");
+        this.statusline = null;
+        this.code = code;
     }
 
     // non-javadoc, see interface HttpResponse
-    public void setReasonPhrase(String reason) {
-
-        if ((reason != null) && ((reason.indexOf('\n') >= 0) ||
-                                 (reason.indexOf('\r') >= 0))
-            ) {
-            throw new IllegalArgumentException("Line break in reason phrase.");
-        }
-        this.statusline = new BasicStatusLine(this.statusline.getProtocolVersion(),
-                                              this.statusline.getStatusCode(),
-                                              reason);
+    public void setReasonPhrase(final String reason) {
+        this.statusline = null;
+        this.reasonPhrase = reason;
     }
 
     // non-javadoc, see interface HttpResponse
@@ -168,15 +197,13 @@ public class BasicHttpResponse extends AbstractHttpMessage
         this.entity = entity;
     }
 
-    // non-javadoc, see interface HttpResponse
-    public void setLocale(Locale loc) {
-        if (loc == null) {
-            throw new IllegalArgumentException("Locale may not be null.");
-        }
-        this.locale = loc;
-        final int code = this.statusline.getStatusCode();
-        this.statusline = new BasicStatusLine
-            (this.statusline.getProtocolVersion(), code, getReason(code));
+    /**
+     * @deprecated (4.3) use {@link org.apache.http.impl.DefaultHttpRequestFactory}
+     */
+    @Deprecated
+    public void setLocale(final Locale locale) {
+        this.locale =  Args.notNull(locale, "Locale");
+        this.statusline = null;
     }
 
     /**
@@ -187,15 +214,19 @@ public class BasicHttpResponse extends AbstractHttpMessage
      * @param code      the status code for which to look up the reason
      *
      * @return  the reason phrase, or <code>null</code> if there is none
+     *
+     * @deprecated (4.3) use {@link org.apache.http.impl.DefaultHttpRequestFactory}
      */
-    protected String getReason(int code) {
-        return (this.reasonCatalog == null) ?
-            null : this.reasonCatalog.getReason(code, this.locale);
+    @Deprecated
+    protected String getReason(final int code) {
+        return this.reasonCatalog != null ? this.reasonCatalog.getReason(code,
+                this.locale != null ? this.locale : Locale.getDefault()) : null;
     }
 
     @Override
     public String toString() {
-        return this.statusline + " " + this.headergroup;
+        final StatusLine statusline = getStatusLine();
+        return statusline + " " + this.headergroup;
     }
 
 }
diff --git a/httpcore/src/main/java/org/apache/http/message/BasicLineFormatter.java b/httpcore/src/main/java/org/apache/http/message/BasicLineFormatter.java
index e186df2..bc9b261 100644
--- a/httpcore/src/main/java/org/apache/http/message/BasicLineFormatter.java
+++ b/httpcore/src/main/java/org/apache/http/message/BasicLineFormatter.java
@@ -27,12 +27,13 @@
 
 package org.apache.http.message;
 
+import org.apache.http.FormattedHeader;
+import org.apache.http.Header;
 import org.apache.http.ProtocolVersion;
 import org.apache.http.RequestLine;
 import org.apache.http.StatusLine;
-import org.apache.http.Header;
-import org.apache.http.FormattedHeader;
 import org.apache.http.annotation.Immutable;
+import org.apache.http.util.Args;
 import org.apache.http.util.CharArrayBuffer;
 
 /**
@@ -55,23 +56,28 @@ public class BasicLineFormatter implements LineFormatter {
      * Note that {@link BasicLineFormatter} is not a singleton, there can
      * be many instances of the class itself and of derived classes.
      * The instance here provides non-customized, default behavior.
+     *
+     * @deprecated (4.3) use {@link #INSTANCE}
      */
+    @Deprecated
     public final static BasicLineFormatter DEFAULT = new BasicLineFormatter();
 
+    public final static BasicLineFormatter INSTANCE = new BasicLineFormatter();
 
-
-    // public default constructor
-
+    public BasicLineFormatter() {
+        super();
+    }
 
     /**
      * Obtains a buffer for formatting.
      *
-     * @param buffer    a buffer already available, or <code>null</code>
+     * @param charBuffer a buffer already available, or <code>null</code>
      *
      * @return  the cleared argument buffer if there is one, or
      *          a new empty buffer that can be used for formatting
      */
-    protected CharArrayBuffer initBuffer(CharArrayBuffer buffer) {
+    protected CharArrayBuffer initBuffer(final CharArrayBuffer charBuffer) {
+        CharArrayBuffer buffer = charBuffer;
         if (buffer != null) {
             buffer.clear();
         } else {
@@ -87,27 +93,22 @@ public class BasicLineFormatter implements LineFormatter {
      * @param version           the protocol version to format
      * @param formatter         the formatter to use, or
      *                          <code>null</code> for the
-     *                          {@link #DEFAULT default}
+     *                          {@link #INSTANCE default}
      *
      * @return  the formatted protocol version
      */
-    public final static
+    public static
         String formatProtocolVersion(final ProtocolVersion version,
-                                     LineFormatter formatter) {
-        if (formatter == null)
-            formatter = BasicLineFormatter.DEFAULT;
-        return formatter.appendProtocolVersion(null, version).toString();
+                                     final LineFormatter formatter) {
+        return (formatter != null ? formatter : BasicLineFormatter.INSTANCE)
+                .appendProtocolVersion(null, version).toString();
     }
 
 
     // non-javadoc, see interface LineFormatter
     public CharArrayBuffer appendProtocolVersion(final CharArrayBuffer buffer,
                                                  final ProtocolVersion version) {
-        if (version == null) {
-            throw new IllegalArgumentException
-                ("Protocol version may not be null");
-        }
-
+        Args.notNull(version, "Protocol version");
         // can't use initBuffer, that would clear the argument!
         CharArrayBuffer result = buffer;
         final int len = estimateProtocolVersionLen(version);
@@ -147,27 +148,22 @@ public class BasicLineFormatter implements LineFormatter {
      * @param reqline           the request line to format
      * @param formatter         the formatter to use, or
      *                          <code>null</code> for the
-     *                          {@link #DEFAULT default}
+     *                          {@link #INSTANCE default}
      *
      * @return  the formatted request line
      */
-    public final static String formatRequestLine(final RequestLine reqline,
-                                                 LineFormatter formatter) {
-        if (formatter == null)
-            formatter = BasicLineFormatter.DEFAULT;
-        return formatter.formatRequestLine(null, reqline).toString();
+    public static String formatRequestLine(final RequestLine reqline,
+                                           final LineFormatter formatter) {
+        return (formatter != null ? formatter : BasicLineFormatter.INSTANCE)
+                .formatRequestLine(null, reqline).toString();
     }
 
 
     // non-javadoc, see interface LineFormatter
-    public CharArrayBuffer formatRequestLine(CharArrayBuffer buffer,
-                                             RequestLine reqline) {
-        if (reqline == null) {
-            throw new IllegalArgumentException
-                ("Request line may not be null");
-        }
-
-        CharArrayBuffer result = initBuffer(buffer);
+    public CharArrayBuffer formatRequestLine(final CharArrayBuffer buffer,
+                                             final RequestLine reqline) {
+        Args.notNull(reqline, "Request line");
+        final CharArrayBuffer result = initBuffer(buffer);
         doFormatRequestLine(result, reqline);
 
         return result;
@@ -188,7 +184,7 @@ public class BasicLineFormatter implements LineFormatter {
         final String uri    = reqline.getUri();
 
         // room for "GET /index.html HTTP/1.1"
-        int len = method.length() + 1 + uri.length() + 1 +
+        final int len = method.length() + 1 + uri.length() + 1 +
             estimateProtocolVersionLen(reqline.getProtocolVersion());
         buffer.ensureCapacity(len);
 
@@ -207,27 +203,22 @@ public class BasicLineFormatter implements LineFormatter {
      * @param statline          the status line to format
      * @param formatter         the formatter to use, or
      *                          <code>null</code> for the
-     *                          {@link #DEFAULT default}
+     *                          {@link #INSTANCE default}
      *
      * @return  the formatted status line
      */
-    public final static String formatStatusLine(final StatusLine statline,
-                                                LineFormatter formatter) {
-        if (formatter == null)
-            formatter = BasicLineFormatter.DEFAULT;
-        return formatter.formatStatusLine(null, statline).toString();
+    public static String formatStatusLine(final StatusLine statline,
+                                          final LineFormatter formatter) {
+        return (formatter != null ? formatter : BasicLineFormatter.INSTANCE)
+                .formatStatusLine(null, statline).toString();
     }
 
 
     // non-javadoc, see interface LineFormatter
     public CharArrayBuffer formatStatusLine(final CharArrayBuffer buffer,
                                             final StatusLine statline) {
-        if (statline == null) {
-            throw new IllegalArgumentException
-                ("Status line may not be null");
-        }
-
-        CharArrayBuffer result = initBuffer(buffer);
+        Args.notNull(statline, "Status line");
+        final CharArrayBuffer result = initBuffer(buffer);
         doFormatStatusLine(result, statline);
 
         return result;
@@ -269,26 +260,22 @@ public class BasicLineFormatter implements LineFormatter {
      * @param header            the header to format
      * @param formatter         the formatter to use, or
      *                          <code>null</code> for the
-     *                          {@link #DEFAULT default}
+     *                          {@link #INSTANCE default}
      *
      * @return  the formatted header
      */
-    public final static String formatHeader(final Header header,
-                                            LineFormatter formatter) {
-        if (formatter == null)
-            formatter = BasicLineFormatter.DEFAULT;
-        return formatter.formatHeader(null, header).toString();
+    public static String formatHeader(final Header header,
+                                      final LineFormatter formatter) {
+        return (formatter != null ? formatter : BasicLineFormatter.INSTANCE)
+                .formatHeader(null, header).toString();
     }
 
 
     // non-javadoc, see interface LineFormatter
-    public CharArrayBuffer formatHeader(CharArrayBuffer buffer,
-                                        Header header) {
-        if (header == null) {
-            throw new IllegalArgumentException
-                ("Header may not be null");
-        }
-        CharArrayBuffer result = null;
+    public CharArrayBuffer formatHeader(final CharArrayBuffer buffer,
+                                        final Header header) {
+        Args.notNull(header, "Header");
+        final CharArrayBuffer result;
 
         if (header instanceof FormattedHeader) {
             // If the header is backed by a buffer, re-use the buffer
diff --git a/httpcore/src/main/java/org/apache/http/message/BasicLineParser.java b/httpcore/src/main/java/org/apache/http/message/BasicLineParser.java
index ec76d18..4e4bf2e 100644
--- a/httpcore/src/main/java/org/apache/http/message/BasicLineParser.java
+++ b/httpcore/src/main/java/org/apache/http/message/BasicLineParser.java
@@ -27,14 +27,15 @@
 
 package org.apache.http.message;
 
+import org.apache.http.Header;
 import org.apache.http.HttpVersion;
-import org.apache.http.ProtocolVersion;
 import org.apache.http.ParseException;
+import org.apache.http.ProtocolVersion;
 import org.apache.http.RequestLine;
 import org.apache.http.StatusLine;
-import org.apache.http.Header;
 import org.apache.http.annotation.Immutable;
 import org.apache.http.protocol.HTTP;
+import org.apache.http.util.Args;
 import org.apache.http.util.CharArrayBuffer;
 
 /**
@@ -63,9 +64,13 @@ public class BasicLineParser implements LineParser {
      * Note that {@link BasicLineParser} is not a singleton, there can
      * be many instances of the class itself and of derived classes.
      * The instance here provides non-customized, default behavior.
+     *
+     * @deprecated (4.3) use {@link #INSTANCE}
      */
+    @Deprecated
     public final static BasicLineParser DEFAULT = new BasicLineParser();
 
+    public final static BasicLineParser INSTANCE = new BasicLineParser();
 
     /**
      * A version of the protocol to parse.
@@ -81,11 +86,8 @@ public class BasicLineParser implements LineParser {
      *                  <code>null</code> for HTTP. The actual version
      *                  is not relevant, only the protocol name.
      */
-    public BasicLineParser(ProtocolVersion proto) {
-        if (proto == null) {
-            proto = HttpVersion.HTTP_1_1;
-        }
-        this.protocol = proto;
+    public BasicLineParser(final ProtocolVersion proto) {
+        this.protocol = proto != null? proto : HttpVersion.HTTP_1_1;
     }
 
 
@@ -97,43 +99,29 @@ public class BasicLineParser implements LineParser {
     }
 
 
-    public final static
-        ProtocolVersion parseProtocolVersion(String value,
-                                             LineParser parser)
-        throws ParseException {
-
-        if (value == null) {
-            throw new IllegalArgumentException
-                ("Value to parse may not be null.");
-        }
+    public static
+        ProtocolVersion parseProtocolVersion(final String value,
+                                             final LineParser parser) throws ParseException {
+        Args.notNull(value, "Value");
 
-        if (parser == null)
-            parser = BasicLineParser.DEFAULT;
-
-        CharArrayBuffer buffer = new CharArrayBuffer(value.length());
+        final CharArrayBuffer buffer = new CharArrayBuffer(value.length());
         buffer.append(value);
-        ParserCursor cursor = new ParserCursor(0, value.length());
-        return parser.parseProtocolVersion(buffer, cursor);
+        final ParserCursor cursor = new ParserCursor(0, value.length());
+        return (parser != null ? parser : BasicLineParser.INSTANCE)
+                .parseProtocolVersion(buffer, cursor);
     }
 
 
     // non-javadoc, see interface LineParser
     public ProtocolVersion parseProtocolVersion(final CharArrayBuffer buffer,
-                                                final ParserCursor cursor)
-        throws ParseException {
-
-        if (buffer == null) {
-            throw new IllegalArgumentException("Char array buffer may not be null");
-        }
-        if (cursor == null) {
-            throw new IllegalArgumentException("Parser cursor may not be null");
-        }
-
+                                                final ParserCursor cursor) throws ParseException {
+        Args.notNull(buffer, "Char array buffer");
+        Args.notNull(cursor, "Parser cursor");
         final String protoname = this.protocol.getProtocol();
         final int protolength  = protoname.length();
 
-        int indexFrom = cursor.getPos();
-        int indexTo = cursor.getUpperBound();
+        final int indexFrom = cursor.getPos();
+        final int indexTo = cursor.getUpperBound();
 
         skipWhitespace(buffer, cursor);
 
@@ -162,16 +150,16 @@ public class BasicLineParser implements LineParser {
 
         i += protolength+1;
 
-        int period = buffer.indexOf('.', i, indexTo);
+        final int period = buffer.indexOf('.', i, indexTo);
         if (period == -1) {
             throw new ParseException
                 ("Invalid protocol version number: " +
                  buffer.substring(indexFrom, indexTo));
         }
-        int major;
+        final int major;
         try {
             major = Integer.parseInt(buffer.substringTrimmed(i, period));
-        } catch (NumberFormatException e) {
+        } catch (final NumberFormatException e) {
             throw new ParseException
                 ("Invalid protocol major version number: " +
                  buffer.substring(indexFrom, indexTo));
@@ -182,10 +170,10 @@ public class BasicLineParser implements LineParser {
         if (blank == -1) {
             blank = indexTo;
         }
-        int minor;
+        final int minor;
         try {
             minor = Integer.parseInt(buffer.substringTrimmed(i, blank));
-        } catch (NumberFormatException e) {
+        } catch (final NumberFormatException e) {
             throw new ParseException(
                 "Invalid protocol minor version number: " +
                 buffer.substring(indexFrom, indexTo));
@@ -207,7 +195,7 @@ public class BasicLineParser implements LineParser {
      *
      * @return  the protocol version
      */
-    protected ProtocolVersion createProtocolVersion(int major, int minor) {
+    protected ProtocolVersion createProtocolVersion(final int major, final int minor) {
         return protocol.forVersion(major, minor);
     }
 
@@ -216,20 +204,17 @@ public class BasicLineParser implements LineParser {
     // non-javadoc, see interface LineParser
     public boolean hasProtocolVersion(final CharArrayBuffer buffer,
                                       final ParserCursor cursor) {
-
-        if (buffer == null) {
-            throw new IllegalArgumentException("Char array buffer may not be null");
-        }
-        if (cursor == null) {
-            throw new IllegalArgumentException("Parser cursor may not be null");
-        }
+        Args.notNull(buffer, "Char array buffer");
+        Args.notNull(cursor, "Parser cursor");
         int index = cursor.getPos();
 
         final String protoname = this.protocol.getProtocol();
         final int  protolength = protoname.length();
 
         if (buffer.length() < protolength+4)
+         {
             return false; // not long enough for "HTTP/1.1"
+        }
 
         if (index < 0) {
             // end of line, no tolerance for trailing whitespace
@@ -244,8 +229,9 @@ public class BasicLineParser implements LineParser {
         } // else within line, don't tolerate whitespace
 
 
-        if (index + protolength + 4 > buffer.length())
+        if (index + protolength + 4 > buffer.length()) {
             return false;
+        }
 
 
         // just check protocol name and slash, no need to analyse the version
@@ -262,23 +248,16 @@ public class BasicLineParser implements LineParser {
 
 
 
-    public final static
+    public static
         RequestLine parseRequestLine(final String value,
-                                     LineParser parser)
-        throws ParseException {
+                                     final LineParser parser) throws ParseException {
+        Args.notNull(value, "Value");
 
-        if (value == null) {
-            throw new IllegalArgumentException
-                ("Value to parse may not be null.");
-        }
-
-        if (parser == null)
-            parser = BasicLineParser.DEFAULT;
-
-        CharArrayBuffer buffer = new CharArrayBuffer(value.length());
+        final CharArrayBuffer buffer = new CharArrayBuffer(value.length());
         buffer.append(value);
-        ParserCursor cursor = new ParserCursor(0, value.length());
-        return parser.parseRequestLine(buffer, cursor);
+        final ParserCursor cursor = new ParserCursor(0, value.length());
+        return (parser != null ? parser : BasicLineParser.INSTANCE)
+            .parseRequestLine(buffer, cursor);
     }
 
 
@@ -292,18 +271,12 @@ public class BasicLineParser implements LineParser {
      * @throws ParseException        in case of a parse error
      */
     public RequestLine parseRequestLine(final CharArrayBuffer buffer,
-                                        final ParserCursor cursor)
-        throws ParseException {
-
-        if (buffer == null) {
-            throw new IllegalArgumentException("Char array buffer may not be null");
-        }
-        if (cursor == null) {
-            throw new IllegalArgumentException("Parser cursor may not be null");
-        }
+                                        final ParserCursor cursor) throws ParseException {
 
-        int indexFrom = cursor.getPos();
-        int indexTo = cursor.getUpperBound();
+        Args.notNull(buffer, "Char array buffer");
+        Args.notNull(cursor, "Parser cursor");
+        final int indexFrom = cursor.getPos();
+        final int indexTo = cursor.getUpperBound();
 
         try {
             skipWhitespace(buffer, cursor);
@@ -314,7 +287,7 @@ public class BasicLineParser implements LineParser {
                 throw new ParseException("Invalid request line: " +
                         buffer.substring(indexFrom, indexTo));
             }
-            String method = buffer.substringTrimmed(i, blank);
+            final String method = buffer.substringTrimmed(i, blank);
             cursor.updatePos(blank);
 
             skipWhitespace(buffer, cursor);
@@ -325,10 +298,10 @@ public class BasicLineParser implements LineParser {
                 throw new ParseException("Invalid request line: " +
                         buffer.substring(indexFrom, indexTo));
             }
-            String uri = buffer.substringTrimmed(i, blank);
+            final String uri = buffer.substringTrimmed(i, blank);
             cursor.updatePos(blank);
 
-            ProtocolVersion ver = parseProtocolVersion(buffer, cursor);
+            final ProtocolVersion ver = parseProtocolVersion(buffer, cursor);
 
             skipWhitespace(buffer, cursor);
             if (!cursor.atEnd()) {
@@ -337,7 +310,7 @@ public class BasicLineParser implements LineParser {
             }
 
             return createRequestLine(method, uri, ver);
-        } catch (IndexOutOfBoundsException e) {
+        } catch (final IndexOutOfBoundsException e) {
             throw new ParseException("Invalid request line: " +
                                      buffer.substring(indexFrom, indexTo));
         }
@@ -362,44 +335,30 @@ public class BasicLineParser implements LineParser {
 
 
 
-    public final static
+    public static
         StatusLine parseStatusLine(final String value,
-                                   LineParser parser)
-        throws ParseException {
-
-        if (value == null) {
-            throw new IllegalArgumentException
-                ("Value to parse may not be null.");
-        }
+                                   final LineParser parser) throws ParseException {
+        Args.notNull(value, "Value");
 
-        if (parser == null)
-            parser = BasicLineParser.DEFAULT;
-
-        CharArrayBuffer buffer = new CharArrayBuffer(value.length());
+        final CharArrayBuffer buffer = new CharArrayBuffer(value.length());
         buffer.append(value);
-        ParserCursor cursor = new ParserCursor(0, value.length());
-        return parser.parseStatusLine(buffer, cursor);
+        final ParserCursor cursor = new ParserCursor(0, value.length());
+        return (parser != null ? parser : BasicLineParser.INSTANCE)
+                .parseStatusLine(buffer, cursor);
     }
 
 
     // non-javadoc, see interface LineParser
     public StatusLine parseStatusLine(final CharArrayBuffer buffer,
-                                      final ParserCursor cursor)
-        throws ParseException {
-
-        if (buffer == null) {
-            throw new IllegalArgumentException("Char array buffer may not be null");
-        }
-        if (cursor == null) {
-            throw new IllegalArgumentException("Parser cursor may not be null");
-        }
-
-        int indexFrom = cursor.getPos();
-        int indexTo = cursor.getUpperBound();
+                                      final ParserCursor cursor) throws ParseException {
+        Args.notNull(buffer, "Char array buffer");
+        Args.notNull(cursor, "Parser cursor");
+        final int indexFrom = cursor.getPos();
+        final int indexTo = cursor.getUpperBound();
 
         try {
             // handle the HTTP-Version
-            ProtocolVersion ver = parseProtocolVersion(buffer, cursor);
+            final ProtocolVersion ver = parseProtocolVersion(buffer, cursor);
 
             // handle the Status-Code
             skipWhitespace(buffer, cursor);
@@ -409,8 +368,8 @@ public class BasicLineParser implements LineParser {
             if (blank < 0) {
                 blank = indexTo;
             }
-            int statusCode = 0;
-            String s = buffer.substringTrimmed(i, blank);
+            final int statusCode;
+            final String s = buffer.substringTrimmed(i, blank);
             for (int j = 0; j < s.length(); j++) {
                 if (!Character.isDigit(s.charAt(j))) {
                     throw new ParseException(
@@ -420,14 +379,14 @@ public class BasicLineParser implements LineParser {
             }
             try {
                 statusCode = Integer.parseInt(s);
-            } catch (NumberFormatException e) {
+            } catch (final NumberFormatException e) {
                 throw new ParseException(
                         "Status line contains invalid status code: "
                         + buffer.substring(indexFrom, indexTo));
             }
             //handle the Reason-Phrase
             i = blank;
-            String reasonPhrase = null;
+            final String reasonPhrase;
             if (i < indexTo) {
                 reasonPhrase = buffer.substringTrimmed(i, indexTo);
             } else {
@@ -435,7 +394,7 @@ public class BasicLineParser implements LineParser {
             }
             return createStatusLine(ver, statusCode, reasonPhrase);
 
-        } catch (IndexOutOfBoundsException e) {
+        } catch (final IndexOutOfBoundsException e) {
             throw new ParseException("Invalid status line: " +
                                      buffer.substring(indexFrom, indexTo));
         }
@@ -460,27 +419,20 @@ public class BasicLineParser implements LineParser {
 
 
 
-    public final static
+    public static
         Header parseHeader(final String value,
-                           LineParser parser)
-        throws ParseException {
-
-        if (value == null) {
-            throw new IllegalArgumentException
-                ("Value to parse may not be null");
-        }
-
-        if (parser == null)
-            parser = BasicLineParser.DEFAULT;
+                           final LineParser parser) throws ParseException {
+        Args.notNull(value, "Value");
 
-        CharArrayBuffer buffer = new CharArrayBuffer(value.length());
+        final CharArrayBuffer buffer = new CharArrayBuffer(value.length());
         buffer.append(value);
-        return parser.parseHeader(buffer);
+        return (parser != null ? parser : BasicLineParser.INSTANCE)
+                .parseHeader(buffer);
     }
 
 
     // non-javadoc, see interface LineParser
-    public Header parseHeader(CharArrayBuffer buffer)
+    public Header parseHeader(final CharArrayBuffer buffer)
         throws ParseException {
 
         // the actual parser code is in the constructor of BufferedHeader
@@ -493,7 +445,7 @@ public class BasicLineParser implements LineParser {
      */
     protected void skipWhitespace(final CharArrayBuffer buffer, final ParserCursor cursor) {
         int pos = cursor.getPos();
-        int indexTo = cursor.getUpperBound();
+        final int indexTo = cursor.getUpperBound();
         while ((pos < indexTo) &&
                HTTP.isWhitespace(buffer.charAt(pos))) {
             pos++;
diff --git a/httpcore/src/main/java/org/apache/http/message/BasicListHeaderIterator.java b/httpcore/src/main/java/org/apache/http/message/BasicListHeaderIterator.java
index 2f4091c..7ddfc4a 100644
--- a/httpcore/src/main/java/org/apache/http/message/BasicListHeaderIterator.java
+++ b/httpcore/src/main/java/org/apache/http/message/BasicListHeaderIterator.java
@@ -33,6 +33,8 @@ import java.util.NoSuchElementException;
 import org.apache.http.Header;
 import org.apache.http.HeaderIterator;
 import org.apache.http.annotation.NotThreadSafe;
+import org.apache.http.util.Args;
+import org.apache.http.util.Asserts;
 
 /**
  * Implementation of a {@link HeaderIterator} based on a {@link List}.
@@ -79,13 +81,9 @@ public class BasicListHeaderIterator implements HeaderIterator {
      * @param name      the name of the headers over which to iterate, or
      *                  <code>null</code> for any
      */
-    public BasicListHeaderIterator(List<Header> headers, String name) {
-        if (headers == null) {
-            throw new IllegalArgumentException
-                ("Header list must not be null.");
-        }
-
-        this.allHeaders = headers;
+    public BasicListHeaderIterator(final List<Header> headers, final String name) {
+        super();
+        this.allHeaders = Args.notNull(headers, "Header list");
         this.headerName = name;
         this.currentIndex = findNext(-1);
         this.lastIndex = -1;
@@ -95,15 +93,17 @@ public class BasicListHeaderIterator implements HeaderIterator {
     /**
      * Determines the index of the next header.
      *
-     * @param from      one less than the index to consider first,
+     * @param pos       one less than the index to consider first,
      *                  -1 to search for the first header
      *
      * @return  the index of the next header that matches the filter name,
      *          or negative if there are no more headers
      */
-    protected int findNext(int from) {
-        if (from < -1)
+    protected int findNext(final int pos) {
+        int from = pos;
+        if (from < -1) {
             return -1;
+        }
 
         final int to = this.allHeaders.size()-1;
         boolean found = false;
@@ -123,9 +123,10 @@ public class BasicListHeaderIterator implements HeaderIterator {
      * @return  <code>true</code> if the header should be part of the
      *          iteration, <code>false</code> to skip
      */
-    protected boolean filterHeader(int index) {
-        if (this.headerName == null)
+    protected boolean filterHeader(final int index) {
+        if (this.headerName == null) {
             return true;
+        }
 
         // non-header elements, including null, will trigger exceptions
         final String name = (this.allHeaders.get(index)).getName();
@@ -181,10 +182,7 @@ public class BasicListHeaderIterator implements HeaderIterator {
      */
     public void remove()
         throws UnsupportedOperationException {
-
-        if (this.lastIndex < 0) {
-            throw new IllegalStateException("No header to remove.");
-        }
+        Asserts.check(this.lastIndex >= 0, "No header to remove");
         this.allHeaders.remove(this.lastIndex);
         this.lastIndex = -1;
         this.currentIndex--; // adjust for the removed element
diff --git a/httpcore/src/main/java/org/apache/http/message/BasicNameValuePair.java b/httpcore/src/main/java/org/apache/http/message/BasicNameValuePair.java
index 7f9d32d..92aad56 100644
--- a/httpcore/src/main/java/org/apache/http/message/BasicNameValuePair.java
+++ b/httpcore/src/main/java/org/apache/http/message/BasicNameValuePair.java
@@ -31,6 +31,7 @@ import java.io.Serializable;
 
 import org.apache.http.NameValuePair;
 import org.apache.http.annotation.Immutable;
+import org.apache.http.util.Args;
 import org.apache.http.util.LangUtils;
 
 /**
@@ -54,10 +55,7 @@ public class BasicNameValuePair implements NameValuePair, Cloneable, Serializabl
      */
     public BasicNameValuePair(final String name, final String value) {
         super();
-        if (name == null) {
-            throw new IllegalArgumentException("Name may not be null");
-        }
-        this.name = name;
+        this.name = Args.notNull(name, "Name");
         this.value = value;
     }
 
@@ -75,26 +73,26 @@ public class BasicNameValuePair implements NameValuePair, Cloneable, Serializabl
 
         if (this.value == null) {
             return name;
-        } else {
-            int len = this.name.length() + 1 + this.value.length();
-            StringBuilder buffer = new StringBuilder(len);
-            buffer.append(this.name);
-            buffer.append("=");
-            buffer.append(this.value);
-            return buffer.toString();
         }
+        final int len = this.name.length() + 1 + this.value.length();
+        final StringBuilder buffer = new StringBuilder(len);
+        buffer.append(this.name);
+        buffer.append("=");
+        buffer.append(this.value);
+        return buffer.toString();
     }
 
     @Override
     public boolean equals(final Object object) {
-        if (this == object) return true;
+        if (this == object) {
+            return true;
+        }
         if (object instanceof NameValuePair) {
-            BasicNameValuePair that = (BasicNameValuePair) object;
+            final BasicNameValuePair that = (BasicNameValuePair) object;
             return this.name.equals(that.name)
                   && LangUtils.equals(this.value, that.value);
-        } else {
-            return false;
         }
+        return false;
     }
 
     @Override
diff --git a/httpcore/src/main/java/org/apache/http/message/BasicRequestLine.java b/httpcore/src/main/java/org/apache/http/message/BasicRequestLine.java
index 23f7048..41a9e25 100644
--- a/httpcore/src/main/java/org/apache/http/message/BasicRequestLine.java
+++ b/httpcore/src/main/java/org/apache/http/message/BasicRequestLine.java
@@ -32,6 +32,7 @@ import java.io.Serializable;
 import org.apache.http.ProtocolVersion;
 import org.apache.http.RequestLine;
 import org.apache.http.annotation.Immutable;
+import org.apache.http.util.Args;
 
 /**
  * Basic implementation of {@link RequestLine}.
@@ -51,21 +52,9 @@ public class BasicRequestLine implements RequestLine, Cloneable, Serializable {
                             final String uri,
                             final ProtocolVersion version) {
         super();
-        if (method == null) {
-            throw new IllegalArgumentException
-                ("Method must not be null.");
-        }
-        if (uri == null) {
-            throw new IllegalArgumentException
-                ("URI must not be null.");
-        }
-        if (version == null) {
-            throw new IllegalArgumentException
-                ("Protocol version must not be null.");
-        }
-        this.method = method;
-        this.uri = uri;
-        this.protoversion = version;
+        this.method = Args.notNull(method, "Method");
+        this.uri = Args.notNull(uri, "URI");
+        this.protoversion = Args.notNull(version, "Version");
     }
 
     public String getMethod() {
@@ -83,8 +72,7 @@ public class BasicRequestLine implements RequestLine, Cloneable, Serializable {
     @Override
     public String toString() {
         // no need for non-default formatting in toString()
-        return BasicLineFormatter.DEFAULT
-            .formatRequestLine(null, this).toString();
+        return BasicLineFormatter.INSTANCE.formatRequestLine(null, this).toString();
     }
 
     @Override
diff --git a/httpcore/src/main/java/org/apache/http/message/BasicStatusLine.java b/httpcore/src/main/java/org/apache/http/message/BasicStatusLine.java
index 7d6c28b..2cfdbdc 100644
--- a/httpcore/src/main/java/org/apache/http/message/BasicStatusLine.java
+++ b/httpcore/src/main/java/org/apache/http/message/BasicStatusLine.java
@@ -32,6 +32,7 @@ import java.io.Serializable;
 import org.apache.http.ProtocolVersion;
 import org.apache.http.StatusLine;
 import org.apache.http.annotation.Immutable;
+import org.apache.http.util.Args;
 
 /**
  * Basic implementation of {@link StatusLine}
@@ -63,19 +64,11 @@ public class BasicStatusLine implements StatusLine, Cloneable, Serializable {
      * @param reasonPhrase      the reason phrase to the status code, or
      *                          <code>null</code>
      */
-    public BasicStatusLine(final ProtocolVersion version, int statusCode,
+    public BasicStatusLine(final ProtocolVersion version, final int statusCode,
                            final String reasonPhrase) {
         super();
-        if (version == null) {
-            throw new IllegalArgumentException
-                ("Protocol version may not be null.");
-        }
-        if (statusCode < 0) {
-            throw new IllegalArgumentException
-                ("Status code may not be negative.");
-        }
-        this.protoVersion = version;
-        this.statusCode   = statusCode;
+        this.protoVersion = Args.notNull(version, "Version");
+        this.statusCode = Args.notNegative(statusCode, "Status code");
         this.reasonPhrase = reasonPhrase;
     }
 
@@ -96,8 +89,7 @@ public class BasicStatusLine implements StatusLine, Cloneable, Serializable {
     @Override
     public String toString() {
         // no need for non-default formatting in toString()
-        return BasicLineFormatter.DEFAULT
-            .formatStatusLine(null, this).toString();
+        return BasicLineFormatter.INSTANCE.formatStatusLine(null, this).toString();
     }
 
     @Override
diff --git a/httpcore/src/main/java/org/apache/http/message/BasicTokenIterator.java b/httpcore/src/main/java/org/apache/http/message/BasicTokenIterator.java
index d2c05c5..046b3b9 100644
--- a/httpcore/src/main/java/org/apache/http/message/BasicTokenIterator.java
+++ b/httpcore/src/main/java/org/apache/http/message/BasicTokenIterator.java
@@ -33,6 +33,7 @@ import org.apache.http.HeaderIterator;
 import org.apache.http.ParseException;
 import org.apache.http.TokenIterator;
 import org.apache.http.annotation.NotThreadSafe;
+import org.apache.http.util.Args;
 
 /**
  * Basic implementation of a {@link TokenIterator}.
@@ -62,7 +63,7 @@ public class BasicTokenIterator implements TokenIterator {
     protected String currentHeader;
 
     /**
-     * The token to be returned by the next call to {@link #currentToken}.
+     * The token to be returned by the next call to {@link #nextToken()}.
      * <code>null</code> if the iteration is over.
      */
     protected String currentToken;
@@ -80,12 +81,8 @@ public class BasicTokenIterator implements TokenIterator {
      * @param headerIterator    the iterator for the headers to tokenize
      */
     public BasicTokenIterator(final HeaderIterator headerIterator) {
-        if (headerIterator == null) {
-            throw new IllegalArgumentException
-                ("Header iterator must not be null.");
-        }
-
-        this.headerIt = headerIterator;
+        super();
+        this.headerIt = Args.notNull(headerIterator, "Header iterator");
         this.searchPos = findNext(-1);
     }
 
@@ -155,7 +152,7 @@ public class BasicTokenIterator implements TokenIterator {
      * will be obtained from {@link #headerIt}.
      * If not found, {@link #currentToken} is set to <code>null</code>.
      *
-     * @param from      the position in the current header at which to
+     * @param pos       the position in the current header at which to
      *                  start the search, -1 to search in the first header
      *
      * @return  the position after the found token in the current header, or
@@ -163,9 +160,8 @@ public class BasicTokenIterator implements TokenIterator {
      *
      * @throws ParseException   if an invalid header value is encountered
      */
-    protected int findNext(int from)
-        throws ParseException {
-
+    protected int findNext(final int pos) throws ParseException {
+        int from = pos;
         if (from < 0) {
             // called from the constructor, initialize the first header
             if (!this.headerIt.hasNext()) {
@@ -178,13 +174,13 @@ public class BasicTokenIterator implements TokenIterator {
             from = findTokenSeparator(from);
         }
 
-        int start = findTokenStart(from);
+        final int start = findTokenStart(from);
         if (start < 0) {
             this.currentToken = null;
             return -1; // nothing found
         }
 
-        int end = findTokenEnd(start);
+        final int end = findTokenEnd(start);
         this.currentToken = createToken(this.currentHeader, start, end);
         return end;
     }
@@ -210,7 +206,7 @@ public class BasicTokenIterator implements TokenIterator {
      *
      * @return  a string representing the token identified by the arguments
      */
-    protected String createToken(String value, int start, int end) {
+    protected String createToken(final String value, final int start, final int end) {
         return value.substring(start, end);
     }
 
@@ -219,18 +215,14 @@ public class BasicTokenIterator implements TokenIterator {
      * Determines the starting position of the next token.
      * This method will iterate over headers if necessary.
      *
-     * @param from      the position in the current header at which to
+     * @param pos       the position in the current header at which to
      *                  start the search
      *
      * @return  the position of the token start in the current header,
      *          negative if no token start could be found
      */
-    protected int findTokenStart(int from) {
-        if (from < 0) {
-            throw new IllegalArgumentException
-                ("Search position must not be negative: " + from);
-        }
-
+    protected int findTokenStart(final int pos) {
+        int from = Args.notNegative(pos, "Search position");
         boolean found = false;
         while (!found && (this.currentHeader != null)) {
 
@@ -270,7 +262,7 @@ public class BasicTokenIterator implements TokenIterator {
      * header value is a token separator. This method does
      * therefore not need to iterate over headers.
      *
-     * @param from      the position in the current header at which to
+     * @param pos       the position in the current header at which to
      *                  start the search
      *
      * @return  the position of a token separator in the current header,
@@ -281,12 +273,8 @@ public class BasicTokenIterator implements TokenIterator {
      *         RFC 2616, section 2.1 explicitly requires a comma between
      *         tokens for <tt>#</tt>.
      */
-    protected int findTokenSeparator(int from) {
-        if (from < 0) {
-            throw new IllegalArgumentException
-                ("Search position must not be negative: " + from);
-        }
-
+    protected int findTokenSeparator(final int pos) {
+        int from = Args.notNegative(pos, "Search position");
         boolean found = false;
         final int to = this.currentHeader.length();
         while (!found && (from < to)) {
@@ -321,12 +309,8 @@ public class BasicTokenIterator implements TokenIterator {
      *          The behavior is undefined if <code>from</code> does not
      *          point to a token character in the current header value.
      */
-    protected int findTokenEnd(int from) {
-        if (from < 0) {
-            throw new IllegalArgumentException
-                ("Token start position must not be negative: " + from);
-        }
-
+    protected int findTokenEnd(final int from) {
+        Args.notNegative(from, "Search position");
         final int to = this.currentHeader.length();
         int end = from+1;
         while ((end < to) && isTokenChar(this.currentHeader.charAt(end))) {
@@ -348,7 +332,7 @@ public class BasicTokenIterator implements TokenIterator {
      * @return  <code>true</code> if the character is a token separator,
      *          <code>false</code> otherwise
      */
-    protected boolean isTokenSeparator(char ch) {
+    protected boolean isTokenSeparator(final char ch) {
         return (ch == ',');
     }
 
@@ -364,7 +348,7 @@ public class BasicTokenIterator implements TokenIterator {
      * @return  <code>true</code> if the character is whitespace,
      *          <code>false</code> otherwise
      */
-    protected boolean isWhitespace(char ch) {
+    protected boolean isWhitespace(final char ch) {
 
         // we do not use Character.isWhitspace(ch) here, since that allows
         // many control characters which are not whitespace as per RFC 2616
@@ -384,19 +368,22 @@ public class BasicTokenIterator implements TokenIterator {
      * @return  <code>true</code> if the character is a valid token start,
      *          <code>false</code> otherwise
      */
-    protected boolean isTokenChar(char ch) {
+    protected boolean isTokenChar(final char ch) {
 
         // common sense extension of ALPHA + DIGIT
-        if (Character.isLetterOrDigit(ch))
+        if (Character.isLetterOrDigit(ch)) {
             return true;
+        }
 
         // common sense extension of CTL
-        if (Character.isISOControl(ch))
+        if (Character.isISOControl(ch)) {
             return false;
+        }
 
         // no common sense extension for this
-        if (isHttpSeparator(ch))
+        if (isHttpSeparator(ch)) {
             return false;
+        }
 
         // RFC 2616, section 2.2 defines a token character as
         // "any CHAR except CTLs or separators". The controls
@@ -418,7 +405,7 @@ public class BasicTokenIterator implements TokenIterator {
      *
      * @return  <code>true</code> if the character is an HTTP separator
      */
-    protected boolean isHttpSeparator(char ch) {
+    protected boolean isHttpSeparator(final char ch) {
         return (HTTP_SEPARATORS.indexOf(ch) >= 0);
     }
 
diff --git a/httpcore/src/main/java/org/apache/http/message/BufferedHeader.java b/httpcore/src/main/java/org/apache/http/message/BufferedHeader.java
index ec573ea..d8d62f4 100644
--- a/httpcore/src/main/java/org/apache/http/message/BufferedHeader.java
+++ b/httpcore/src/main/java/org/apache/http/message/BufferedHeader.java
@@ -33,6 +33,7 @@ import org.apache.http.FormattedHeader;
 import org.apache.http.HeaderElement;
 import org.apache.http.ParseException;
 import org.apache.http.annotation.NotThreadSafe;
+import org.apache.http.util.Args;
 import org.apache.http.util.CharArrayBuffer;
 
 /**
@@ -75,16 +76,13 @@ public class BufferedHeader implements FormattedHeader, Cloneable, Serializable
         throws ParseException {
 
         super();
-        if (buffer == null) {
-            throw new IllegalArgumentException
-                ("Char array buffer may not be null");
-        }
-        int colon = buffer.indexOf(':');
+        Args.notNull(buffer, "Char array buffer");
+        final int colon = buffer.indexOf(':');
         if (colon == -1) {
             throw new ParseException
                 ("Invalid header: " + buffer.toString());
         }
-        String s = buffer.substringTrimmed(0, colon);
+        final String s = buffer.substringTrimmed(0, colon);
         if (s.length() == 0) {
             throw new ParseException
                 ("Invalid header: " + buffer.toString());
@@ -104,10 +102,9 @@ public class BufferedHeader implements FormattedHeader, Cloneable, Serializable
     }
 
     public HeaderElement[] getElements() throws ParseException {
-        ParserCursor cursor = new ParserCursor(0, this.buffer.length());
+        final ParserCursor cursor = new ParserCursor(0, this.buffer.length());
         cursor.updatePos(this.valuePos);
-        return BasicHeaderValueParser.DEFAULT
-            .parseElements(this.buffer, cursor);
+        return BasicHeaderValueParser.INSTANCE.parseElements(this.buffer, cursor);
     }
 
     public int getValuePos() {
diff --git a/httpcore/src/main/java/org/apache/http/message/HeaderGroup.java b/httpcore/src/main/java/org/apache/http/message/HeaderGroup.java
index 0725e89..6432406 100644
--- a/httpcore/src/main/java/org/apache/http/message/HeaderGroup.java
+++ b/httpcore/src/main/java/org/apache/http/message/HeaderGroup.java
@@ -29,6 +29,7 @@ package org.apache.http.message;
 
 import java.io.Serializable;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 import java.util.Locale;
 
@@ -73,7 +74,7 @@ public class HeaderGroup implements Cloneable, Serializable {
      *
      * @param header the header to add
      */
-    public void addHeader(Header header) {
+    public void addHeader(final Header header) {
         if (header == null) {
             return;
         }
@@ -85,7 +86,7 @@ public class HeaderGroup implements Cloneable, Serializable {
      *
      * @param header the header to remove
      */
-    public void removeHeader(Header header) {
+    public void removeHeader(final Header header) {
         if (header == null) {
             return;
         }
@@ -99,12 +100,12 @@ public class HeaderGroup implements Cloneable, Serializable {
      * @param header the new header that should replace the first header with the same
      * name if present in the list.
      */
-    public void updateHeader(Header header) {
+    public void updateHeader(final Header header) {
         if (header == null) {
             return;
         }
         for (int i = 0; i < this.headers.size(); i++) {
-            Header current = this.headers.get(i);
+            final Header current = this.headers.get(i);
             if (current.getName().equalsIgnoreCase(header.getName())) {
                 this.headers.set(i, header);
                 return;
@@ -120,14 +121,12 @@ public class HeaderGroup implements Cloneable, Serializable {
      *
      * @param headers the headers to set
      */
-    public void setHeaders(Header[] headers) {
+    public void setHeaders(final Header[] headers) {
         clear();
         if (headers == null) {
             return;
         }
-        for (int i = 0; i < headers.length; i++) {
-            this.headers.add(headers[i]);
-        }
+        Collections.addAll(this.headers, headers);
     }
 
     /**
@@ -141,15 +140,15 @@ public class HeaderGroup implements Cloneable, Serializable {
      * @return a header with a condensed value or <code>null</code> if no
      * headers by the given name are present
      */
-    public Header getCondensedHeader(String name) {
-        Header[] headers = getHeaders(name);
+    public Header getCondensedHeader(final String name) {
+        final Header[] headers = getHeaders(name);
 
         if (headers.length == 0) {
             return null;
         } else if (headers.length == 1) {
             return headers[0];
         } else {
-            CharArrayBuffer valueBuffer = new CharArrayBuffer(128);
+            final CharArrayBuffer valueBuffer = new CharArrayBuffer(128);
             valueBuffer.append(headers[0].getValue());
             for (int i = 1; i < headers.length; i++) {
                 valueBuffer.append(", ");
@@ -170,11 +169,10 @@ public class HeaderGroup implements Cloneable, Serializable {
      *
      * @return an array of length >= 0
      */
-    public Header[] getHeaders(String name) {
-        List<Header> headersFound = new ArrayList<Header>();
+    public Header[] getHeaders(final String name) {
+        final List<Header> headersFound = new ArrayList<Header>();
 
-        for (int i = 0; i < headers.size(); i++) {
-            Header header = headers.get(i);
+        for (final Header header : headers) {
             if (header.getName().equalsIgnoreCase(name)) {
                 headersFound.add(header);
             }
@@ -191,9 +189,8 @@ public class HeaderGroup implements Cloneable, Serializable {
      * @param name the name of the header to get
      * @return the first header or <code>null</code>
      */
-    public Header getFirstHeader(String name) {
-        for (int i = 0; i < headers.size(); i++) {
-            Header header = headers.get(i);
+    public Header getFirstHeader(final String name) {
+        for (final Header header : headers) {
             if (header.getName().equalsIgnoreCase(name)) {
                 return header;
             }
@@ -209,10 +206,10 @@ public class HeaderGroup implements Cloneable, Serializable {
      * @param name the name of the header to get
      * @return the last header or <code>null</code>
      */
-    public Header getLastHeader(String name) {
+    public Header getLastHeader(final String name) {
         // start at the end of the list and work backwards
         for (int i = headers.size() - 1; i >= 0; i--) {
-            Header header = headers.get(i);
+            final Header header = headers.get(i);
             if (header.getName().equalsIgnoreCase(name)) {
                 return header;
             }
@@ -239,9 +236,8 @@ public class HeaderGroup implements Cloneable, Serializable {
      * @return <code>true</code> if at least one header with the name is
      * contained, <code>false</code> otherwise
      */
-    public boolean containsHeader(String name) {
-        for (int i = 0; i < headers.size(); i++) {
-            Header header = headers.get(i);
+    public boolean containsHeader(final String name) {
+        for (final Header header : headers) {
             if (header.getName().equalsIgnoreCase(name)) {
                 return true;
             }
@@ -283,7 +279,7 @@ public class HeaderGroup implements Cloneable, Serializable {
      * @since 4.0
      */
     public HeaderGroup copy() {
-        HeaderGroup clone = new HeaderGroup();
+        final HeaderGroup clone = new HeaderGroup();
         clone.headers.addAll(this.headers);
         return clone;
     }
diff --git a/httpcore/src/main/java/org/apache/http/message/LineFormatter.java b/httpcore/src/main/java/org/apache/http/message/LineFormatter.java
index 8e7649a..b3163c4 100644
--- a/httpcore/src/main/java/org/apache/http/message/LineFormatter.java
+++ b/httpcore/src/main/java/org/apache/http/message/LineFormatter.java
@@ -27,10 +27,10 @@
 
 package org.apache.http.message;
 
+import org.apache.http.Header;
 import org.apache.http.ProtocolVersion;
 import org.apache.http.RequestLine;
 import org.apache.http.StatusLine;
-import org.apache.http.Header;
 import org.apache.http.util.CharArrayBuffer;
 
 /**
diff --git a/httpcore/src/main/java/org/apache/http/message/LineParser.java b/httpcore/src/main/java/org/apache/http/message/LineParser.java
index eaea38a..5418f44 100644
--- a/httpcore/src/main/java/org/apache/http/message/LineParser.java
+++ b/httpcore/src/main/java/org/apache/http/message/LineParser.java
@@ -27,11 +27,11 @@
 
 package org.apache.http.message;
 
-import org.apache.http.ProtocolVersion;
+import org.apache.http.Header;
 import org.apache.http.ParseException;
+import org.apache.http.ProtocolVersion;
 import org.apache.http.RequestLine;
 import org.apache.http.StatusLine;
-import org.apache.http.Header;
 import org.apache.http.util.CharArrayBuffer;
 
 /**
diff --git a/httpcore/src/main/java/org/apache/http/message/ParserCursor.java b/httpcore/src/main/java/org/apache/http/message/ParserCursor.java
index ffa96f5..c92b14a 100644
--- a/httpcore/src/main/java/org/apache/http/message/ParserCursor.java
+++ b/httpcore/src/main/java/org/apache/http/message/ParserCursor.java
@@ -45,7 +45,7 @@ public class ParserCursor {
     private final int upperBound;
     private int pos;
 
-    public ParserCursor(int lowerBound, int upperBound) {
+    public ParserCursor(final int lowerBound, final int upperBound) {
         super();
         if (lowerBound < 0) {
             throw new IndexOutOfBoundsException("Lower bound cannot be negative");
@@ -70,7 +70,7 @@ public class ParserCursor {
         return this.pos;
     }
 
-    public void updatePos(int pos) {
+    public void updatePos(final int pos) {
         if (pos < this.lowerBound) {
             throw new IndexOutOfBoundsException("pos: "+pos+" < lowerBound: "+this.lowerBound);
         }
@@ -86,7 +86,7 @@ public class ParserCursor {
 
     @Override
     public String toString() {
-        StringBuilder buffer = new StringBuilder();
+        final StringBuilder buffer = new StringBuilder();
         buffer.append('[');
         buffer.append(Integer.toString(this.lowerBound));
         buffer.append('>');
diff --git a/httpcore/src/main/java/org/apache/http/params/AbstractHttpParams.java b/httpcore/src/main/java/org/apache/http/params/AbstractHttpParams.java
index c0d5561..5b83318 100644
--- a/httpcore/src/main/java/org/apache/http/params/AbstractHttpParams.java
+++ b/httpcore/src/main/java/org/apache/http/params/AbstractHttpParams.java
@@ -29,16 +29,17 @@ package org.apache.http.params;
 
 import java.util.Set;
 
-import org.apache.http.params.HttpParams;
-
-
 /**
  * Abstract base class for parameter collections.
  * Type specific setters and getters are mapped to the abstract,
  * generic getters and setters.
  *
  * @since 4.0
+ *
+ * @deprecated (4.3) use configuration classes provided 'org.apache.http.config'
+ *  and 'org.apache.http.client.config'
  */
+ at Deprecated
 public abstract class AbstractHttpParams implements HttpParams, HttpParamsNames {
 
     /**
@@ -48,54 +49,54 @@ public abstract class AbstractHttpParams implements HttpParams, HttpParamsNames
         super();
     }
 
-    public long getLongParameter(final String name, long defaultValue) {
-        Object param = getParameter(name);
+    public long getLongParameter(final String name, final long defaultValue) {
+        final Object param = getParameter(name);
         if (param == null) {
             return defaultValue;
         }
-        return ((Long)param).longValue();
+        return ((Long) param).longValue();
     }
 
-    public HttpParams setLongParameter(final String name, long value) {
-        setParameter(name, new Long(value));
+    public HttpParams setLongParameter(final String name, final long value) {
+        setParameter(name, Long.valueOf(value));
         return this;
     }
 
-    public int getIntParameter(final String name, int defaultValue) {
-        Object param = getParameter(name);
+    public int getIntParameter(final String name, final int defaultValue) {
+        final Object param = getParameter(name);
         if (param == null) {
             return defaultValue;
         }
-        return ((Integer)param).intValue();
+        return ((Integer) param).intValue();
     }
 
-    public HttpParams setIntParameter(final String name, int value) {
-        setParameter(name, new Integer(value));
+    public HttpParams setIntParameter(final String name, final int value) {
+        setParameter(name, Integer.valueOf(value));
         return this;
     }
 
-    public double getDoubleParameter(final String name, double defaultValue) {
-        Object param = getParameter(name);
+    public double getDoubleParameter(final String name, final double defaultValue) {
+        final Object param = getParameter(name);
         if (param == null) {
             return defaultValue;
         }
-        return ((Double)param).doubleValue();
+        return ((Double) param).doubleValue();
     }
 
-    public HttpParams setDoubleParameter(final String name, double value) {
-        setParameter(name, new Double(value));
+    public HttpParams setDoubleParameter(final String name, final double value) {
+        setParameter(name, Double.valueOf(value));
         return this;
     }
 
-    public boolean getBooleanParameter(final String name, boolean defaultValue) {
-        Object param = getParameter(name);
+    public boolean getBooleanParameter(final String name, final boolean defaultValue) {
+        final Object param = getParameter(name);
         if (param == null) {
             return defaultValue;
         }
-        return ((Boolean)param).booleanValue();
+        return ((Boolean) param).booleanValue();
     }
 
-    public HttpParams setBooleanParameter(final String name, boolean value) {
+    public HttpParams setBooleanParameter(final String name, final boolean value) {
         setParameter(name, value ? Boolean.TRUE : Boolean.FALSE);
         return this;
     }
diff --git a/httpcore/src/main/java/org/apache/http/params/BasicHttpParams.java b/httpcore/src/main/java/org/apache/http/params/BasicHttpParams.java
index 8e12bf3..f053a03 100644
--- a/httpcore/src/main/java/org/apache/http/params/BasicHttpParams.java
+++ b/httpcore/src/main/java/org/apache/http/params/BasicHttpParams.java
@@ -30,12 +30,10 @@ package org.apache.http.params;
 import java.io.Serializable;
 import java.util.HashSet;
 import java.util.Map;
-import java.util.HashMap;
-import java.util.Iterator;
 import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
 
-import org.apache.http.annotation.NotThreadSafe;
-import org.apache.http.params.HttpParams;
+import org.apache.http.annotation.ThreadSafe;
 
 /**
  * Default implementation of {@link HttpParams} interface.
@@ -44,14 +42,18 @@ import org.apache.http.params.HttpParams;
  * synchronized and therefore this class may be thread-unsafe.
  *
  * @since 4.0
+ *
+ * @deprecated (4.3) use configuration classes provided 'org.apache.http.config'
+ *  and 'org.apache.http.client.config'
  */
- at NotThreadSafe
+ at Deprecated
+ at ThreadSafe
 public class BasicHttpParams extends AbstractHttpParams implements Serializable, Cloneable {
 
     private static final long serialVersionUID = -7086398485908701455L;
 
     /** Map of HTTP parameters that this collection contains. */
-    private final HashMap<String, Object> parameters = new HashMap<String, Object>();
+    private final Map<String, Object> parameters = new ConcurrentHashMap<String, Object>();
 
     public BasicHttpParams() {
         super();
@@ -62,11 +64,18 @@ public class BasicHttpParams extends AbstractHttpParams implements Serializable,
     }
 
     public HttpParams setParameter(final String name, final Object value) {
-        this.parameters.put(name, value);
+        if (name == null) {
+            return this;
+        }
+        if (value != null) {
+            this.parameters.put(name, value);
+        } else {
+            this.parameters.remove(name);
+        }
         return this;
     }
 
-    public boolean removeParameter(String name) {
+    public boolean removeParameter(final String name) {
         //this is to avoid the case in which the key has a null value
         if (this.parameters.containsKey(name)) {
             this.parameters.remove(name);
@@ -83,8 +92,8 @@ public class BasicHttpParams extends AbstractHttpParams implements Serializable,
      * @param value parameter value
      */
     public void setParameters(final String[] names, final Object value) {
-        for (int i = 0; i < names.length; i++) {
-            setParameter(names[i], value);
+        for (final String name : names) {
+            setParameter(name, value);
         }
     }
 
@@ -131,14 +140,12 @@ public class BasicHttpParams extends AbstractHttpParams implements Serializable,
      * @return  a new set of params holding a copy of the
      *          <i>local</i> parameters in this object.
      *
-     * @deprecated (4.1)
      * @throws UnsupportedOperationException if the clone() fails
      */
-    @Deprecated
     public HttpParams copy() {
         try {
             return (HttpParams) clone();
-        } catch (CloneNotSupportedException ex) {
+        } catch (final CloneNotSupportedException ex) {
             throw new UnsupportedOperationException("Cloning not supported");
         }
     }
@@ -149,7 +156,7 @@ public class BasicHttpParams extends AbstractHttpParams implements Serializable,
      */
     @Override
     public Object clone() throws CloneNotSupportedException {
-        BasicHttpParams clone = (BasicHttpParams) super.clone();
+        final BasicHttpParams clone = (BasicHttpParams) super.clone();
         copyParams(clone);
         return clone;
     }
@@ -161,12 +168,9 @@ public class BasicHttpParams extends AbstractHttpParams implements Serializable,
      * @param target    the parameters to which to copy
      * @since 4.2
      */
-    public void copyParams(HttpParams target) {
-        Iterator<Map.Entry<String, Object>> iter = this.parameters.entrySet().iterator();
-        while (iter.hasNext()) {
-            Map.Entry<String, Object> me = iter.next();
-            if (me.getKey() instanceof String)
-                target.setParameter(me.getKey(), me.getValue());
+    public void copyParams(final HttpParams target) {
+        for (final Map.Entry<String, Object> me : this.parameters.entrySet()) {
+            target.setParameter(me.getKey(), me.getValue());
         }
     }
 
diff --git a/httpcore/src/main/java/org/apache/http/params/CoreConnectionPNames.java b/httpcore/src/main/java/org/apache/http/params/CoreConnectionPNames.java
index 02d0768..61dd753 100644
--- a/httpcore/src/main/java/org/apache/http/params/CoreConnectionPNames.java
+++ b/httpcore/src/main/java/org/apache/http/params/CoreConnectionPNames.java
@@ -31,7 +31,11 @@ package org.apache.http.params;
  * Defines parameter names for connections in HttpCore.
  *
  * @since 4.0
+ *
+ * @deprecated (4.3) use configuration classes provided 'org.apache.http.config'
+ *  and 'org.apache.http.client.config'
  */
+ at Deprecated
 public interface CoreConnectionPNames {
 
     /**
diff --git a/httpcore/src/main/java/org/apache/http/params/CoreProtocolPNames.java b/httpcore/src/main/java/org/apache/http/params/CoreProtocolPNames.java
index e5a46bd..f3242f2 100644
--- a/httpcore/src/main/java/org/apache/http/params/CoreProtocolPNames.java
+++ b/httpcore/src/main/java/org/apache/http/params/CoreProtocolPNames.java
@@ -27,19 +27,21 @@
 
 package org.apache.http.params;
 
-import org.apache.http.ProtocolVersion;
-
 /**
  * Defines parameter names for protocol execution in HttpCore.
  *
  * @since 4.0
+ *
+ * @deprecated (4.3) use configuration classes provided 'org.apache.http.config'
+ *  and 'org.apache.http.client.config'
  */
+ at Deprecated
 public interface CoreProtocolPNames {
 
     /**
-     * Defines the {@link ProtocolVersion} used per default.
+     * Defines the {@link org.apache.http.ProtocolVersion} used per default.
      * <p>
-     * This parameter expects a value of type {@link ProtocolVersion}.
+     * This parameter expects a value of type {@link org.apache.http.ProtocolVersion}.
      * </p>
      */
     public static final String PROTOCOL_VERSION = "http.protocol.version";
diff --git a/httpcore/src/main/java/org/apache/http/params/HttpParamConfig.java b/httpcore/src/main/java/org/apache/http/params/HttpParamConfig.java
new file mode 100644
index 0000000..ef0ccf0
--- /dev/null
+++ b/httpcore/src/main/java/org/apache/http/params/HttpParamConfig.java
@@ -0,0 +1,78 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+
+package org.apache.http.params;
+
+import java.nio.charset.Charset;
+import java.nio.charset.CodingErrorAction;
+
+import org.apache.http.config.ConnectionConfig;
+import org.apache.http.config.MessageConstraints;
+import org.apache.http.config.SocketConfig;
+
+/**
+ * @deprecated (4.3) provided for compatibility with {@link HttpParams}. Do not use.
+ *
+ * @since 4.3
+ */
+ at Deprecated
+public final class HttpParamConfig {
+
+    private HttpParamConfig() {
+    }
+
+    public static SocketConfig getSocketConfig(final HttpParams params) {
+        return SocketConfig.custom()
+                .setSoTimeout(params.getIntParameter(CoreConnectionPNames.SO_TIMEOUT, 0))
+                .setSoReuseAddress(params.getBooleanParameter(CoreConnectionPNames.SO_REUSEADDR, false))
+                .setSoKeepAlive(params.getBooleanParameter(CoreConnectionPNames.SO_KEEPALIVE, false))
+                .setSoLinger(params.getIntParameter(CoreConnectionPNames.SO_LINGER, -1))
+                .setTcpNoDelay(params.getBooleanParameter(CoreConnectionPNames.TCP_NODELAY, true))
+                .build();
+    }
+
+    public static MessageConstraints getMessageConstraints(final HttpParams params) {
+        return MessageConstraints.custom()
+                .setMaxHeaderCount(params.getIntParameter(CoreConnectionPNames.MAX_HEADER_COUNT, -1))
+                .setMaxLineLength(params.getIntParameter(CoreConnectionPNames.MAX_LINE_LENGTH, -1))
+                .build();
+    }
+
+    public static ConnectionConfig getConnectionConfig(final HttpParams params) {
+        final MessageConstraints messageConstraints = getMessageConstraints(params);
+        final String csname = (String) params.getParameter(CoreProtocolPNames.HTTP_ELEMENT_CHARSET);
+        return ConnectionConfig.custom()
+                .setCharset(csname != null ? Charset.forName(csname) : null)
+                .setMalformedInputAction((CodingErrorAction)
+                        params.getParameter(CoreProtocolPNames.HTTP_MALFORMED_INPUT_ACTION))
+                .setMalformedInputAction((CodingErrorAction)
+                        params.getParameter(CoreProtocolPNames.HTTP_UNMAPPABLE_INPUT_ACTION))
+                .setMessageConstraints(messageConstraints)
+                .build();
+    }
+
+}
diff --git a/httpcore/src/main/java/org/apache/http/params/HttpParams.java b/httpcore/src/main/java/org/apache/http/params/HttpParams.java
index 443f699..8c479c7 100644
--- a/httpcore/src/main/java/org/apache/http/params/HttpParams.java
+++ b/httpcore/src/main/java/org/apache/http/params/HttpParams.java
@@ -42,10 +42,12 @@ package org.apache.http.params;
  * In the simplest form one set of parameters can use content of another one
  * to obtain default values of parameters not present in the local set.
  *
- * @see DefaultedHttpParams
- *
  * @since 4.0
+ *
+ * @deprecated (4.3) use configuration classes provided 'org.apache.http.config'
+ *  and 'org.apache.http.client.config'
  */
+ at Deprecated
 public interface HttpParams {
 
     /**
@@ -73,10 +75,7 @@ public interface HttpParams {
      * Creates a copy of these parameters.
      *
      * @return  a new set of parameters holding the same values as this one
-     *
-     * @deprecated (4.1)
      */
-    @Deprecated
     HttpParams copy();
 
     /**
diff --git a/httpcore/src/main/java/org/apache/http/params/HttpParamsNames.java b/httpcore/src/main/java/org/apache/http/params/HttpParamsNames.java
index fd60612..b2721d9 100644
--- a/httpcore/src/main/java/org/apache/http/params/HttpParamsNames.java
+++ b/httpcore/src/main/java/org/apache/http/params/HttpParamsNames.java
@@ -35,7 +35,11 @@ import java.util.Set;
  * @see HttpParams
  *
  * @since 4.2
+ *
+ * @deprecated (4.3) use configuration classes provided 'org.apache.http.config'
+ *  and 'org.apache.http.client.config'
  */
+ at Deprecated
 public interface HttpParamsNames {
 
     /**
diff --git a/httpcore/src/main/java/org/apache/http/pool/AbstractConnPool.java b/httpcore/src/main/java/org/apache/http/pool/AbstractConnPool.java
index 75f835c..463331e 100644
--- a/httpcore/src/main/java/org/apache/http/pool/AbstractConnPool.java
+++ b/httpcore/src/main/java/org/apache/http/pool/AbstractConnPool.java
@@ -42,6 +42,8 @@ import java.util.concurrent.locks.ReentrantLock;
 
 import org.apache.http.annotation.ThreadSafe;
 import org.apache.http.concurrent.FutureCallback;
+import org.apache.http.util.Args;
+import org.apache.http.util.Asserts;
 
 /**
  * Abstract synchronous (blocking) pool of connections.
@@ -76,27 +78,18 @@ public abstract class AbstractConnPool<T, C, E extends PoolEntry<T, C>>
 
     public AbstractConnPool(
             final ConnFactory<T, C> connFactory,
-            int defaultMaxPerRoute,
-            int maxTotal) {
+            final int defaultMaxPerRoute,
+            final int maxTotal) {
         super();
-        if (connFactory == null) {
-            throw new IllegalArgumentException("Connection factory may not null");
-        }
-        if (defaultMaxPerRoute <= 0) {
-            throw new IllegalArgumentException("Max per route value may not be negative or zero");
-        }
-        if (maxTotal <= 0) {
-            throw new IllegalArgumentException("Max total value may not be negative or zero");
-        }
+        this.connFactory = Args.notNull(connFactory, "Connection factory");
+        this.defaultMaxPerRoute = Args.notNegative(defaultMaxPerRoute, "Max per route value");
+        this.maxTotal = Args.notNegative(maxTotal, "Max total value");
         this.lock = new ReentrantLock();
-        this.connFactory = connFactory;
         this.routeToPool = new HashMap<T, RouteSpecificPool<T, C, E>>();
         this.leased = new HashSet<E>();
         this.available = new LinkedList<E>();
         this.pending = new LinkedList<PoolEntryFuture<E>>();
         this.maxPerRoute = new HashMap<T, Integer>();
-        this.defaultMaxPerRoute = defaultMaxPerRoute;
-        this.maxTotal = maxTotal;
     }
 
     /**
@@ -104,6 +97,18 @@ public abstract class AbstractConnPool<T, C, E extends PoolEntry<T, C>>
      */
     protected abstract E createEntry(T route, C conn);
 
+    /**
+     * @since 4.3
+     */
+    protected void onLease(final E entry) {
+    }
+
+    /**
+     * @since 4.3
+     */
+    protected void onRelease(final E entry) {
+    }
+
     public boolean isShutdown() {
         return this.isShutDown;
     }
@@ -118,13 +123,13 @@ public abstract class AbstractConnPool<T, C, E extends PoolEntry<T, C>>
         this.isShutDown = true;
         this.lock.lock();
         try {
-            for (E entry: this.available) {
+            for (final E entry: this.available) {
                 entry.close();
             }
-            for (E entry: this.leased) {
+            for (final E entry: this.leased) {
                 entry.close();
             }
-            for (RouteSpecificPool<T, C, E> pool: this.routeToPool.values()) {
+            for (final RouteSpecificPool<T, C, E> pool: this.routeToPool.values()) {
                 pool.shutdown();
             }
             this.routeToPool.clear();
@@ -141,7 +146,7 @@ public abstract class AbstractConnPool<T, C, E extends PoolEntry<T, C>>
             pool = new RouteSpecificPool<T, C, E>(route) {
 
                 @Override
-                protected E createEntry(C conn) {
+                protected E createEntry(final C conn) {
                     return AbstractConnPool.this.createEntry(route, conn);
                 }
 
@@ -160,20 +165,18 @@ public abstract class AbstractConnPool<T, C, E extends PoolEntry<T, C>>
      * returned by this method in order for the lease operation to complete.
      */
     public Future<E> lease(final T route, final Object state, final FutureCallback<E> callback) {
-        if (route == null) {
-            throw new IllegalArgumentException("Route may not be null");
-        }
-        if (this.isShutDown) {
-            throw new IllegalStateException("Connection pool shut down");
-        }
+        Args.notNull(route, "Route");
+        Asserts.check(!this.isShutDown, "Connection pool shut down");
         return new PoolEntryFuture<E>(this.lock, callback) {
 
             @Override
             public E getPoolEntry(
-                    long timeout,
-                    TimeUnit tunit)
+                    final long timeout,
+                    final TimeUnit tunit)
                         throws InterruptedException, TimeoutException, IOException {
-                return getPoolEntryBlocking(route, state, timeout, tunit, this);
+                final E entry = getPoolEntryBlocking(route, state, timeout, tunit, this);
+                onLease(entry);
+                return entry;
             }
 
         };
@@ -213,12 +216,10 @@ public abstract class AbstractConnPool<T, C, E extends PoolEntry<T, C>>
 
         this.lock.lock();
         try {
-            RouteSpecificPool<T, C, E> pool = getPool(route);
+            final RouteSpecificPool<T, C, E> pool = getPool(route);
             E entry = null;
             while (entry == null) {
-                if (this.isShutDown) {
-                    throw new IllegalStateException("Connection pool shut down");
-                }
+                Asserts.check(!this.isShutDown, "Connection pool shut down");
                 for (;;) {
                     entry = pool.getFree(state);
                     if (entry == null) {
@@ -239,12 +240,12 @@ public abstract class AbstractConnPool<T, C, E extends PoolEntry<T, C>>
                 }
 
                 // New connection is needed
-                int maxPerRoute = getMax(route);
+                final int maxPerRoute = getMax(route);
                 // Shrink the pool prior to allocating a new connection
-                int excess = Math.max(0, pool.getAllocatedCount() + 1 - maxPerRoute);
+                final int excess = Math.max(0, pool.getAllocatedCount() + 1 - maxPerRoute);
                 if (excess > 0) {
                     for (int i = 0; i < excess; i++) {
-                        E lastUsed = pool.getLastUsed();
+                        final E lastUsed = pool.getLastUsed();
                         if (lastUsed == null) {
                             break;
                         }
@@ -255,19 +256,19 @@ public abstract class AbstractConnPool<T, C, E extends PoolEntry<T, C>>
                 }
 
                 if (pool.getAllocatedCount() < maxPerRoute) {
-                    int totalUsed = this.leased.size();
-                    int freeCapacity = Math.max(this.maxTotal - totalUsed, 0);
+                    final int totalUsed = this.leased.size();
+                    final int freeCapacity = Math.max(this.maxTotal - totalUsed, 0);
                     if (freeCapacity > 0) {
-                        int totalAvailable = this.available.size();
+                        final int totalAvailable = this.available.size();
                         if (totalAvailable > freeCapacity - 1) {
                             if (!this.available.isEmpty()) {
-                                E lastUsed = this.available.removeLast();
+                                final E lastUsed = this.available.removeLast();
                                 lastUsed.close();
-                                RouteSpecificPool<T, C, E> otherpool = getPool(lastUsed.getRoute());
+                                final RouteSpecificPool<T, C, E> otherpool = getPool(lastUsed.getRoute());
                                 otherpool.remove(lastUsed);
                             }
                         }
-                        C conn = this.connFactory.create(route);
+                        final C conn = this.connFactory.create(route);
                         entry = pool.add(conn);
                         this.leased.add(entry);
                         return entry;
@@ -311,14 +312,15 @@ public abstract class AbstractConnPool<T, C, E extends PoolEntry<T, C>>
         }
     }
 
-    public void release(E entry, boolean reusable) {
+    public void release(final E entry, final boolean reusable) {
         this.lock.lock();
         try {
             if (this.leased.remove(entry)) {
-                RouteSpecificPool<T, C, E> pool = getPool(entry.getRoute());
+                final RouteSpecificPool<T, C, E> pool = getPool(entry.getRoute());
                 pool.free(entry, reusable);
                 if (reusable && !this.isShutDown) {
                     this.available.addFirst(entry);
+                    onRelease(entry);
                 } else {
                     entry.close();
                 }
@@ -330,7 +332,7 @@ public abstract class AbstractConnPool<T, C, E extends PoolEntry<T, C>>
     }
 
     private int getMax(final T route) {
-        Integer v = this.maxPerRoute.get(route);
+        final Integer v = this.maxPerRoute.get(route);
         if (v != null) {
             return v.intValue();
         } else {
@@ -338,10 +340,8 @@ public abstract class AbstractConnPool<T, C, E extends PoolEntry<T, C>>
         }
     }
 
-    public void setMaxTotal(int max) {
-        if (max <= 0) {
-            throw new IllegalArgumentException("Max value may not be negative or zero");
-        }
+    public void setMaxTotal(final int max) {
+        Args.notNegative(max, "Max value");
         this.lock.lock();
         try {
             this.maxTotal = max;
@@ -359,10 +359,8 @@ public abstract class AbstractConnPool<T, C, E extends PoolEntry<T, C>>
         }
     }
 
-    public void setDefaultMaxPerRoute(int max) {
-        if (max <= 0) {
-            throw new IllegalArgumentException("Max value may not be negative or zero");
-        }
+    public void setDefaultMaxPerRoute(final int max) {
+        Args.notNegative(max, "Max per route value");
         this.lock.lock();
         try {
             this.defaultMaxPerRoute = max;
@@ -380,25 +378,19 @@ public abstract class AbstractConnPool<T, C, E extends PoolEntry<T, C>>
         }
     }
 
-    public void setMaxPerRoute(final T route, int max) {
-        if (route == null) {
-            throw new IllegalArgumentException("Route may not be null");
-        }
-        if (max <= 0) {
-            throw new IllegalArgumentException("Max value may not be negative or zero");
-        }
+    public void setMaxPerRoute(final T route, final int max) {
+        Args.notNull(route, "Route");
+        Args.notNegative(max, "Max per route value");
         this.lock.lock();
         try {
-            this.maxPerRoute.put(route, max);
+            this.maxPerRoute.put(route, Integer.valueOf(max));
         } finally {
             this.lock.unlock();
         }
     }
 
-    public int getMaxPerRoute(T route) {
-        if (route == null) {
-            throw new IllegalArgumentException("Route may not be null");
-        }
+    public int getMaxPerRoute(final T route) {
+        Args.notNull(route, "Route");
         this.lock.lock();
         try {
             return getMax(route);
@@ -421,12 +413,10 @@ public abstract class AbstractConnPool<T, C, E extends PoolEntry<T, C>>
     }
 
     public PoolStats getStats(final T route) {
-        if (route == null) {
-            throw new IllegalArgumentException("Route may not be null");
-        }
+        Args.notNull(route, "Route");
         this.lock.lock();
         try {
-            RouteSpecificPool<T, C, E> pool = getPool(route);
+            final RouteSpecificPool<T, C, E> pool = getPool(route);
             return new PoolStats(
                     pool.getLeasedCount(),
                     pool.getPendingCount(),
@@ -438,65 +428,89 @@ public abstract class AbstractConnPool<T, C, E extends PoolEntry<T, C>>
     }
 
     /**
+     * Enumerates all available connections.
+     *
+     * @since 4.3
+     */
+    protected void enumAvailable(final PoolEntryCallback<T, C> callback) {
+        this.lock.lock();
+        try {
+            enumEntries(this.available.iterator(), callback);
+        } finally {
+            this.lock.unlock();
+        }
+    }
+
+    /**
+     * Enumerates all leased connections.
+     *
+     * @since 4.3
+     */
+    protected void enumLeased(final PoolEntryCallback<T, C> callback) {
+        this.lock.lock();
+        try {
+            enumEntries(this.leased.iterator(), callback);
+        } finally {
+            this.lock.unlock();
+        }
+    }
+
+    private void enumEntries(final Iterator<E> it, final PoolEntryCallback<T, C> callback) {
+        while (it.hasNext()) {
+            final E entry = it.next();
+            callback.process(entry);
+            if (entry.isClosed()) {
+                final RouteSpecificPool<T, C, E> pool = getPool(entry.getRoute());
+                pool.remove(entry);
+                it.remove();
+            }
+        }
+    }
+
+    /**
      * Closes connections that have been idle longer than the given period
      * of time and evicts them from the pool.
      *
      * @param idletime maximum idle time.
      * @param tunit time unit.
      */
-    public void closeIdle(long idletime, final TimeUnit tunit) {
-        if (tunit == null) {
-            throw new IllegalArgumentException("Time unit must not be null.");
-        }
+    public void closeIdle(final long idletime, final TimeUnit tunit) {
+        Args.notNull(tunit, "Time unit");
         long time = tunit.toMillis(idletime);
         if (time < 0) {
             time = 0;
         }
-        long deadline = System.currentTimeMillis() - time;
-        this.lock.lock();
-        try {
-            Iterator<E> it = this.available.iterator();
-            while (it.hasNext()) {
-                E entry = it.next();
+        final long deadline = System.currentTimeMillis() - time;
+        enumAvailable(new PoolEntryCallback<T, C>() {
+
+            public void process(final PoolEntry<T, C> entry) {
                 if (entry.getUpdated() <= deadline) {
                     entry.close();
-                    RouteSpecificPool<T, C, E> pool = getPool(entry.getRoute());
-                    pool.remove(entry);
-                    it.remove();
-                    notifyPending(pool);
                 }
             }
-        } finally {
-            this.lock.unlock();
-        }
+
+        });
     }
 
     /**
      * Closes expired connections and evicts them from the pool.
      */
     public void closeExpired() {
-        long now = System.currentTimeMillis();
-        this.lock.lock();
-        try {
-            Iterator<E> it = this.available.iterator();
-            while (it.hasNext()) {
-                E entry = it.next();
+        final long now = System.currentTimeMillis();
+        enumAvailable(new PoolEntryCallback<T, C>() {
+
+            public void process(final PoolEntry<T, C> entry) {
                 if (entry.isExpired(now)) {
                     entry.close();
-                    RouteSpecificPool<T, C, E> pool = getPool(entry.getRoute());
-                    pool.remove(entry);
-                    it.remove();
-                    notifyPending(pool);
                 }
             }
-        } finally {
-            this.lock.unlock();
-        }
+
+        });
     }
 
     @Override
     public String toString() {
-        StringBuilder buffer = new StringBuilder();
+        final StringBuilder buffer = new StringBuilder();
         buffer.append("[leased: ");
         buffer.append(this.leased);
         buffer.append("][available: ");
diff --git a/httpcore/src/main/java/org/apache/http/pool/PoolEntry.java b/httpcore/src/main/java/org/apache/http/pool/PoolEntry.java
index 04f804f..e01f8b4 100644
--- a/httpcore/src/main/java/org/apache/http/pool/PoolEntry.java
+++ b/httpcore/src/main/java/org/apache/http/pool/PoolEntry.java
@@ -30,6 +30,7 @@ import java.util.concurrent.TimeUnit;
 
 import org.apache.http.annotation.GuardedBy;
 import org.apache.http.annotation.ThreadSafe;
+import org.apache.http.util.Args;
 
 /**
  * Pool entry containing a pool connection object along with its route.
@@ -77,15 +78,9 @@ public abstract class PoolEntry<T, C> {
     public PoolEntry(final String id, final T route, final C conn,
             final long timeToLive, final TimeUnit tunit) {
         super();
-        if (route == null) {
-            throw new IllegalArgumentException("Route may not be null");
-        }
-        if (conn == null) {
-            throw new IllegalArgumentException("Connection may not be null");
-        }
-        if (tunit == null) {
-            throw new IllegalArgumentException("Time unit may not be null");
-        }
+        Args.notNull(route, "Route");
+        Args.notNull(conn, "Connection");
+        Args.notNull(tunit, "Time unit");
         this.id = id;
         this.route = route;
         this.conn = conn;
@@ -146,11 +141,9 @@ public abstract class PoolEntry<T, C> {
     }
 
     public synchronized void updateExpiry(final long time, final TimeUnit tunit) {
-        if (tunit == null) {
-            throw new IllegalArgumentException("Time unit may not be null");
-        }
+        Args.notNull(tunit, "Time unit");
         this.updated = System.currentTimeMillis();
-        long newExpiry;
+        final long newExpiry;
         if (time > 0) {
             newExpiry = this.updated + tunit.toMillis(time);
         } else {
@@ -176,7 +169,7 @@ public abstract class PoolEntry<T, C> {
 
     @Override
     public String toString() {
-        StringBuilder buffer = new StringBuilder();
+        final StringBuilder buffer = new StringBuilder();
         buffer.append("[id:");
         buffer.append(this.id);
         buffer.append("][route:");
diff --git a/httpcore/src/main/java/org/apache/http/io/EofSensor.java b/httpcore/src/main/java/org/apache/http/pool/PoolEntryCallback.java
similarity index 80%
copy from httpcore/src/main/java/org/apache/http/io/EofSensor.java
copy to httpcore/src/main/java/org/apache/http/pool/PoolEntryCallback.java
index b1ec82e..07dbcb0 100644
--- a/httpcore/src/main/java/org/apache/http/io/EofSensor.java
+++ b/httpcore/src/main/java/org/apache/http/pool/PoolEntryCallback.java
@@ -24,16 +24,18 @@
  * <http://www.apache.org/>.
  *
  */
-
-package org.apache.http.io;
+package org.apache.http.pool;
 
 /**
- * EOF sensor.
+ * Pool entry callabck.
  *
- * @since 4.0
+ * @param <T> the route type that represents the opposite endpoint of a pooled
+ *   connection.
+ * @param <C> the connection type.
+ * @since 4.3
  */
-public interface EofSensor {
+public interface PoolEntryCallback<T, C> {
 
-    boolean isEof();
+    void process(PoolEntry<T, C> entry);
 
 }
diff --git a/httpcore/src/main/java/org/apache/http/pool/PoolEntryFuture.java b/httpcore/src/main/java/org/apache/http/pool/PoolEntryFuture.java
index 7fd8e3b..8979a11 100644
--- a/httpcore/src/main/java/org/apache/http/pool/PoolEntryFuture.java
+++ b/httpcore/src/main/java/org/apache/http/pool/PoolEntryFuture.java
@@ -1,20 +1,21 @@
 /*
  * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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
  *
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You 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
  *
- *      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.
+ * 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.
  * ====================================================================
  *
  * This software consists of voluntary contributions made by many
@@ -23,7 +24,6 @@
  * <http://www.apache.org/>.
  *
  */
-
 package org.apache.http.pool;
 
 import java.io.IOException;
@@ -37,6 +37,7 @@ import java.util.concurrent.locks.Lock;
 
 import org.apache.http.annotation.ThreadSafe;
 import org.apache.http.concurrent.FutureCallback;
+import org.apache.http.util.Args;
 
 @ThreadSafe
 abstract class PoolEntryFuture<T> implements Future<T> {
@@ -55,7 +56,7 @@ abstract class PoolEntryFuture<T> implements Future<T> {
         this.callback = callback;
     }
 
-    public boolean cancel(boolean mayInterruptIfRunning) {
+    public boolean cancel(final boolean mayInterruptIfRunning) {
         this.lock.lock();
         try {
             if (this.completed) {
@@ -84,14 +85,15 @@ abstract class PoolEntryFuture<T> implements Future<T> {
     public T get() throws InterruptedException, ExecutionException {
         try {
             return get(0, TimeUnit.MILLISECONDS);
-        } catch (TimeoutException ex) {
+        } catch (final TimeoutException ex) {
             throw new ExecutionException(ex);
         }
     }
 
     public T get(
-            long timeout,
+            final long timeout,
             final TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {
+        Args.notNull(unit, "Time unit");
         this.lock.lock();
         try {
             if (this.completed) {
@@ -103,7 +105,7 @@ abstract class PoolEntryFuture<T> implements Future<T> {
                 this.callback.completed(this.result);
             }
             return result;
-        } catch (IOException ex) {
+        } catch (final IOException ex) {
             this.completed = true;
             this.result = null;
             if (this.callback != null) {
@@ -124,7 +126,7 @@ abstract class PoolEntryFuture<T> implements Future<T> {
             if (this.cancelled) {
                 throw new InterruptedException("Operation interrupted");
             }
-            boolean success = false;
+            final boolean success;
             if (deadline != null) {
                 success = this.condition.awaitUntil(deadline);
             } else {
diff --git a/httpcore/src/main/java/org/apache/http/pool/PoolStats.java b/httpcore/src/main/java/org/apache/http/pool/PoolStats.java
index 69c01ec..a3260cc 100644
--- a/httpcore/src/main/java/org/apache/http/pool/PoolStats.java
+++ b/httpcore/src/main/java/org/apache/http/pool/PoolStats.java
@@ -30,9 +30,11 @@ import org.apache.http.annotation.Immutable;
 
 /**
  * Pool statistics.
+ * <p>
+ * The total number of connections in the pool is equal to {@code available} plus {@code leased}.
+ * </p>
  *
  * @since 4.2
- *
  */
 @Immutable
 public class PoolStats {
@@ -42,7 +44,7 @@ public class PoolStats {
     private final int available;
     private final int max;
 
-    public PoolStats(int leased, int pending, int free, int max) {
+    public PoolStats(final int leased, final int pending, final int free, final int max) {
         super();
         this.leased = leased;
         this.pending = pending;
@@ -50,25 +52,53 @@ public class PoolStats {
         this.max = max;
     }
 
+    /**
+     * Gets the number of persistent connections tracked by the connection manager currently being used to execute
+     * requests.
+     * <p>
+     * The total number of connections in the pool is equal to {@code available} plus {@code leased}.
+     * </p>
+     *
+     * @return the number of persistent connections.
+     */
     public int getLeased() {
         return this.leased;
     }
 
+    /**
+     * Gets the number of connection requests being blocked awaiting a free connection. This can happen only if there
+     * are more worker threads contending for fewer connections.
+     *
+     * @return the number of connection requests being blocked awaiting a free connection.
+     */
     public int getPending() {
         return this.pending;
     }
 
+    /**
+     * Gets the number idle persistent connections.
+     * <p>
+     * The total number of connections in the pool is equal to {@code available} plus {@code leased}.
+     * </p>
+     *
+     * @return number idle persistent connections.
+     */
     public int getAvailable() {
         return this.available;
     }
 
+    /**
+     * Gets the maximum number of allowed persistent connections.
+     *
+     * @return the maximum number of allowed persistent connections.
+     */
     public int getMax() {
         return this.max;
     }
 
     @Override
     public String toString() {
-        StringBuilder buffer = new StringBuilder();
+        final StringBuilder buffer = new StringBuilder();
         buffer.append("[leased: ");
         buffer.append(this.leased);
         buffer.append("; pending: ");
diff --git a/httpcore/src/main/java/org/apache/http/pool/RouteSpecificPool.java b/httpcore/src/main/java/org/apache/http/pool/RouteSpecificPool.java
index 6da282c..f560e0d 100644
--- a/httpcore/src/main/java/org/apache/http/pool/RouteSpecificPool.java
+++ b/httpcore/src/main/java/org/apache/http/pool/RouteSpecificPool.java
@@ -1,20 +1,21 @@
 /*
  * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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
  *
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You 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
  *
- *      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.
+ * 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.
  * ====================================================================
  *
  * This software consists of voluntary contributions made by many
@@ -23,7 +24,6 @@
  * <http://www.apache.org/>.
  *
  */
-
 package org.apache.http.pool;
 
 import java.util.HashSet;
@@ -32,6 +32,8 @@ import java.util.LinkedList;
 import java.util.Set;
 
 import org.apache.http.annotation.NotThreadSafe;
+import org.apache.http.util.Args;
+import org.apache.http.util.Asserts;
 
 @NotThreadSafe
 abstract class RouteSpecificPool<T, C, E extends PoolEntry<T, C>> {
@@ -74,9 +76,9 @@ abstract class RouteSpecificPool<T, C, E extends PoolEntry<T, C>> {
     public E getFree(final Object state) {
         if (!this.available.isEmpty()) {
             if (state != null) {
-                Iterator<E> it = this.available.iterator();
+                final Iterator<E> it = this.available.iterator();
                 while (it.hasNext()) {
-                    E entry = it.next();
+                    final E entry = it.next();
                     if (state.equals(entry.getState())) {
                         it.remove();
                         this.leased.add(entry);
@@ -84,9 +86,9 @@ abstract class RouteSpecificPool<T, C, E extends PoolEntry<T, C>> {
                     }
                 }
             }
-            Iterator<E> it = this.available.iterator();
+            final Iterator<E> it = this.available.iterator();
             while (it.hasNext()) {
-                E entry = it.next();
+                final E entry = it.next();
                 if (entry.getState() == null) {
                     it.remove();
                     this.leased.add(entry);
@@ -106,9 +108,7 @@ abstract class RouteSpecificPool<T, C, E extends PoolEntry<T, C>> {
     }
 
     public boolean remove(final E entry) {
-        if (entry == null) {
-            throw new IllegalArgumentException("Pool entry may not be null");
-        }
+        Args.notNull(entry, "Pool entry");
         if (!this.available.remove(entry)) {
             if (!this.leased.remove(entry)) {
                 return false;
@@ -117,22 +117,17 @@ abstract class RouteSpecificPool<T, C, E extends PoolEntry<T, C>> {
         return true;
     }
 
-    public void free(final E entry, boolean reusable) {
-        if (entry == null) {
-            throw new IllegalArgumentException("Pool entry may not be null");
-        }
-        boolean found = this.leased.remove(entry);
-        if (!found) {
-            throw new IllegalStateException("Entry " + entry +
-                    " has not been leased from this pool");
-        }
+    public void free(final E entry, final boolean reusable) {
+        Args.notNull(entry, "Pool entry");
+        final boolean found = this.leased.remove(entry);
+        Asserts.check(found, "Entry %s has not been leased from this pool", entry);
         if (reusable) {
             this.available.addFirst(entry);
         }
     }
 
     public E add(final C conn) {
-        E entry = createEntry(conn);
+        final E entry = createEntry(conn);
         this.leased.add(entry);
         return entry;
     }
@@ -149,22 +144,23 @@ abstract class RouteSpecificPool<T, C, E extends PoolEntry<T, C>> {
     }
 
     public void unqueue(final PoolEntryFuture<E> future) {
-        if (future == null)
+        if (future == null) {
             return;
+        }
 
         this.pending.remove(future);
     }
 
     public void shutdown() {
-        for (PoolEntryFuture<E> future: this.pending) {
+        for (final PoolEntryFuture<E> future: this.pending) {
             future.cancel(true);
         }
         this.pending.clear();
-        for (E entry: this.available) {
+        for (final E entry: this.available) {
             entry.close();
         }
         this.available.clear();
-        for (E entry: this.leased) {
+        for (final E entry: this.leased) {
             entry.close();
         }
         this.leased.clear();
@@ -172,7 +168,7 @@ abstract class RouteSpecificPool<T, C, E extends PoolEntry<T, C>> {
 
     @Override
     public String toString() {
-        StringBuilder buffer = new StringBuilder();
+        final StringBuilder buffer = new StringBuilder();
         buffer.append("[route: ");
         buffer.append(this.route);
         buffer.append("][leased: ");
diff --git a/httpcore/src/main/java/org/apache/http/protocol/BasicHttpContext.java b/httpcore/src/main/java/org/apache/http/protocol/BasicHttpContext.java
index 18c7f8d..28b9073 100644
--- a/httpcore/src/main/java/org/apache/http/protocol/BasicHttpContext.java
+++ b/httpcore/src/main/java/org/apache/http/protocol/BasicHttpContext.java
@@ -31,6 +31,7 @@ import java.util.HashMap;
 import java.util.Map;
 
 import org.apache.http.annotation.NotThreadSafe;
+import org.apache.http.util.Args;
 
 /**
  * Default implementation of {@link HttpContext}.
@@ -56,9 +57,7 @@ public class BasicHttpContext implements HttpContext {
     }
 
     public Object getAttribute(final String id) {
-        if (id == null) {
-            throw new IllegalArgumentException("Id may not be null");
-        }
+        Args.notNull(id, "Id");
         Object obj = null;
         if (this.map != null) {
             obj = this.map.get(id);
@@ -70,9 +69,7 @@ public class BasicHttpContext implements HttpContext {
     }
 
     public void setAttribute(final String id, final Object obj) {
-        if (id == null) {
-            throw new IllegalArgumentException("Id may not be null");
-        }
+        Args.notNull(id, "Id");
         if (this.map == null) {
             this.map = new HashMap<String, Object>();
         }
@@ -80,9 +77,7 @@ public class BasicHttpContext implements HttpContext {
     }
 
     public Object removeAttribute(final String id) {
-        if (id == null) {
-            throw new IllegalArgumentException("Id may not be null");
-        }
+        Args.notNull(id, "Id");
         if (this.map != null) {
             return this.map.remove(id);
         } else {
diff --git a/httpcore/src/main/java/org/apache/http/protocol/ChainBuilder.java b/httpcore/src/main/java/org/apache/http/protocol/ChainBuilder.java
new file mode 100644
index 0000000..c1ca4dd
--- /dev/null
+++ b/httpcore/src/main/java/org/apache/http/protocol/ChainBuilder.java
@@ -0,0 +1,126 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+
+package org.apache.http.protocol;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.Map;
+
+import org.apache.http.annotation.NotThreadSafe;
+
+/**
+ * Builder class to build a linked list (chain) of unique class instances. Each class can have
+ * only one instance in the list. Useful for building lists of protocol interceptors.
+ *
+ * @see ImmutableHttpProcessor
+ *
+ * @since 4.3
+ */
+ at NotThreadSafe
+final class ChainBuilder<E> {
+
+    private final LinkedList<E> list;
+    private final Map<Class<?>, E> uniqueClasses;
+
+    public ChainBuilder() {
+        this.list = new LinkedList<E>();
+        this.uniqueClasses = new HashMap<Class<?>, E>();
+    }
+
+    private void ensureUnique(final E e) {
+        final E previous = this.uniqueClasses.remove(e.getClass());
+        if (previous != null) {
+            this.list.remove(previous);
+        }
+        this.uniqueClasses.put(e.getClass(), e);
+    }
+
+    public ChainBuilder<E> addFirst(final E e) {
+        if (e == null) {
+            return this;
+        }
+        ensureUnique(e);
+        this.list.addFirst(e);
+        return this;
+    }
+
+    public ChainBuilder<E> addLast(final E e) {
+        if (e == null) {
+            return this;
+        }
+        ensureUnique(e);
+        this.list.addLast(e);
+        return this;
+    }
+
+    public ChainBuilder<E> addAllFirst(final Collection<E> c) {
+        if (c == null) {
+            return this;
+        }
+        for (final E e: c) {
+            addFirst(e);
+        }
+        return this;
+    }
+
+    public ChainBuilder<E> addAllFirst(final E... c) {
+        if (c == null) {
+            return this;
+        }
+        for (final E e: c) {
+            addFirst(e);
+        }
+        return this;
+    }
+
+    public ChainBuilder<E> addAllLast(final Collection<E> c) {
+        if (c == null) {
+            return this;
+        }
+        for (final E e: c) {
+            addLast(e);
+        }
+        return this;
+    }
+
+    public ChainBuilder<E> addAllLast(final E... c) {
+        if (c == null) {
+            return this;
+        }
+        for (final E e: c) {
+            addLast(e);
+        }
+        return this;
+    }
+
+    public LinkedList<E> build() {
+        return new LinkedList<E>(this.list);
+    }
+
+}
diff --git a/httpcore/src/main/java/org/apache/http/protocol/HTTP.java b/httpcore/src/main/java/org/apache/http/protocol/HTTP.java
index 44c3608..cd7c7fb 100644
--- a/httpcore/src/main/java/org/apache/http/protocol/HTTP.java
+++ b/httpcore/src/main/java/org/apache/http/protocol/HTTP.java
@@ -68,7 +68,7 @@ public final class HTTP {
 
     public static final Charset DEF_CONTENT_CHARSET = Consts.ISO_8859_1;
     public static final Charset DEF_PROTOCOL_CHARSET = Consts.ASCII;
-    
+
     /**
      * @deprecated (4.2)
      */
@@ -125,7 +125,7 @@ public final class HTTP {
     @Deprecated
     public final static String DEFAULT_CONTENT_TYPE = OCTET_STREAM_TYPE;
 
-    public static boolean isWhitespace(char ch) {
+    public static boolean isWhitespace(final char ch) {
         return ch == SP || ch == HT || ch == CR || ch == LF;
     }
 
diff --git a/httpcore/src/main/java/org/apache/http/protocol/HttpContext.java b/httpcore/src/main/java/org/apache/http/protocol/HttpContext.java
index 0e57283..ddf030b 100644
--- a/httpcore/src/main/java/org/apache/http/protocol/HttpContext.java
+++ b/httpcore/src/main/java/org/apache/http/protocol/HttpContext.java
@@ -27,18 +27,19 @@
 
 package org.apache.http.protocol;
 
-import java.util.HashMap;
-
 /**
  * HttpContext represents execution state of an HTTP process. It is a structure
- * that can be used to map an attribute name to an attribute value. Internally
- * HTTP context implementations are usually backed by a {@link HashMap}.
- * <p>
+ * that can be used to map an attribute name to an attribute value.
+ * <p/>
  * The primary purpose of the HTTP context is to facilitate information sharing
  * among various  logically related components. HTTP context can be used
  * to store a processing state for one message or several consecutive messages.
  * Multiple logically related messages can participate in a logical session
  * if the same context is reused between consecutive messages.
+ * <p>/
+ * IMPORTANT: Please note HTTP context implementation, even when thread safe,
+ * may not be used concurrently by multiple threads, as the context may contain
+ * thread unsafe attributes.
  *
  * @since 4.0
  */
diff --git a/httpcore/src/main/java/org/apache/http/protocol/HttpCoreContext.java b/httpcore/src/main/java/org/apache/http/protocol/HttpCoreContext.java
new file mode 100644
index 0000000..c65951c
--- /dev/null
+++ b/httpcore/src/main/java/org/apache/http/protocol/HttpCoreContext.java
@@ -0,0 +1,152 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+
+package org.apache.http.protocol;
+
+import org.apache.http.HttpConnection;
+import org.apache.http.HttpHost;
+import org.apache.http.HttpRequest;
+import org.apache.http.HttpResponse;
+import org.apache.http.annotation.NotThreadSafe;
+import org.apache.http.util.Args;
+
+/**
+ * Implementation of {@link HttpContext} that provides convenience
+ * setters for user assignable attributes and getter for readable attributes.
+ *
+ * @since 4.3
+ */
+ at NotThreadSafe
+public class HttpCoreContext implements HttpContext {
+
+    /**
+     * Attribute name of a {@link org.apache.http.HttpConnection} object that
+     * represents the actual HTTP connection.
+     */
+    public static final String HTTP_CONNECTION  = "http.connection";
+
+    /**
+     * Attribute name of a {@link org.apache.http.HttpRequest} object that
+     * represents the actual HTTP request.
+     */
+    public static final String HTTP_REQUEST     = "http.request";
+
+    /**
+     * Attribute name of a {@link org.apache.http.HttpResponse} object that
+     * represents the actual HTTP response.
+     */
+    public static final String HTTP_RESPONSE    = "http.response";
+
+    /**
+     * Attribute name of a {@link org.apache.http.HttpHost} object that
+     * represents the connection target.
+     */
+    public static final String HTTP_TARGET_HOST = "http.target_host";
+
+    /**
+     * Attribute name of a {@link Boolean} object that represents the
+     * the flag indicating whether the actual request has been fully transmitted
+     * to the target host.
+     */
+    public static final String HTTP_REQ_SENT    = "http.request_sent";
+
+    public static HttpCoreContext create() {
+        return new HttpCoreContext(new BasicHttpContext());
+    }
+
+    public static HttpCoreContext adapt(final HttpContext context) {
+        Args.notNull(context, "HTTP context");
+        if (context instanceof HttpCoreContext) {
+            return (HttpCoreContext) context;
+        } else {
+            return new HttpCoreContext(context);
+        }
+    }
+
+    private final HttpContext context;
+
+    public HttpCoreContext(final HttpContext context) {
+        super();
+        this.context = context;
+    }
+
+    public HttpCoreContext() {
+        super();
+        this.context = new BasicHttpContext();
+    }
+
+    public Object getAttribute(final String id) {
+        return context.getAttribute(id);
+    }
+
+    public void setAttribute(final String id, final Object obj) {
+        context.setAttribute(id, obj);
+    }
+
+    public Object removeAttribute(final String id) {
+        return context.removeAttribute(id);
+    }
+
+    public <T> T getAttribute(final String attribname, final Class<T> clazz) {
+        Args.notNull(clazz, "Attribute class");
+        final Object obj = getAttribute(attribname);
+        if (obj == null) {
+            return null;
+        }
+        return clazz.cast(obj);
+    }
+
+    public <T extends HttpConnection> T getConnection(final Class<T> clazz) {
+        return getAttribute(HTTP_CONNECTION, clazz);
+    }
+
+    public HttpConnection getConnection() {
+        return getAttribute(HTTP_CONNECTION, HttpConnection.class);
+    }
+
+    public HttpRequest getRequest() {
+        return getAttribute(HTTP_REQUEST, HttpRequest.class);
+    }
+
+    public boolean isRequestSent() {
+        final Boolean b = getAttribute(HTTP_REQ_SENT, Boolean.class);
+        return b != null && b.booleanValue();
+    }
+
+    public HttpResponse getResponse() {
+        return getAttribute(HTTP_RESPONSE, HttpResponse.class);
+    }
+
+    public void setTargetHost(final HttpHost host) {
+        setAttribute(HTTP_TARGET_HOST, host);
+    }
+
+    public HttpHost getTargetHost() {
+        return getAttribute(HTTP_TARGET_HOST, HttpHost.class);
+    }
+
+}
diff --git a/httpcore/src/main/java/org/apache/http/protocol/HttpDateGenerator.java b/httpcore/src/main/java/org/apache/http/protocol/HttpDateGenerator.java
index 00bf71d..d5fdaca 100644
--- a/httpcore/src/main/java/org/apache/http/protocol/HttpDateGenerator.java
+++ b/httpcore/src/main/java/org/apache/http/protocol/HttpDateGenerator.java
@@ -65,7 +65,7 @@ public class HttpDateGenerator {
     }
 
     public synchronized String getCurrentDate() {
-        long now = System.currentTimeMillis();
+        final long now = System.currentTimeMillis();
         if (now - this.dateAsLong > 1000) {
             // Generate new date string
             this.dateAsText = this.dateformat.format(new Date(now));
diff --git a/httpcore/src/main/java/org/apache/http/protocol/HttpProcessorBuilder.java b/httpcore/src/main/java/org/apache/http/protocol/HttpProcessorBuilder.java
new file mode 100644
index 0000000..5e5627d
--- /dev/null
+++ b/httpcore/src/main/java/org/apache/http/protocol/HttpProcessorBuilder.java
@@ -0,0 +1,151 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+
+package org.apache.http.protocol;
+
+import org.apache.http.HttpRequestInterceptor;
+import org.apache.http.HttpResponseInterceptor;
+
+/**
+ * Builder for {@link HttpProcessor} instances.
+ *
+ * @since 4.3
+ */
+public class HttpProcessorBuilder {
+
+    private ChainBuilder<HttpRequestInterceptor> requestChainBuilder;
+    private ChainBuilder<HttpResponseInterceptor> responseChainBuilder;
+
+    public static HttpProcessorBuilder create() {
+        return new HttpProcessorBuilder();
+    }
+
+    HttpProcessorBuilder() {
+        super();
+    }
+
+    private ChainBuilder<HttpRequestInterceptor> getRequestChainBuilder() {
+        if (requestChainBuilder == null) {
+            requestChainBuilder = new ChainBuilder<HttpRequestInterceptor>();
+        }
+        return requestChainBuilder;
+    }
+
+    private ChainBuilder<HttpResponseInterceptor> getResponseChainBuilder() {
+        if (responseChainBuilder == null) {
+            responseChainBuilder = new ChainBuilder<HttpResponseInterceptor>();
+        }
+        return responseChainBuilder;
+    }
+
+    public HttpProcessorBuilder addFirst(final HttpRequestInterceptor e) {
+        if (e == null) {
+            return this;
+        }
+        getRequestChainBuilder().addFirst(e);
+        return this;
+    }
+
+    public HttpProcessorBuilder addLast(final HttpRequestInterceptor e) {
+        if (e == null) {
+            return this;
+        }
+        getRequestChainBuilder().addLast(e);
+        return this;
+    }
+
+    public HttpProcessorBuilder add(final HttpRequestInterceptor e) {
+        return addLast(e);
+    }
+
+    public HttpProcessorBuilder addAllFirst(final HttpRequestInterceptor... e) {
+        if (e == null) {
+            return this;
+        }
+        getRequestChainBuilder().addAllFirst(e);
+        return this;
+    }
+
+    public HttpProcessorBuilder addAllLast(final HttpRequestInterceptor... e) {
+        if (e == null) {
+            return this;
+        }
+        getRequestChainBuilder().addAllLast(e);
+        return this;
+    }
+
+    public HttpProcessorBuilder addAll(final HttpRequestInterceptor... e) {
+        return addAllLast(e);
+    }
+
+    public HttpProcessorBuilder addFirst(final HttpResponseInterceptor e) {
+        if (e == null) {
+            return this;
+        }
+        getResponseChainBuilder().addFirst(e);
+        return this;
+    }
+
+    public HttpProcessorBuilder addLast(final HttpResponseInterceptor e) {
+        if (e == null) {
+            return this;
+        }
+        getResponseChainBuilder().addLast(e);
+        return this;
+    }
+
+    public HttpProcessorBuilder add(final HttpResponseInterceptor e) {
+        return addLast(e);
+    }
+
+    public HttpProcessorBuilder addAllFirst(final HttpResponseInterceptor... e) {
+        if (e == null) {
+            return this;
+        }
+        getResponseChainBuilder().addAllFirst(e);
+        return this;
+    }
+
+    public HttpProcessorBuilder addAllLast(final HttpResponseInterceptor... e) {
+        if (e == null) {
+            return this;
+        }
+        getResponseChainBuilder().addAllLast(e);
+        return this;
+    }
+
+    public HttpProcessorBuilder addAll(final HttpResponseInterceptor... e) {
+        return addAllLast(e);
+    }
+
+    public HttpProcessor build() {
+        return new ImmutableHttpProcessor(
+                requestChainBuilder != null ? requestChainBuilder.build() : null,
+                responseChainBuilder != null ? responseChainBuilder.build() : null);
+    }
+
+}
diff --git a/httpcore/src/main/java/org/apache/http/protocol/HttpRequestExecutor.java b/httpcore/src/main/java/org/apache/http/protocol/HttpRequestExecutor.java
index 532e357..73a6e4c 100644
--- a/httpcore/src/main/java/org/apache/http/protocol/HttpRequestExecutor.java
+++ b/httpcore/src/main/java/org/apache/http/protocol/HttpRequestExecutor.java
@@ -30,7 +30,6 @@ package org.apache.http.protocol;
 import java.io.IOException;
 
 import org.apache.http.HttpClientConnection;
-import org.apache.http.HttpEntity;
 import org.apache.http.HttpEntityEnclosingRequest;
 import org.apache.http.HttpException;
 import org.apache.http.HttpRequest;
@@ -40,7 +39,7 @@ import org.apache.http.HttpVersion;
 import org.apache.http.ProtocolException;
 import org.apache.http.ProtocolVersion;
 import org.apache.http.annotation.Immutable;
-import org.apache.http.params.CoreProtocolPNames;
+import org.apache.http.util.Args;
 
 /**
  * <tt>HttpRequestExecutor</tt> is a client side HTTP protocol handler based
@@ -52,23 +51,28 @@ import org.apache.http.params.CoreProtocolPNames;
  * Application specific processing can be implemented outside
  * <tt>HttpRequestExecutor</tt> once the request has been executed and
  * a response has been received.
- * <p/>
- * The following parameters can be used to customize the behavior of this
- * class:
- * <ul>
- *  <li>{@link org.apache.http.params.CoreProtocolPNames#WAIT_FOR_CONTINUE}</li>
- * </ul>
  *
  * @since 4.0
  */
 @Immutable
 public class HttpRequestExecutor {
 
+    public static final int DEFAULT_WAIT_FOR_CONTINUE = 3000;
+
+    private final int waitForContinue;
+
     /**
-     * Create a new request executor.
+     * Creates new instance of HttpRequestExecutor.
+     *
+     * @since 4.3
      */
-    public HttpRequestExecutor() {
+    public HttpRequestExecutor(final int waitForContinue) {
         super();
+        this.waitForContinue = Args.positive(waitForContinue, "Wait for continue time");
+    }
+
+    public HttpRequestExecutor() {
+        this(DEFAULT_WAIT_FOR_CONTINUE);
     }
 
     /**
@@ -87,7 +91,7 @@ public class HttpRequestExecutor {
         if ("HEAD".equalsIgnoreCase(request.getRequestLine().getMethod())) {
             return false;
         }
-        int status = response.getStatusLine().getStatusCode();
+        final int status = response.getStatusLine().getStatusCode();
         return status >= HttpStatus.SC_OK
             && status != HttpStatus.SC_NO_CONTENT
             && status != HttpStatus.SC_NOT_MODIFIED
@@ -109,40 +113,32 @@ public class HttpRequestExecutor {
     public HttpResponse execute(
             final HttpRequest request,
             final HttpClientConnection conn,
-            final HttpContext context)
-                throws IOException, HttpException {
-        if (request == null) {
-            throw new IllegalArgumentException("HTTP request may not be null");
-        }
-        if (conn == null) {
-            throw new IllegalArgumentException("Client connection may not be null");
-        }
-        if (context == null) {
-            throw new IllegalArgumentException("HTTP context may not be null");
-        }
-
+            final HttpContext context) throws IOException, HttpException {
+        Args.notNull(request, "HTTP request");
+        Args.notNull(conn, "Client connection");
+        Args.notNull(context, "HTTP context");
         try {
             HttpResponse response = doSendRequest(request, conn, context);
             if (response == null) {
                 response = doReceiveResponse(request, conn, context);
             }
             return response;
-        } catch (IOException ex) {
+        } catch (final IOException ex) {
             closeConnection(conn);
             throw ex;
-        } catch (HttpException ex) {
+        } catch (final HttpException ex) {
             closeConnection(conn);
             throw ex;
-        } catch (RuntimeException ex) {
+        } catch (final RuntimeException ex) {
             closeConnection(conn);
             throw ex;
         }
     }
 
-    private final static void closeConnection(final HttpClientConnection conn) {
+    private static void closeConnection(final HttpClientConnection conn) {
         try {
             conn.close();
-        } catch (IOException ignore) {
+        } catch (final IOException ignore) {
         }
     }
 
@@ -161,18 +157,11 @@ public class HttpRequestExecutor {
     public void preProcess(
             final HttpRequest request,
             final HttpProcessor processor,
-            final HttpContext context)
-                throws HttpException, IOException {
-        if (request == null) {
-            throw new IllegalArgumentException("HTTP request may not be null");
-        }
-        if (processor == null) {
-            throw new IllegalArgumentException("HTTP processor may not be null");
-        }
-        if (context == null) {
-            throw new IllegalArgumentException("HTTP context may not be null");
-        }
-        context.setAttribute(ExecutionContext.HTTP_REQUEST, request);
+            final HttpContext context) throws HttpException, IOException {
+        Args.notNull(request, "HTTP request");
+        Args.notNull(processor, "HTTP processor");
+        Args.notNull(context, "HTTP context");
+        context.setAttribute(HttpCoreContext.HTTP_REQUEST, request);
         processor.process(request, context);
     }
 
@@ -201,22 +190,15 @@ public class HttpRequestExecutor {
     protected HttpResponse doSendRequest(
             final HttpRequest request,
             final HttpClientConnection conn,
-            final HttpContext context)
-                throws IOException, HttpException {
-        if (request == null) {
-            throw new IllegalArgumentException("HTTP request may not be null");
-        }
-        if (conn == null) {
-            throw new IllegalArgumentException("HTTP connection may not be null");
-        }
-        if (context == null) {
-            throw new IllegalArgumentException("HTTP context may not be null");
-        }
+            final HttpContext context) throws IOException, HttpException {
+        Args.notNull(request, "HTTP request");
+        Args.notNull(conn, "Client connection");
+        Args.notNull(context, "HTTP context");
 
         HttpResponse response = null;
 
-        context.setAttribute(ExecutionContext.HTTP_CONNECTION, conn);
-        context.setAttribute(ExecutionContext.HTTP_REQ_SENT, Boolean.FALSE);
+        context.setAttribute(HttpCoreContext.HTTP_CONNECTION, conn);
+        context.setAttribute(HttpCoreContext.HTTP_REQ_SENT, Boolean.FALSE);
 
         conn.sendRequestHeader(request);
         if (request instanceof HttpEntityEnclosingRequest) {
@@ -232,15 +214,12 @@ public class HttpRequestExecutor {
                 conn.flush();
                 // As suggested by RFC 2616 section 8.2.3, we don't wait for a
                 // 100-continue response forever. On timeout, send the entity.
-                int tms = request.getParams().getIntParameter(
-                        CoreProtocolPNames.WAIT_FOR_CONTINUE, 2000);
-
-                if (conn.isResponseAvailable(tms)) {
+                if (conn.isResponseAvailable(this.waitForContinue)) {
                     response = conn.receiveResponseHeader();
                     if (canResponseHaveBody(request, response)) {
                         conn.receiveResponseEntity(response);
                     }
-                    int status = response.getStatusLine().getStatusCode();
+                    final int status = response.getStatusLine().getStatusCode();
                     if (status < 200) {
                         if (status != HttpStatus.SC_CONTINUE) {
                             throw new ProtocolException(
@@ -258,7 +237,7 @@ public class HttpRequestExecutor {
             }
         }
         conn.flush();
-        context.setAttribute(ExecutionContext.HTTP_REQ_SENT, Boolean.TRUE);
+        context.setAttribute(HttpCoreContext.HTTP_REQ_SENT, Boolean.TRUE);
         return response;
     }
 
@@ -278,35 +257,26 @@ public class HttpRequestExecutor {
      *   problem.
      */
     protected HttpResponse doReceiveResponse(
-            final HttpRequest          request,
+            final HttpRequest request,
             final HttpClientConnection conn,
-            final HttpContext          context)
-                throws HttpException, IOException {
-        if (request == null) {
-            throw new IllegalArgumentException("HTTP request may not be null");
-        }
-        if (conn == null) {
-            throw new IllegalArgumentException("HTTP connection may not be null");
-        }
-        if (context == null) {
-            throw new IllegalArgumentException("HTTP context may not be null");
-        }
-
+            final HttpContext context) throws HttpException, IOException {
+        Args.notNull(request, "HTTP request");
+        Args.notNull(conn, "Client connection");
+        Args.notNull(context, "HTTP context");
         HttpResponse response = null;
-        int statuscode = 0;
+        int statusCode = 0;
 
-        while (response == null || statuscode < HttpStatus.SC_OK) {
+        while (response == null || statusCode < HttpStatus.SC_OK) {
 
             response = conn.receiveResponseHeader();
             if (canResponseHaveBody(request, response)) {
                 conn.receiveResponseEntity(response);
             }
-            statuscode = response.getStatusLine().getStatusCode();
+            statusCode = response.getStatusLine().getStatusCode();
 
         } // while intermediate response
 
         return response;
-
     }
 
     /**
@@ -316,7 +286,7 @@ public class HttpRequestExecutor {
      * This method does <i>not</i> read the response entity, if any.
      * The connection over which content of the response entity is being
      * streamed from cannot be reused until
-     * {@link org.apache.http.util.EntityUtils#consume(HttpEntity)}
+     * {@link org.apache.http.util.EntityUtils#consume(org.apache.http.HttpEntity)}
      * has been invoked.
      *
      * @param response  the response object to post-process
@@ -330,18 +300,11 @@ public class HttpRequestExecutor {
     public void postProcess(
             final HttpResponse response,
             final HttpProcessor processor,
-            final HttpContext context)
-                throws HttpException, IOException {
-        if (response == null) {
-            throw new IllegalArgumentException("HTTP response may not be null");
-        }
-        if (processor == null) {
-            throw new IllegalArgumentException("HTTP processor may not be null");
-        }
-        if (context == null) {
-            throw new IllegalArgumentException("HTTP context may not be null");
-        }
-        context.setAttribute(ExecutionContext.HTTP_RESPONSE, response);
+            final HttpContext context) throws HttpException, IOException {
+        Args.notNull(response, "HTTP response");
+        Args.notNull(processor, "HTTP processor");
+        Args.notNull(context, "HTTP context");
+        context.setAttribute(HttpCoreContext.HTTP_RESPONSE, response);
         processor.process(response, context);
     }
 
diff --git a/httpcore/src/main/java/org/apache/http/protocol/HttpRequestHandlerResolver.java b/httpcore/src/main/java/org/apache/http/protocol/HttpRequestHandlerMapper.java
similarity index 74%
copy from httpcore/src/main/java/org/apache/http/protocol/HttpRequestHandlerResolver.java
copy to httpcore/src/main/java/org/apache/http/protocol/HttpRequestHandlerMapper.java
index 31a70a5..2cd5f10 100644
--- a/httpcore/src/main/java/org/apache/http/protocol/HttpRequestHandlerResolver.java
+++ b/httpcore/src/main/java/org/apache/http/protocol/HttpRequestHandlerMapper.java
@@ -27,23 +27,24 @@
 
 package org.apache.http.protocol;
 
+import org.apache.http.HttpRequest;
+
 /**
- * HttpRequestHandlerResolver can be used to resolve an instance of
- * {@link HttpRequestHandler} matching a particular request URI. Usually the
- * resolved request handler will be used to process the request with the
- * specified request URI.
+ * HttpRequestHandlerMapper can be used to resolve an instance of
+ * {@link HttpRequestHandler} matching a particular {@link HttpRequest}. Usually the
+ * mapped request handler will be used to process the request.
  *
- * @since 4.0
+ * @since 4.3
  */
-public interface HttpRequestHandlerResolver {
+public interface HttpRequestHandlerMapper {
 
     /**
-     * Looks up a handler matching the given request URI.
+     * Looks up a handler matching the given request.
      *
-     * @param requestURI the request URI
+     * @param request the request to map to a handler
      * @return HTTP request handler or <code>null</code> if no match
      * is found.
      */
-    HttpRequestHandler lookup(String requestURI);
+    HttpRequestHandler lookup(HttpRequest request);
 
 }
diff --git a/httpcore/src/main/java/org/apache/http/protocol/HttpRequestHandlerResolver.java b/httpcore/src/main/java/org/apache/http/protocol/HttpRequestHandlerResolver.java
index 31a70a5..556e6b0 100644
--- a/httpcore/src/main/java/org/apache/http/protocol/HttpRequestHandlerResolver.java
+++ b/httpcore/src/main/java/org/apache/http/protocol/HttpRequestHandlerResolver.java
@@ -30,11 +30,13 @@ package org.apache.http.protocol;
 /**
  * HttpRequestHandlerResolver can be used to resolve an instance of
  * {@link HttpRequestHandler} matching a particular request URI. Usually the
- * resolved request handler will be used to process the request with the
+ * mapped request handler will be used to process the request with the
  * specified request URI.
  *
  * @since 4.0
+ * @deprecated see {@link HttpRequestHandlerMapper}
  */
+ at Deprecated
 public interface HttpRequestHandlerResolver {
 
     /**
diff --git a/httpcore/src/main/java/org/apache/http/protocol/HttpRequestInterceptorList.java b/httpcore/src/main/java/org/apache/http/protocol/HttpRequestInterceptorList.java
index 9dcb41b..f988396 100644
--- a/httpcore/src/main/java/org/apache/http/protocol/HttpRequestInterceptorList.java
+++ b/httpcore/src/main/java/org/apache/http/protocol/HttpRequestInterceptorList.java
@@ -37,7 +37,10 @@ import org.apache.http.HttpRequestInterceptor;
  * for {@link HttpProcessor processing}.
  *
  * @since 4.0
+ *
+ * @deprecated (4.3)
  */
+ at Deprecated
 public interface HttpRequestInterceptorList {
 
     /**
diff --git a/httpcore/src/main/java/org/apache/http/protocol/HttpResponseInterceptorList.java b/httpcore/src/main/java/org/apache/http/protocol/HttpResponseInterceptorList.java
index eeed61c..3249c0a 100644
--- a/httpcore/src/main/java/org/apache/http/protocol/HttpResponseInterceptorList.java
+++ b/httpcore/src/main/java/org/apache/http/protocol/HttpResponseInterceptorList.java
@@ -37,7 +37,10 @@ import org.apache.http.HttpResponseInterceptor;
  * for {@link HttpProcessor processing}.
  *
  * @since 4.0
+ *
+ * @deprecated (4.3)
  */
+ at Deprecated
 public interface HttpResponseInterceptorList {
 
     /**
diff --git a/httpcore/src/main/java/org/apache/http/protocol/HttpService.java b/httpcore/src/main/java/org/apache/http/protocol/HttpService.java
index 1d9cf7d..994f7c0 100644
--- a/httpcore/src/main/java/org/apache/http/protocol/HttpService.java
+++ b/httpcore/src/main/java/org/apache/http/protocol/HttpService.java
@@ -44,8 +44,10 @@ import org.apache.http.ProtocolException;
 import org.apache.http.UnsupportedHttpVersionException;
 import org.apache.http.annotation.Immutable;
 import org.apache.http.entity.ByteArrayEntity;
+import org.apache.http.impl.DefaultConnectionReuseStrategy;
+import org.apache.http.impl.DefaultHttpResponseFactory;
 import org.apache.http.params.HttpParams;
-import org.apache.http.params.DefaultedHttpParams;
+import org.apache.http.util.Args;
 import org.apache.http.util.EncodingUtils;
 import org.apache.http.util.EntityUtils;
 
@@ -59,7 +61,7 @@ import org.apache.http.util.EntityUtils;
  * individual {@link HttpRequestHandler}s are expected to implement
  * application specific content generation and processing.
  * <p/>
- * <tt>HttpService</tt> uses {@link HttpRequestHandlerResolver} to resolve
+ * <tt>HttpService</tt> uses {@link HttpRequestHandlerMapper} to map
  * matching request handler for a particular request URI of an incoming HTTP
  * request.
  * <p/>
@@ -68,6 +70,7 @@ import org.apache.http.util.EntityUtils;
  *
  * @since 4.0
  */
+ at SuppressWarnings("deprecation")
 @Immutable // provided injected dependencies are immutable and deprecated methods are not used
 public class HttpService {
 
@@ -76,7 +79,7 @@ public class HttpService {
      */
     private volatile HttpParams params = null;
     private volatile HttpProcessor processor = null;
-    private volatile HttpRequestHandlerResolver handlerResolver = null;
+    private volatile HttpRequestHandlerMapper handlerMapper = null;
     private volatile ConnectionReuseStrategy connStrategy = null;
     private volatile HttpResponseFactory responseFactory = null;
     private volatile HttpExpectationVerifier expectationVerifier = null;
@@ -92,7 +95,10 @@ public class HttpService {
      * @param params               the HTTP parameters
      *
      * @since 4.1
+     * @deprecated (4.3) use {@link HttpService#HttpService(HttpProcessor, ConnectionReuseStrategy,
+     *   HttpResponseFactory, HttpRequestHandlerMapper, HttpExpectationVerifier)}
      */
+    @Deprecated
     public HttpService(
             final HttpProcessor processor,
             final ConnectionReuseStrategy connStrategy,
@@ -100,24 +106,11 @@ public class HttpService {
             final HttpRequestHandlerResolver handlerResolver,
             final HttpExpectationVerifier expectationVerifier,
             final HttpParams params) {
-        super();
-        if (processor == null) {
-            throw new IllegalArgumentException("HTTP processor may not be null");
-        }
-        if (connStrategy == null) {
-            throw new IllegalArgumentException("Connection reuse strategy may not be null");
-        }
-        if (responseFactory == null) {
-            throw new IllegalArgumentException("Response factory may not be null");
-        }
-        if (params == null) {
-            throw new IllegalArgumentException("HTTP parameters may not be null");
-        }
-        this.processor = processor;
-        this.connStrategy = connStrategy;
-        this.responseFactory = responseFactory;
-        this.handlerResolver = handlerResolver;
-        this.expectationVerifier = expectationVerifier;
+        this(processor,
+             connStrategy,
+             responseFactory,
+             new HttpRequestHandlerResolverAdapter(handlerResolver),
+             expectationVerifier);
         this.params = params;
     }
 
@@ -131,14 +124,22 @@ public class HttpService {
      * @param params               the HTTP parameters
      *
      * @since 4.1
+     * @deprecated (4.3) use {@link HttpService#HttpService(HttpProcessor, ConnectionReuseStrategy,
+     *   HttpResponseFactory, HttpRequestHandlerMapper)}
      */
+    @Deprecated
     public HttpService(
             final HttpProcessor processor,
             final ConnectionReuseStrategy connStrategy,
             final HttpResponseFactory responseFactory,
             final HttpRequestHandlerResolver handlerResolver,
             final HttpParams params) {
-        this(processor, connStrategy, responseFactory, handlerResolver, null, params);
+        this(processor,
+             connStrategy,
+             responseFactory,
+             new HttpRequestHandlerResolverAdapter(handlerResolver),
+             null);
+        this.params = params;
     }
 
     /**
@@ -163,13 +164,73 @@ public class HttpService {
     }
 
     /**
+     * Create a new HTTP service.
+     *
+     * @param processor the processor to use on requests and responses
+     * @param connStrategy the connection reuse strategy. If <code>null</code>
+     *   {@link DefaultConnectionReuseStrategy#INSTANCE} will be used.
+     * @param responseFactory  the response factory. If <code>null</code>
+     *   {@link DefaultHttpResponseFactory#INSTANCE} will be used.
+     * @param handlerMapper  the handler mapper. May be null.
+     * @param expectationVerifier the expectation verifier. May be null.
+     *
+     * @since 4.3
+     */
+    public HttpService(
+            final HttpProcessor processor,
+            final ConnectionReuseStrategy connStrategy,
+            final HttpResponseFactory responseFactory,
+            final HttpRequestHandlerMapper handlerMapper,
+            final HttpExpectationVerifier expectationVerifier) {
+        super();
+        this.processor =  Args.notNull(processor, "HTTP processor");
+        this.connStrategy = connStrategy != null ? connStrategy :
+            DefaultConnectionReuseStrategy.INSTANCE;
+        this.responseFactory = responseFactory != null ? responseFactory :
+            DefaultHttpResponseFactory.INSTANCE;
+        this.handlerMapper = handlerMapper;
+        this.expectationVerifier = expectationVerifier;
+    }
+
+    /**
+     * Create a new HTTP service.
+     *
+     * @param processor the processor to use on requests and responses
+     * @param connStrategy the connection reuse strategy. If <code>null</code>
+     *   {@link DefaultConnectionReuseStrategy#INSTANCE} will be used.
+     * @param responseFactory  the response factory. If <code>null</code>
+     *   {@link DefaultHttpResponseFactory#INSTANCE} will be used.
+     * @param handlerMapper  the handler mapper. May be null.
+     *
+     * @since 4.3
+     */
+    public HttpService(
+            final HttpProcessor processor,
+            final ConnectionReuseStrategy connStrategy,
+            final HttpResponseFactory responseFactory,
+            final HttpRequestHandlerMapper handlerMapper) {
+        this(processor, connStrategy, responseFactory, handlerMapper, null);
+    }
+
+    /**
+     * Create a new HTTP service.
+     *
+     * @param processor the processor to use on requests and responses
+     * @param handlerMapper  the handler mapper. May be null.
+     *
+     * @since 4.3
+     */
+    public HttpService(
+            final HttpProcessor processor, final HttpRequestHandlerMapper handlerMapper) {
+        this(processor, null, null, handlerMapper, null);
+    }
+
+    /**
      * @deprecated (4.1) set {@link HttpProcessor} using constructor
      */
     @Deprecated
     public void setHttpProcessor(final HttpProcessor processor) {
-        if (processor == null) {
-            throw new IllegalArgumentException("HTTP processor may not be null");
-        }
+        Args.notNull(processor, "HTTP processor");
         this.processor = processor;
     }
 
@@ -178,9 +239,7 @@ public class HttpService {
      */
     @Deprecated
     public void setConnReuseStrategy(final ConnectionReuseStrategy connStrategy) {
-        if (connStrategy == null) {
-            throw new IllegalArgumentException("Connection reuse strategy may not be null");
-        }
+        Args.notNull(connStrategy, "Connection reuse strategy");
         this.connStrategy = connStrategy;
     }
 
@@ -189,9 +248,7 @@ public class HttpService {
      */
     @Deprecated
     public void setResponseFactory(final HttpResponseFactory responseFactory) {
-        if (responseFactory == null) {
-            throw new IllegalArgumentException("Response factory may not be null");
-        }
+        Args.notNull(responseFactory, "Response factory");
         this.responseFactory = responseFactory;
     }
 
@@ -208,7 +265,7 @@ public class HttpService {
      */
     @Deprecated
     public void setHandlerResolver(final HttpRequestHandlerResolver handlerResolver) {
-        this.handlerResolver = handlerResolver;
+        this.handlerMapper = new HttpRequestHandlerResolverAdapter(handlerResolver);
     }
 
     /**
@@ -219,6 +276,10 @@ public class HttpService {
         this.expectationVerifier = expectationVerifier;
     }
 
+    /**
+     * @deprecated (4.3) no longer used.
+     */
+    @Deprecated
     public HttpParams getParams() {
         return this.params;
     }
@@ -237,32 +298,24 @@ public class HttpService {
             final HttpServerConnection conn,
             final HttpContext context) throws IOException, HttpException {
 
-        context.setAttribute(ExecutionContext.HTTP_CONNECTION, conn);
+        context.setAttribute(HttpCoreContext.HTTP_CONNECTION, conn);
 
         HttpResponse response = null;
 
         try {
 
-            HttpRequest request = conn.receiveRequestHeader();
-            request.setParams(
-                    new DefaultedHttpParams(request.getParams(), this.params));
-
+            final HttpRequest request = conn.receiveRequestHeader();
             if (request instanceof HttpEntityEnclosingRequest) {
 
                 if (((HttpEntityEnclosingRequest) request).expectContinue()) {
                     response = this.responseFactory.newHttpResponse(HttpVersion.HTTP_1_1,
                             HttpStatus.SC_CONTINUE, context);
-                    response.setParams(
-                            new DefaultedHttpParams(response.getParams(), this.params));
-
                     if (this.expectationVerifier != null) {
                         try {
                             this.expectationVerifier.verify(request, response, context);
-                        } catch (HttpException ex) {
+                        } catch (final HttpException ex) {
                             response = this.responseFactory.newHttpResponse(HttpVersion.HTTP_1_0,
                                     HttpStatus.SC_INTERNAL_SERVER_ERROR, context);
-                            response.setParams(
-                                    new DefaultedHttpParams(response.getParams(), this.params));
                             handleException(ex, response);
                         }
                     }
@@ -279,33 +332,29 @@ public class HttpService {
                 }
             }
 
-            context.setAttribute(ExecutionContext.HTTP_REQUEST, request);
+            context.setAttribute(HttpCoreContext.HTTP_REQUEST, request);
 
             if (response == null) {
                 response = this.responseFactory.newHttpResponse(HttpVersion.HTTP_1_1,
                         HttpStatus.SC_OK, context);
-                response.setParams(
-                        new DefaultedHttpParams(response.getParams(), this.params));
                 this.processor.process(request, context);
                 doService(request, response, context);
             }
 
             // Make sure the request content is fully consumed
             if (request instanceof HttpEntityEnclosingRequest) {
-                HttpEntity entity = ((HttpEntityEnclosingRequest)request).getEntity();
+                final HttpEntity entity = ((HttpEntityEnclosingRequest)request).getEntity();
                 EntityUtils.consume(entity);
             }
 
-        } catch (HttpException ex) {
+        } catch (final HttpException ex) {
             response = this.responseFactory.newHttpResponse
                 (HttpVersion.HTTP_1_0, HttpStatus.SC_INTERNAL_SERVER_ERROR,
                  context);
-            response.setParams(
-                    new DefaultedHttpParams(response.getParams(), this.params));
             handleException(ex, response);
         }
 
-        context.setAttribute(ExecutionContext.HTTP_RESPONSE, response);
+        context.setAttribute(HttpCoreContext.HTTP_RESPONSE, response);
 
         this.processor.process(response, context);
         conn.sendResponseHeader(response);
@@ -339,8 +388,8 @@ public class HttpService {
         if (message == null) {
             message = ex.toString();
         }
-        byte[] msg = EncodingUtils.getAsciiBytes(message);
-        ByteArrayEntity entity = new ByteArrayEntity(msg);
+        final byte[] msg = EncodingUtils.getAsciiBytes(message);
+        final ByteArrayEntity entity = new ByteArrayEntity(msg);
         entity.setContentType("text/plain; charset=US-ASCII");
         response.setEntity(entity);
     }
@@ -367,9 +416,8 @@ public class HttpService {
             final HttpResponse response,
             final HttpContext context) throws HttpException, IOException {
         HttpRequestHandler handler = null;
-        if (this.handlerResolver != null) {
-            String requestURI = request.getRequestLine().getUri();
-            handler = this.handlerResolver.lookup(requestURI);
+        if (this.handlerMapper != null) {
+            handler = this.handlerMapper.lookup(request);
         }
         if (handler != null) {
             handler.handle(request, response, context);
@@ -378,4 +426,22 @@ public class HttpService {
         }
     }
 
+    /**
+     * Adaptor class to transition from HttpRequestHandlerResolver to HttpRequestHandlerMapper.
+     */
+    @Deprecated
+    private static class HttpRequestHandlerResolverAdapter implements HttpRequestHandlerMapper {
+
+        private final HttpRequestHandlerResolver resolver;
+
+        public HttpRequestHandlerResolverAdapter(final HttpRequestHandlerResolver resolver) {
+            this.resolver = resolver;
+        }
+
+        public HttpRequestHandler lookup(final HttpRequest request) {
+            return resolver.lookup(request.getRequestLine().getUri());
+        }
+
+    }
+
 }
diff --git a/httpcore/src/main/java/org/apache/http/protocol/ImmutableHttpProcessor.java b/httpcore/src/main/java/org/apache/http/protocol/ImmutableHttpProcessor.java
index 82d02e7..661c339 100644
--- a/httpcore/src/main/java/org/apache/http/protocol/ImmutableHttpProcessor.java
+++ b/httpcore/src/main/java/org/apache/http/protocol/ImmutableHttpProcessor.java
@@ -22,11 +22,12 @@
  * individuals on behalf of the Apache Software Foundation.  For more
  * information on the Apache Software Foundation, please see
  * <http://www.apache.org/>.
+ *
  */
-
 package org.apache.http.protocol;
 
 import java.io.IOException;
+import java.util.List;
 
 import org.apache.http.HttpException;
 import org.apache.http.HttpRequest;
@@ -51,31 +52,52 @@ public final class ImmutableHttpProcessor implements HttpProcessor {
             final HttpResponseInterceptor[] responseInterceptors) {
         super();
         if (requestInterceptors != null) {
-            int count = requestInterceptors.length;
-            this.requestInterceptors = new HttpRequestInterceptor[count];
-            for (int i = 0; i < count; i++) {
-                this.requestInterceptors[i] = requestInterceptors[i];
-            }
+            final int l = requestInterceptors.length;
+            this.requestInterceptors = new HttpRequestInterceptor[l];
+            System.arraycopy(requestInterceptors, 0, this.requestInterceptors, 0, l);
         } else {
             this.requestInterceptors = new HttpRequestInterceptor[0];
         }
         if (responseInterceptors != null) {
-            int count = responseInterceptors.length;
-            this.responseInterceptors = new HttpResponseInterceptor[count];
-            for (int i = 0; i < count; i++) {
-                this.responseInterceptors[i] = responseInterceptors[i];
-            }
+            final int l = responseInterceptors.length;
+            this.responseInterceptors = new HttpResponseInterceptor[l];
+            System.arraycopy(responseInterceptors, 0, this.responseInterceptors, 0, l);
+        } else {
+            this.responseInterceptors = new HttpResponseInterceptor[0];
+        }
+    }
+
+    /**
+     * @since 4.3
+     */
+    public ImmutableHttpProcessor(
+            final List<HttpRequestInterceptor> requestInterceptors,
+            final List<HttpResponseInterceptor> responseInterceptors) {
+        super();
+        if (requestInterceptors != null) {
+            final int l = requestInterceptors.size();
+            this.requestInterceptors = requestInterceptors.toArray(new HttpRequestInterceptor[l]);
+        } else {
+            this.requestInterceptors = new HttpRequestInterceptor[0];
+        }
+        if (responseInterceptors != null) {
+            final int l = responseInterceptors.size();
+            this.responseInterceptors = responseInterceptors.toArray(new HttpResponseInterceptor[l]);
         } else {
             this.responseInterceptors = new HttpResponseInterceptor[0];
         }
     }
 
+    /**
+     * @deprecated (4.3) do not use.
+     */
+    @Deprecated
     public ImmutableHttpProcessor(
             final HttpRequestInterceptorList requestInterceptors,
             final HttpResponseInterceptorList responseInterceptors) {
         super();
         if (requestInterceptors != null) {
-            int count = requestInterceptors.getRequestInterceptorCount();
+            final int count = requestInterceptors.getRequestInterceptorCount();
             this.requestInterceptors = new HttpRequestInterceptor[count];
             for (int i = 0; i < count; i++) {
                 this.requestInterceptors[i] = requestInterceptors.getRequestInterceptor(i);
@@ -84,7 +106,7 @@ public final class ImmutableHttpProcessor implements HttpProcessor {
             this.requestInterceptors = new HttpRequestInterceptor[0];
         }
         if (responseInterceptors != null) {
-            int count = responseInterceptors.getResponseInterceptorCount();
+            final int count = responseInterceptors.getResponseInterceptorCount();
             this.responseInterceptors = new HttpResponseInterceptor[count];
             for (int i = 0; i < count; i++) {
                 this.responseInterceptors[i] = responseInterceptors.getResponseInterceptor(i);
@@ -94,27 +116,27 @@ public final class ImmutableHttpProcessor implements HttpProcessor {
         }
     }
 
-    public ImmutableHttpProcessor(final HttpRequestInterceptor[] requestInterceptors) {
+    public ImmutableHttpProcessor(final HttpRequestInterceptor... requestInterceptors) {
         this(requestInterceptors, null);
     }
 
-    public ImmutableHttpProcessor(final HttpResponseInterceptor[] responseInterceptors) {
+    public ImmutableHttpProcessor(final HttpResponseInterceptor... responseInterceptors) {
         this(null, responseInterceptors);
     }
 
     public void process(
             final HttpRequest request,
             final HttpContext context) throws IOException, HttpException {
-        for (int i = 0; i < this.requestInterceptors.length; i++) {
-            this.requestInterceptors[i].process(request, context);
+        for (final HttpRequestInterceptor requestInterceptor : this.requestInterceptors) {
+            requestInterceptor.process(request, context);
         }
     }
 
     public void process(
             final HttpResponse response,
             final HttpContext context) throws IOException, HttpException {
-        for (int i = 0; i < this.responseInterceptors.length; i++) {
-            this.responseInterceptors[i].process(response, context);
+        for (final HttpResponseInterceptor responseInterceptor : this.responseInterceptors) {
+            responseInterceptor.process(response, context);
         }
     }
 
diff --git a/httpcore/src/main/java/org/apache/http/protocol/RequestConnControl.java b/httpcore/src/main/java/org/apache/http/protocol/RequestConnControl.java
index 5bae97e..afd9b24 100644
--- a/httpcore/src/main/java/org/apache/http/protocol/RequestConnControl.java
+++ b/httpcore/src/main/java/org/apache/http/protocol/RequestConnControl.java
@@ -33,6 +33,7 @@ import org.apache.http.HttpException;
 import org.apache.http.HttpRequest;
 import org.apache.http.HttpRequestInterceptor;
 import org.apache.http.annotation.Immutable;
+import org.apache.http.util.Args;
 
 /**
  * RequestConnControl is responsible for adding <code>Connection</code> header
@@ -51,11 +52,9 @@ public class RequestConnControl implements HttpRequestInterceptor {
 
     public void process(final HttpRequest request, final HttpContext context)
             throws HttpException, IOException {
-        if (request == null) {
-            throw new IllegalArgumentException("HTTP request may not be null");
-        }
+        Args.notNull(request, "HTTP request");
 
-        String method = request.getRequestLine().getMethod();
+        final String method = request.getRequestLine().getMethod();
         if (method.equalsIgnoreCase("CONNECT")) {
             return;
         }
diff --git a/httpcore/src/main/java/org/apache/http/protocol/RequestContent.java b/httpcore/src/main/java/org/apache/http/protocol/RequestContent.java
index 82bc372..9d2fefe 100644
--- a/httpcore/src/main/java/org/apache/http/protocol/RequestContent.java
+++ b/httpcore/src/main/java/org/apache/http/protocol/RequestContent.java
@@ -35,9 +35,10 @@ import org.apache.http.HttpException;
 import org.apache.http.HttpRequest;
 import org.apache.http.HttpRequestInterceptor;
 import org.apache.http.HttpVersion;
-import org.apache.http.ProtocolVersion;
 import org.apache.http.ProtocolException;
+import org.apache.http.ProtocolVersion;
 import org.apache.http.annotation.Immutable;
+import org.apache.http.util.Args;
 
 /**
  * RequestContent is the most important interceptor for outgoing requests.
@@ -71,19 +72,17 @@ public class RequestContent implements HttpRequestInterceptor {
      * If set to <code>false</code> the <code>Content-Length</code> and
      * <code>Transfer-Encoding</code> headers will cause the interceptor to throw
      * {@link ProtocolException} if already present in the response message.
-     * 
+     *
      * @since 4.2
      */
-     public RequestContent(boolean overwrite) {
+     public RequestContent(final boolean overwrite) {
          super();
          this.overwrite = overwrite;
     }
 
     public void process(final HttpRequest request, final HttpContext context)
             throws HttpException, IOException {
-        if (request == null) {
-            throw new IllegalArgumentException("HTTP request may not be null");
-        }
+        Args.notNull(request, "HTTP request");
         if (request instanceof HttpEntityEnclosingRequest) {
             if (this.overwrite) {
                 request.removeHeaders(HTTP.TRANSFER_ENCODING);
@@ -96,8 +95,8 @@ public class RequestContent implements HttpRequestInterceptor {
                     throw new ProtocolException("Content-Length header already present");
                 }
             }
-            ProtocolVersion ver = request.getRequestLine().getProtocolVersion();
-            HttpEntity entity = ((HttpEntityEnclosingRequest)request).getEntity();
+            final ProtocolVersion ver = request.getRequestLine().getProtocolVersion();
+            final HttpEntity entity = ((HttpEntityEnclosingRequest)request).getEntity();
             if (entity == null) {
                 request.addHeader(HTTP.CONTENT_LEN, "0");
                 return;
diff --git a/httpcore/src/main/java/org/apache/http/protocol/RequestDate.java b/httpcore/src/main/java/org/apache/http/protocol/RequestDate.java
index bc31cfd..306522d 100644
--- a/httpcore/src/main/java/org/apache/http/protocol/RequestDate.java
+++ b/httpcore/src/main/java/org/apache/http/protocol/RequestDate.java
@@ -29,11 +29,12 @@ package org.apache.http.protocol;
 
 import java.io.IOException;
 
+import org.apache.http.HttpEntityEnclosingRequest;
 import org.apache.http.HttpException;
 import org.apache.http.HttpRequest;
-import org.apache.http.HttpEntityEnclosingRequest;
 import org.apache.http.HttpRequestInterceptor;
 import org.apache.http.annotation.ThreadSafe;
+import org.apache.http.util.Args;
 
 /**
  * RequestDate interceptor is responsible for adding <code>Date</code> header
@@ -53,13 +54,10 @@ public class RequestDate implements HttpRequestInterceptor {
 
     public void process(final HttpRequest request, final HttpContext context)
             throws HttpException, IOException {
-        if (request == null) {
-            throw new IllegalArgumentException
-                ("HTTP request may not be null.");
-        }
+        Args.notNull(request, "HTTP request");
         if ((request instanceof HttpEntityEnclosingRequest) &&
             !request.containsHeader(HTTP.DATE_HEADER)) {
-            String httpdate = DATE_GENERATOR.getCurrentDate();
+            final String httpdate = DATE_GENERATOR.getCurrentDate();
             request.setHeader(HTTP.DATE_HEADER, httpdate);
         }
     }
diff --git a/httpcore/src/main/java/org/apache/http/protocol/RequestExpectContinue.java b/httpcore/src/main/java/org/apache/http/protocol/RequestExpectContinue.java
index e0573ce..baf9c58 100644
--- a/httpcore/src/main/java/org/apache/http/protocol/RequestExpectContinue.java
+++ b/httpcore/src/main/java/org/apache/http/protocol/RequestExpectContinue.java
@@ -37,41 +37,54 @@ import org.apache.http.HttpRequestInterceptor;
 import org.apache.http.HttpVersion;
 import org.apache.http.ProtocolVersion;
 import org.apache.http.annotation.Immutable;
-import org.apache.http.params.HttpProtocolParams;
+import org.apache.http.params.CoreProtocolPNames;
+import org.apache.http.util.Args;
 
 /**
  * RequestExpectContinue is responsible for enabling the 'expect-continue'
  * handshake by adding <code>Expect</code> header. This interceptor is
  * recommended for client side protocol processors.
- * <p>
- * The following parameters can be used to customize the behavior of this
- * class:
- * <ul>
- *  <li>{@link org.apache.http.params.CoreProtocolPNames#USE_EXPECT_CONTINUE}</li>
- * </ul>
  *
  * @since 4.0
  */
 @Immutable
+ at SuppressWarnings("deprecation")
 public class RequestExpectContinue implements HttpRequestInterceptor {
 
+    private final boolean activeByDefault;
+
+    /**
+     * @deprecated (4.3) use {@link org.apache.http.protocol.RequestExpectContinue#RequestExpectContinue(boolean)}
+     */
+    @Deprecated
     public RequestExpectContinue() {
+        this(false);
+    }
+
+    /**
+     * @since 4.3
+     */
+    public RequestExpectContinue(final boolean activeByDefault) {
         super();
+        this.activeByDefault = activeByDefault;
     }
 
     public void process(final HttpRequest request, final HttpContext context)
             throws HttpException, IOException {
-        if (request == null) {
-            throw new IllegalArgumentException("HTTP request may not be null");
-        }
-        if (request instanceof HttpEntityEnclosingRequest) {
-            HttpEntity entity = ((HttpEntityEnclosingRequest)request).getEntity();
-            // Do not send the expect header if request body is known to be empty
-            if (entity != null && entity.getContentLength() != 0) {
-                ProtocolVersion ver = request.getRequestLine().getProtocolVersion();
-                if (HttpProtocolParams.useExpectContinue(request.getParams())
-                        && !ver.lessEquals(HttpVersion.HTTP_1_0)) {
-                    request.addHeader(HTTP.EXPECT_DIRECTIVE, HTTP.EXPECT_CONTINUE);
+        Args.notNull(request, "HTTP request");
+
+        if (!request.containsHeader(HTTP.EXPECT_DIRECTIVE)) {
+            if (request instanceof HttpEntityEnclosingRequest) {
+                final ProtocolVersion ver = request.getRequestLine().getProtocolVersion();
+                final HttpEntity entity = ((HttpEntityEnclosingRequest)request).getEntity();
+                // Do not send the expect header if request body is known to be empty
+                if (entity != null
+                        && entity.getContentLength() != 0 && !ver.lessEquals(HttpVersion.HTTP_1_0)) {
+                    final boolean active = request.getParams().getBooleanParameter(
+                            CoreProtocolPNames.USE_EXPECT_CONTINUE, this.activeByDefault);
+                    if (active) {
+                        request.addHeader(HTTP.EXPECT_DIRECTIVE, HTTP.EXPECT_CONTINUE);
+                    }
                 }
             }
         }
diff --git a/httpcore/src/main/java/org/apache/http/protocol/RequestTargetHost.java b/httpcore/src/main/java/org/apache/http/protocol/RequestTargetHost.java
index 88bbb96..5313656 100644
--- a/httpcore/src/main/java/org/apache/http/protocol/RequestTargetHost.java
+++ b/httpcore/src/main/java/org/apache/http/protocol/RequestTargetHost.java
@@ -37,9 +37,10 @@ import org.apache.http.HttpInetConnection;
 import org.apache.http.HttpRequest;
 import org.apache.http.HttpRequestInterceptor;
 import org.apache.http.HttpVersion;
-import org.apache.http.ProtocolVersion;
 import org.apache.http.ProtocolException;
+import org.apache.http.ProtocolVersion;
 import org.apache.http.annotation.Immutable;
+import org.apache.http.util.Args;
 
 /**
  * RequestTargetHost is responsible for adding <code>Host</code> header. This
@@ -56,30 +57,25 @@ public class RequestTargetHost implements HttpRequestInterceptor {
 
     public void process(final HttpRequest request, final HttpContext context)
             throws HttpException, IOException {
-        if (request == null) {
-            throw new IllegalArgumentException("HTTP request may not be null");
-        }
-        if (context == null) {
-            throw new IllegalArgumentException("HTTP context may not be null");
-        }
+        Args.notNull(request, "HTTP request");
+
+        final HttpCoreContext corecontext = HttpCoreContext.adapt(context);
 
-        ProtocolVersion ver = request.getRequestLine().getProtocolVersion();
-        String method = request.getRequestLine().getMethod();
+        final ProtocolVersion ver = request.getRequestLine().getProtocolVersion();
+        final String method = request.getRequestLine().getMethod();
         if (method.equalsIgnoreCase("CONNECT") && ver.lessEquals(HttpVersion.HTTP_1_0)) {
             return;
         }
 
         if (!request.containsHeader(HTTP.TARGET_HOST)) {
-            HttpHost targethost = (HttpHost) context
-                .getAttribute(ExecutionContext.HTTP_TARGET_HOST);
+            HttpHost targethost = corecontext.getTargetHost();
             if (targethost == null) {
-                HttpConnection conn = (HttpConnection) context
-                    .getAttribute(ExecutionContext.HTTP_CONNECTION);
+                final HttpConnection conn = corecontext.getConnection();
                 if (conn instanceof HttpInetConnection) {
                     // Populate the context with a default HTTP host based on the
                     // inet address of the target host
-                    InetAddress address = ((HttpInetConnection) conn).getRemoteAddress();
-                    int port = ((HttpInetConnection) conn).getRemotePort();
+                    final InetAddress address = ((HttpInetConnection) conn).getRemoteAddress();
+                    final int port = ((HttpInetConnection) conn).getRemotePort();
                     if (address != null) {
                         targethost = new HttpHost(address.getHostName(), port);
                     }
diff --git a/httpcore/src/main/java/org/apache/http/protocol/RequestUserAgent.java b/httpcore/src/main/java/org/apache/http/protocol/RequestUserAgent.java
index 862a00a..8f2d3d1 100644
--- a/httpcore/src/main/java/org/apache/http/protocol/RequestUserAgent.java
+++ b/httpcore/src/main/java/org/apache/http/protocol/RequestUserAgent.java
@@ -33,36 +33,45 @@ import org.apache.http.HttpException;
 import org.apache.http.HttpRequest;
 import org.apache.http.HttpRequestInterceptor;
 import org.apache.http.annotation.Immutable;
-import org.apache.http.params.HttpProtocolParams;
+import org.apache.http.params.CoreProtocolPNames;
+import org.apache.http.params.HttpParams;
+import org.apache.http.util.Args;
 
 /**
  * RequestUserAgent is responsible for adding <code>User-Agent</code> header.
  * This interceptor is recommended for client side protocol processors.
- * <p>
- * The following parameters can be used to customize the behavior of this
- * class:
- * <ul>
- *  <li>{@link org.apache.http.params.CoreProtocolPNames#USER_AGENT}</li>
- * </ul>
  *
  * @since 4.0
  */
+ at SuppressWarnings("deprecation")
 @Immutable
 public class RequestUserAgent implements HttpRequestInterceptor {
 
-    public RequestUserAgent() {
+    private final String userAgent;
+
+    public RequestUserAgent(final String userAgent) {
         super();
+        this.userAgent = userAgent;
+    }
+
+    public RequestUserAgent() {
+        this(null);
     }
 
     public void process(final HttpRequest request, final HttpContext context)
         throws HttpException, IOException {
-        if (request == null) {
-            throw new IllegalArgumentException("HTTP request may not be null");
-        }
+        Args.notNull(request, "HTTP request");
         if (!request.containsHeader(HTTP.USER_AGENT)) {
-            String useragent = HttpProtocolParams.getUserAgent(request.getParams());
-            if (useragent != null) {
-                request.addHeader(HTTP.USER_AGENT, useragent);
+            String s = null;
+            final HttpParams params = request.getParams();
+            if (params != null) {
+                s = (String) params.getParameter(CoreProtocolPNames.USER_AGENT);
+            }
+            if (s == null) {
+                s = this.userAgent;
+            }
+            if (s != null) {
+                request.addHeader(HTTP.USER_AGENT, s);
             }
         }
     }
diff --git a/httpcore/src/main/java/org/apache/http/protocol/ResponseConnControl.java b/httpcore/src/main/java/org/apache/http/protocol/ResponseConnControl.java
index bef1bcf..87f5908 100644
--- a/httpcore/src/main/java/org/apache/http/protocol/ResponseConnControl.java
+++ b/httpcore/src/main/java/org/apache/http/protocol/ResponseConnControl.java
@@ -39,6 +39,7 @@ import org.apache.http.HttpStatus;
 import org.apache.http.HttpVersion;
 import org.apache.http.ProtocolVersion;
 import org.apache.http.annotation.Immutable;
+import org.apache.http.util.Args;
 
 /**
  * ResponseConnControl is responsible for adding <code>Connection</code> header
@@ -57,14 +58,12 @@ public class ResponseConnControl implements HttpResponseInterceptor {
 
     public void process(final HttpResponse response, final HttpContext context)
             throws HttpException, IOException {
-        if (response == null) {
-            throw new IllegalArgumentException("HTTP response may not be null");
-        }
-        if (context == null) {
-            throw new IllegalArgumentException("HTTP context may not be null");
-        }
+        Args.notNull(response, "HTTP response");
+
+        final HttpCoreContext corecontext = HttpCoreContext.adapt(context);
+
         // Always drop connection after certain type of responses
-        int status = response.getStatusLine().getStatusCode();
+        final int status = response.getStatusLine().getStatusCode();
         if (status == HttpStatus.SC_BAD_REQUEST ||
                 status == HttpStatus.SC_REQUEST_TIMEOUT ||
                 status == HttpStatus.SC_LENGTH_REQUIRED ||
@@ -75,16 +74,16 @@ public class ResponseConnControl implements HttpResponseInterceptor {
             response.setHeader(HTTP.CONN_DIRECTIVE, HTTP.CONN_CLOSE);
             return;
         }
-        Header explicit = response.getFirstHeader(HTTP.CONN_DIRECTIVE);
+        final Header explicit = response.getFirstHeader(HTTP.CONN_DIRECTIVE);
         if (explicit != null && HTTP.CONN_CLOSE.equalsIgnoreCase(explicit.getValue())) {
             // Connection persistence explicitly disabled
             return;
         }
         // Always drop connection for HTTP/1.0 responses and below
         // if the content body cannot be correctly delimited
-        HttpEntity entity = response.getEntity();
+        final HttpEntity entity = response.getEntity();
         if (entity != null) {
-            ProtocolVersion ver = response.getStatusLine().getProtocolVersion();
+            final ProtocolVersion ver = response.getStatusLine().getProtocolVersion();
             if (entity.getContentLength() < 0 &&
                     (!entity.isChunked() || ver.lessEquals(HttpVersion.HTTP_1_0))) {
                 response.setHeader(HTTP.CONN_DIRECTIVE, HTTP.CONN_CLOSE);
@@ -92,10 +91,9 @@ public class ResponseConnControl implements HttpResponseInterceptor {
             }
         }
         // Drop connection if requested by the client or request was <= 1.0
-        HttpRequest request = (HttpRequest)
-            context.getAttribute(ExecutionContext.HTTP_REQUEST);
+        final HttpRequest request = corecontext.getRequest();
         if (request != null) {
-            Header header = request.getFirstHeader(HTTP.CONN_DIRECTIVE);
+            final Header header = request.getFirstHeader(HTTP.CONN_DIRECTIVE);
             if (header != null) {
                 response.setHeader(HTTP.CONN_DIRECTIVE, header.getValue());
             } else if (request.getProtocolVersion().lessEquals(HttpVersion.HTTP_1_0)) {
diff --git a/httpcore/src/main/java/org/apache/http/protocol/ResponseContent.java b/httpcore/src/main/java/org/apache/http/protocol/ResponseContent.java
index bf490d9..5e1453a 100644
--- a/httpcore/src/main/java/org/apache/http/protocol/ResponseContent.java
+++ b/httpcore/src/main/java/org/apache/http/protocol/ResponseContent.java
@@ -35,9 +35,10 @@ import org.apache.http.HttpResponse;
 import org.apache.http.HttpResponseInterceptor;
 import org.apache.http.HttpStatus;
 import org.apache.http.HttpVersion;
-import org.apache.http.ProtocolVersion;
 import org.apache.http.ProtocolException;
+import org.apache.http.ProtocolVersion;
 import org.apache.http.annotation.Immutable;
+import org.apache.http.util.Args;
 
 /**
  * ResponseContent is the most important interceptor for outgoing responses.
@@ -71,10 +72,10 @@ public class ResponseContent implements HttpResponseInterceptor {
      * If set to <code>false</code> the <code>Content-Length</code> and
      * <code>Transfer-Encoding</code> headers will cause the interceptor to throw
      * {@link ProtocolException} if already present in the response message.
-     * 
+     *
      * @since 4.2
      */
-     public ResponseContent(boolean overwrite) {
+     public ResponseContent(final boolean overwrite) {
          super();
          this.overwrite = overwrite;
     }
@@ -88,9 +89,7 @@ public class ResponseContent implements HttpResponseInterceptor {
      */
     public void process(final HttpResponse response, final HttpContext context)
             throws HttpException, IOException {
-        if (response == null) {
-            throw new IllegalArgumentException("HTTP response may not be null");
-        }
+        Args.notNull(response, "HTTP response");
         if (this.overwrite) {
             response.removeHeaders(HTTP.TRANSFER_ENCODING);
             response.removeHeaders(HTTP.CONTENT_LEN);
@@ -102,10 +101,10 @@ public class ResponseContent implements HttpResponseInterceptor {
                 throw new ProtocolException("Content-Length header already present");
             }
         }
-        ProtocolVersion ver = response.getStatusLine().getProtocolVersion();
-        HttpEntity entity = response.getEntity();
+        final ProtocolVersion ver = response.getStatusLine().getProtocolVersion();
+        final HttpEntity entity = response.getEntity();
         if (entity != null) {
-            long len = entity.getContentLength();
+            final long len = entity.getContentLength();
             if (entity.isChunked() && !ver.lessEquals(HttpVersion.HTTP_1_0)) {
                 response.addHeader(HTTP.TRANSFER_ENCODING, HTTP.CHUNK_CODING);
             } else if (len >= 0) {
@@ -122,7 +121,7 @@ public class ResponseContent implements HttpResponseInterceptor {
                 response.addHeader(entity.getContentEncoding());
             }
         } else {
-            int status = response.getStatusLine().getStatusCode();
+            final int status = response.getStatusLine().getStatusCode();
             if (status != HttpStatus.SC_NO_CONTENT
                     && status != HttpStatus.SC_NOT_MODIFIED
                     && status != HttpStatus.SC_RESET_CONTENT) {
diff --git a/httpcore/src/main/java/org/apache/http/protocol/ResponseDate.java b/httpcore/src/main/java/org/apache/http/protocol/ResponseDate.java
index d83e570..a896f07 100644
--- a/httpcore/src/main/java/org/apache/http/protocol/ResponseDate.java
+++ b/httpcore/src/main/java/org/apache/http/protocol/ResponseDate.java
@@ -34,6 +34,7 @@ import org.apache.http.HttpResponse;
 import org.apache.http.HttpResponseInterceptor;
 import org.apache.http.HttpStatus;
 import org.apache.http.annotation.ThreadSafe;
+import org.apache.http.util.Args;
 
 /**
  * ResponseDate is responsible for adding <code>Date<c/ode> header to the
@@ -53,14 +54,11 @@ public class ResponseDate implements HttpResponseInterceptor {
 
     public void process(final HttpResponse response, final HttpContext context)
             throws HttpException, IOException {
-        if (response == null) {
-            throw new IllegalArgumentException
-                ("HTTP response may not be null.");
-        }
-        int status = response.getStatusLine().getStatusCode();
+        Args.notNull(response, "HTTP response");
+        final int status = response.getStatusLine().getStatusCode();
         if ((status >= HttpStatus.SC_OK) &&
             !response.containsHeader(HTTP.DATE_HEADER)) {
-            String httpdate = DATE_GENERATOR.getCurrentDate();
+            final String httpdate = DATE_GENERATOR.getCurrentDate();
             response.setHeader(HTTP.DATE_HEADER, httpdate);
         }
     }
diff --git a/httpcore/src/main/java/org/apache/http/protocol/ResponseServer.java b/httpcore/src/main/java/org/apache/http/protocol/ResponseServer.java
index 9ca3303..e4fd770 100644
--- a/httpcore/src/main/java/org/apache/http/protocol/ResponseServer.java
+++ b/httpcore/src/main/java/org/apache/http/protocol/ResponseServer.java
@@ -33,37 +33,37 @@ import org.apache.http.HttpException;
 import org.apache.http.HttpResponse;
 import org.apache.http.HttpResponseInterceptor;
 import org.apache.http.annotation.Immutable;
-import org.apache.http.params.CoreProtocolPNames;
+import org.apache.http.util.Args;
 
 /**
  * ResponseServer is responsible for adding <code>Server</code> header. This
  * interceptor is recommended for server side protocol processors.
- * <p>
- * The following parameters can be used to customize the behavior of this
- * class:
- * <ul>
- *  <li>{@link org.apache.http.params.CoreProtocolPNames#ORIGIN_SERVER}</li>
- * </ul>
  *
  * @since 4.0
  */
 @Immutable
 public class ResponseServer implements HttpResponseInterceptor {
 
-    public ResponseServer() {
+    private final String originServer;
+
+    /**
+     * @since 4.3
+     */
+    public ResponseServer(final String originServer) {
         super();
+        this.originServer = originServer;
+    }
+
+    public ResponseServer() {
+        this(null);
     }
 
     public void process(final HttpResponse response, final HttpContext context)
             throws HttpException, IOException {
-        if (response == null) {
-            throw new IllegalArgumentException("HTTP request may not be null");
-        }
+        Args.notNull(response, "HTTP response");
         if (!response.containsHeader(HTTP.SERVER_HEADER)) {
-            String s = (String) response.getParams().getParameter(
-                    CoreProtocolPNames.ORIGIN_SERVER);
-            if (s != null) {
-                response.addHeader(HTTP.SERVER_HEADER, s);
+            if (this.originServer != null) {
+                response.addHeader(HTTP.SERVER_HEADER, this.originServer);
             }
         }
     }
diff --git a/httpcore/src/main/java/org/apache/http/protocol/HttpRequestHandlerRegistry.java b/httpcore/src/main/java/org/apache/http/protocol/UriHttpRequestHandlerMapper.java
similarity index 62%
rename from httpcore/src/main/java/org/apache/http/protocol/HttpRequestHandlerRegistry.java
rename to httpcore/src/main/java/org/apache/http/protocol/UriHttpRequestHandlerMapper.java
index 737317b..0f03161 100644
--- a/httpcore/src/main/java/org/apache/http/protocol/HttpRequestHandlerRegistry.java
+++ b/httpcore/src/main/java/org/apache/http/protocol/UriHttpRequestHandlerMapper.java
@@ -27,9 +27,9 @@
 
 package org.apache.http.protocol;
 
-import java.util.Map;
-
+import org.apache.http.HttpRequest;
 import org.apache.http.annotation.ThreadSafe;
+import org.apache.http.util.Args;
 
 /**
  * Maintains a map of HTTP request handlers keyed by a request URI pattern.
@@ -41,20 +41,25 @@ import org.apache.http.annotation.ThreadSafe;
  *   <li><code><uri>*</code></li>
  * </ul>
  * <br>
- * This class can be used to resolve an instance of
+ * This class can be used to map an instance of
  * {@link HttpRequestHandler} matching a particular request URI. Usually the
- * resolved request handler will be used to process the request with the
+ * mapped request handler will be used to process the request with the
  * specified request URI.
  *
- * @since 4.0
+ * @since 4.3
  */
 @ThreadSafe // provided injected dependencies are thread-safe
-public class HttpRequestHandlerRegistry implements HttpRequestHandlerResolver {
+public class UriHttpRequestHandlerMapper implements HttpRequestHandlerMapper {
 
     private final UriPatternMatcher<HttpRequestHandler> matcher;
 
-    public HttpRequestHandlerRegistry() {
-        matcher = new UriPatternMatcher<HttpRequestHandler>();
+    protected UriHttpRequestHandlerMapper(final UriPatternMatcher<HttpRequestHandler> matcher) {
+        super();
+        this.matcher = Args.notNull(matcher, "Pattern matcher");
+    }
+
+    public UriHttpRequestHandlerMapper() {
+        this(new UriPatternMatcher<HttpRequestHandler>());
     }
 
     /**
@@ -65,12 +70,8 @@ public class HttpRequestHandlerRegistry implements HttpRequestHandlerResolver {
      * @param handler the handler.
      */
     public void register(final String pattern, final HttpRequestHandler handler) {
-        if (pattern == null) {
-            throw new IllegalArgumentException("URI request pattern may not be null");
-        }
-        if (handler == null) {
-            throw new IllegalArgumentException("Request handler may not be null");
-        }
+        Args.notNull(pattern, "Pattern");
+        Args.notNull(handler, "Handler");
         matcher.register(pattern, handler);
     }
 
@@ -84,25 +85,31 @@ public class HttpRequestHandlerRegistry implements HttpRequestHandlerResolver {
     }
 
     /**
-     * Sets handlers from the given map.
-     * @param map the map containing handlers keyed by their URI patterns.
+     * Extracts request path from the given {@link HttpRequest}
      */
-    public void setHandlers(final Map<String, HttpRequestHandler> map) {
-        matcher.setObjects(map);
+    protected String getRequestPath(final HttpRequest request) {
+        String uriPath = request.getRequestLine().getUri();
+        int index = uriPath.indexOf("?");
+        if (index != -1) {
+            uriPath = uriPath.substring(0, index);
+        } else {
+            index = uriPath.indexOf("#");
+            if (index != -1) {
+                uriPath = uriPath.substring(0, index);
+            }
+        }
+        return uriPath;
     }
 
     /**
-     * Get the handler map.
-     * @return The map of handlers and their associated URI patterns.
+     * Looks up a handler matching the given request URI.
      *
-     * @since 4.2
+     * @param request the request
+     * @return handler or <code>null</code> if no match is found.
      */
-    public Map<String, HttpRequestHandler> getHandlers() {
-        return matcher.getObjects();
-    }
-
-    public HttpRequestHandler lookup(final String requestURI) {
-        return matcher.lookup(requestURI);
+    public HttpRequestHandler lookup(final HttpRequest request) {
+        Args.notNull(request, "HTTP request");
+        return matcher.lookup(getRequestPath(request));
     }
 
 }
diff --git a/httpcore/src/main/java/org/apache/http/protocol/UriPatternMatcher.java b/httpcore/src/main/java/org/apache/http/protocol/UriPatternMatcher.java
index 4c60b79..affded7 100644
--- a/httpcore/src/main/java/org/apache/http/protocol/UriPatternMatcher.java
+++ b/httpcore/src/main/java/org/apache/http/protocol/UriPatternMatcher.java
@@ -28,11 +28,11 @@
 package org.apache.http.protocol;
 
 import java.util.HashMap;
-import java.util.Iterator;
 import java.util.Map;
 
 import org.apache.http.annotation.GuardedBy;
 import org.apache.http.annotation.ThreadSafe;
+import org.apache.http.util.Args;
 
 /**
  * Maintains a map of objects keyed by a request URI pattern.
@@ -67,9 +67,7 @@ public class UriPatternMatcher<T> {
      * @param obj the object.
      */
     public synchronized void register(final String pattern, final T obj) {
-        if (pattern == null) {
-            throw new IllegalArgumentException("URI request pattern may not be null");
-        }
+        Args.notNull(pattern, "URI request pattern");
         this.map.put(pattern, obj);
     }
 
@@ -86,63 +84,48 @@ public class UriPatternMatcher<T> {
     }
 
     /**
-     * @deprecated (4.1) use {@link #setObjects(Map)}
+     * @deprecated (4.1) do not use
      */
     @Deprecated
     public synchronized void setHandlers(final Map<String, T> map) {
-        if (map == null) {
-            throw new IllegalArgumentException("Map of handlers may not be null");
-        }
+        Args.notNull(map, "Map of handlers");
         this.map.clear();
         this.map.putAll(map);
     }
 
     /**
-     * Sets objects from the given map.
-     * @param map the map containing objects keyed by their URI patterns.
+     * @deprecated (4.1) do not use
      */
+    @Deprecated
     public synchronized void setObjects(final Map<String, T> map) {
-        if (map == null) {
-            throw new IllegalArgumentException("Map of handlers may not be null");
-        }
+        Args.notNull(map, "Map of handlers");
         this.map.clear();
         this.map.putAll(map);
     }
 
     /**
-     * Returns the objects map.
-     * @return The map of objects.
-     *
-     * @since 4.2
+     * @deprecated (4.1) do not use
      */
+    @Deprecated
     public synchronized Map<String, T> getObjects() {
         return this.map;
     }
 
     /**
-     * Looks up an object matching the given request URI.
+     * Looks up an object matching the given request path.
      *
-     * @param requestURI the request URI
+     * @param path the request path
      * @return object or <code>null</code> if no match is found.
      */
-    public synchronized T lookup(String requestURI) {
-        if (requestURI == null) {
-            throw new IllegalArgumentException("Request URI may not be null");
-        }
-        //Strip away the query part part if found
-        int index = requestURI.indexOf("?");
-        if (index != -1) {
-            requestURI = requestURI.substring(0, index);
-        }
-
+    public synchronized T lookup(final String path) {
+        Args.notNull(path, "Request path");
         // direct match?
-        T obj = this.map.get(requestURI);
+        T obj = this.map.get(path);
         if (obj == null) {
             // pattern match?
             String bestMatch = null;
-            for (Iterator<String> it = this.map.keySet().iterator(); it.hasNext();) {
-                String pattern = it.next();
-                if (matchUriRequestPattern(pattern, requestURI)) {
+            for (final String pattern : this.map.keySet()) {
+                if (matchUriRequestPattern(pattern, path)) {
                     // we have a match. is it any better?
                     if (bestMatch == null
                             || (bestMatch.length() < pattern.length())
@@ -157,21 +140,26 @@ public class UriPatternMatcher<T> {
     }
 
     /**
-     * Tests if the given request URI matches the given pattern.
+     * Tests if the given request path matches the given pattern.
      *
      * @param pattern the pattern
-     * @param requestUri the request URI
+     * @param path the request path
      * @return <code>true</code> if the request URI matches the pattern,
      *   <code>false</code> otherwise.
      */
-    protected boolean matchUriRequestPattern(final String pattern, final String requestUri) {
+    protected boolean matchUriRequestPattern(final String pattern, final String path) {
         if (pattern.equals("*")) {
             return true;
         } else {
             return
-            (pattern.endsWith("*") && requestUri.startsWith(pattern.substring(0, pattern.length() - 1))) ||
-            (pattern.startsWith("*") && requestUri.endsWith(pattern.substring(1, pattern.length())));
+            (pattern.endsWith("*") && path.startsWith(pattern.substring(0, pattern.length() - 1))) ||
+            (pattern.startsWith("*") && path.endsWith(pattern.substring(1, pattern.length())));
         }
     }
 
+    @Override
+    public String toString() {
+        return this.map.toString();
+    }
+
 }
diff --git a/httpcore/src/main/java/org/apache/http/protocol/package.html b/httpcore/src/main/java/org/apache/http/protocol/package.html
index f000350..bef4549 100644
--- a/httpcore/src/main/java/org/apache/http/protocol/package.html
+++ b/httpcore/src/main/java/org/apache/http/protocol/package.html
@@ -30,7 +30,7 @@
 -->
 </head>
 <body>
-HTTP protocol execution framework and synchronous HTTP protocol handlers 
+HTTP protocol execution framework and synchronous HTTP protocol handlers
 based on the blocking I/O model.
 </body>
 </html>
diff --git a/httpcore/src/main/java/org/apache/http/util/Args.java b/httpcore/src/main/java/org/apache/http/util/Args.java
new file mode 100644
index 0000000..eed9034
--- /dev/null
+++ b/httpcore/src/main/java/org/apache/http/util/Args.java
@@ -0,0 +1,111 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+
+package org.apache.http.util;
+
+import java.util.Collection;
+
+public class Args {
+
+    public static void check(final boolean expression, final String message) {
+        if (!expression) {
+            throw new IllegalArgumentException(message);
+        }
+    }
+
+    public static void check(final boolean expression, final String message, final Object... args) {
+        if (!expression) {
+            throw new IllegalArgumentException(String.format(message, args));
+        }
+    }
+
+    public static <T> T notNull(final T argument, final String name) {
+        if (argument == null) {
+            throw new IllegalArgumentException(name + " may not be null");
+        }
+        return argument;
+    }
+
+    public static <T extends CharSequence> T notEmpty(final T argument, final String name) {
+        if (argument == null) {
+            throw new IllegalArgumentException(name + " may not be null");
+        }
+        if (TextUtils.isEmpty(argument)) {
+            throw new IllegalArgumentException(name + " may not be empty");
+        }
+        return argument;
+    }
+
+    public static <T extends CharSequence> T notBlank(final T argument, final String name) {
+        if (argument == null) {
+            throw new IllegalArgumentException(name + " may not be null");
+        }
+        if (TextUtils.isBlank(argument)) {
+            throw new IllegalArgumentException(name + " may not be blank");
+        }
+        return argument;
+    }
+
+    public static <E, T extends Collection<E>> T notEmpty(final T argument, final String name) {
+        if (argument == null) {
+            throw new IllegalArgumentException(name + " may not be null");
+        }
+        if (argument.isEmpty()) {
+            throw new IllegalArgumentException(name + " may not be empty");
+        }
+        return argument;
+    }
+
+    public static int positive(final int n, final String name) {
+        if (n <= 0) {
+            throw new IllegalArgumentException(name + " may not be negative or zero");
+        }
+        return n;
+    }
+
+    public static long positive(final long n, final String name) {
+        if (n <= 0) {
+            throw new IllegalArgumentException(name + " may not be negative or zero");
+        }
+        return n;
+    }
+
+    public static int notNegative(final int n, final String name) {
+        if (n < 0) {
+            throw new IllegalArgumentException(name + " may not be negative");
+        }
+        return n;
+    }
+
+    public static long notNegative(final long n, final String name) {
+        if (n < 0) {
+            throw new IllegalArgumentException(name + " may not be negative");
+        }
+        return n;
+    }
+
+}
diff --git a/httpcore-nio/src/test/java/org/apache/http/nio/util/ContentDecoderMock.java b/httpcore/src/main/java/org/apache/http/util/Asserts.java
similarity index 56%
copy from httpcore-nio/src/test/java/org/apache/http/nio/util/ContentDecoderMock.java
copy to httpcore/src/main/java/org/apache/http/util/Asserts.java
index e0400f2..3a383c4 100644
--- a/httpcore-nio/src/test/java/org/apache/http/nio/util/ContentDecoderMock.java
+++ b/httpcore/src/main/java/org/apache/http/util/Asserts.java
@@ -25,40 +25,38 @@
  *
  */
 
-package org.apache.http.nio.util;
+package org.apache.http.util;
 
-import java.io.IOException;
-import java.nio.ByteBuffer;
-import java.nio.channels.ReadableByteChannel;
+public class Asserts {
 
-import org.apache.http.nio.ContentDecoder;
-
-public class ContentDecoderMock implements ContentDecoder {
-
-    private final ReadableByteChannel channel;
-    private boolean completed;
-
-    public ContentDecoderMock(final ReadableByteChannel channel) {
-        super();
-        this.channel = channel;
+    public static void check(final boolean expression, final String message) {
+        if (!expression) {
+            throw new IllegalStateException(message);
+        }
     }
 
-    public int read(final ByteBuffer dst) throws IOException {
-        if (dst == null) {
-            throw new IllegalArgumentException("Byte buffer may not be null");
+    public static void check(final boolean expression, final String message, final Object... args) {
+        if (!expression) {
+            throw new IllegalStateException(String.format(message, args));
         }
-        if (this.completed) {
-            return -1;
+    }
+
+    public static void notNull(final Object object, final String name) {
+        if (object == null) {
+            throw new IllegalStateException(name + " is null");
         }
-        int bytesRead = this.channel.read(dst);
-        if (bytesRead == -1) {
-            this.completed = true;
+    }
+
+    public static void notEmpty(final CharSequence s, final String name) {
+        if (TextUtils.isEmpty(s)) {
+            throw new IllegalStateException(name + " is empty");
         }
-        return bytesRead;
     }
 
-    public boolean isCompleted() {
-        return this.completed;
+    public static void notBlank(final CharSequence s, final String name) {
+        if (TextUtils.isBlank(s)) {
+            throw new IllegalStateException(name + " is blank");
+        }
     }
 
 }
diff --git a/httpcore/src/main/java/org/apache/http/util/ByteArrayBuffer.java b/httpcore/src/main/java/org/apache/http/util/ByteArrayBuffer.java
index e48f775..4da6ecc 100644
--- a/httpcore/src/main/java/org/apache/http/util/ByteArrayBuffer.java
+++ b/httpcore/src/main/java/org/apache/http/util/ByteArrayBuffer.java
@@ -50,16 +50,14 @@ public final class ByteArrayBuffer implements Serializable {
      *
      * @param capacity the capacity
      */
-    public ByteArrayBuffer(int capacity) {
+    public ByteArrayBuffer(final int capacity) {
         super();
-        if (capacity < 0) {
-            throw new IllegalArgumentException("Buffer capacity may not be negative");
-        }
+        Args.notNegative(capacity, "Buffer capacity");
         this.buffer = new byte[capacity];
     }
 
-    private void expand(int newlen) {
-        byte newbuffer[] = new byte[Math.max(this.buffer.length << 1, newlen)];
+    private void expand(final int newlen) {
+        final byte newbuffer[] = new byte[Math.max(this.buffer.length << 1, newlen)];
         System.arraycopy(this.buffer, 0, newbuffer, 0, this.len);
         this.buffer = newbuffer;
     }
@@ -76,7 +74,7 @@ public final class ByteArrayBuffer implements Serializable {
      * range, <code>len</code> is negative, or
      * <code>off</code> + <code>len</code> is out of range.
      */
-    public void append(final byte[] b, int off, int len) {
+    public void append(final byte[] b, final int off, final int len) {
         if (b == null) {
             return;
         }
@@ -87,7 +85,7 @@ public final class ByteArrayBuffer implements Serializable {
         if (len == 0) {
             return;
         }
-        int newlen = this.len + len;
+        final int newlen = this.len + len;
         if (newlen > this.buffer.length) {
             expand(newlen);
         }
@@ -101,8 +99,8 @@ public final class ByteArrayBuffer implements Serializable {
      *
      * @param   b        the byte to be appended.
      */
-    public void append(int b) {
-        int newlen = this.len + 1;
+    public void append(final int b) {
+        final int newlen = this.len + 1;
         if (newlen > this.buffer.length) {
             expand(newlen);
         }
@@ -124,7 +122,7 @@ public final class ByteArrayBuffer implements Serializable {
      * range, <code>len</code> is negative, or
      * <code>off</code> + <code>len</code> is out of range.
      */
-    public void append(final char[] b, int off, int len) {
+    public void append(final char[] b, final int off, final int len) {
         if (b == null) {
             return;
         }
@@ -135,8 +133,8 @@ public final class ByteArrayBuffer implements Serializable {
         if (len == 0) {
             return;
         }
-        int oldlen = this.len;
-        int newlen = oldlen + len;
+        final int oldlen = this.len;
+        final int newlen = oldlen + len;
         if (newlen > this.buffer.length) {
             expand(newlen);
         }
@@ -161,7 +159,7 @@ public final class ByteArrayBuffer implements Serializable {
      * range, <code>len</code> is negative, or
      * <code>off</code> + <code>len</code> is out of range.
      */
-    public void append(final CharArrayBuffer b, int off, int len) {
+    public void append(final CharArrayBuffer b, final int off, final int len) {
         if (b == null) {
             return;
         }
@@ -181,7 +179,7 @@ public final class ByteArrayBuffer implements Serializable {
      * @return byte array
      */
     public byte[] toByteArray() {
-        byte[] b = new byte[this.len];
+        final byte[] b = new byte[this.len];
         if (this.len > 0) {
             System.arraycopy(this.buffer, 0, b, 0, this.len);
         }
@@ -198,7 +196,7 @@ public final class ByteArrayBuffer implements Serializable {
      * @throws     IndexOutOfBoundsException  if <code>index</code> is
      *             negative or greater than or equal to {@link #length()}.
      */
-    public int byteAt(int i) {
+    public int byteAt(final int i) {
         return this.buffer[i];
     }
 
@@ -232,11 +230,11 @@ public final class ByteArrayBuffer implements Serializable {
      *
      * @since 4.1
      */
-    public void ensureCapacity(int required) {
+    public void ensureCapacity(final int required) {
         if (required <= 0) {
             return;
         }
-        int available = this.buffer.length - this.len;
+        final int available = this.buffer.length - this.len;
         if (required > available) {
             expand(this.len + required);
         }
@@ -261,7 +259,7 @@ public final class ByteArrayBuffer implements Serializable {
      *               <code>len</code> argument is greater than the current
      *               capacity of the buffer or less than <code>0</code>.
      */
-    public void setLength(int len) {
+    public void setLength(final int len) {
         if (len < 0 || len > this.buffer.length) {
             throw new IndexOutOfBoundsException("len: "+len+" < 0 or > buffer len: "+this.buffer.length);
         }
@@ -303,18 +301,20 @@ public final class ByteArrayBuffer implements Serializable {
      * the <code>endIndex</code>, <code>-1</code> is returned.
      *
      * @param   b            the byte to search for.
-     * @param   beginIndex   the index to start the search from.
-     * @param   endIndex     the index to finish the search at.
+     * @param   from         the index to start the search from.
+     * @param   to           the index to finish the search at.
      * @return  the index of the first occurrence of the byte in the buffer
      *   within the given bounds, or <code>-1</code> if the byte does
      *   not occur.
      *
      * @since 4.1
      */
-    public int indexOf(byte b, int beginIndex, int endIndex) {
+    public int indexOf(final byte b, final int from, final int to) {
+        int beginIndex = from;
         if (beginIndex < 0) {
             beginIndex = 0;
         }
+        int endIndex = to;
         if (endIndex > this.len) {
             endIndex = this.len;
         }
@@ -341,7 +341,7 @@ public final class ByteArrayBuffer implements Serializable {
      *
      * @since 4.1
      */
-    public int indexOf(byte b) {
+    public int indexOf(final byte b) {
         return indexOf(b, 0, this.len);
     }
 }
diff --git a/httpcore/src/main/java/org/apache/http/util/CharArrayBuffer.java b/httpcore/src/main/java/org/apache/http/util/CharArrayBuffer.java
index a417284..37f3051 100644
--- a/httpcore/src/main/java/org/apache/http/util/CharArrayBuffer.java
+++ b/httpcore/src/main/java/org/apache/http/util/CharArrayBuffer.java
@@ -51,16 +51,14 @@ public final class CharArrayBuffer implements Serializable {
      *
      * @param capacity the capacity
      */
-    public CharArrayBuffer(int capacity) {
+    public CharArrayBuffer(final int capacity) {
         super();
-        if (capacity < 0) {
-            throw new IllegalArgumentException("Buffer capacity may not be negative");
-        }
+        Args.notNegative(capacity, "Buffer capacity");
         this.buffer = new char[capacity];
     }
 
-    private void expand(int newlen) {
-        char newbuffer[] = new char[Math.max(this.buffer.length << 1, newlen)];
+    private void expand(final int newlen) {
+        final char newbuffer[] = new char[Math.max(this.buffer.length << 1, newlen)];
         System.arraycopy(this.buffer, 0, newbuffer, 0, this.len);
         this.buffer = newbuffer;
     }
@@ -77,7 +75,7 @@ public final class CharArrayBuffer implements Serializable {
      * range, <code>len</code> is negative, or
      * <code>off</code> + <code>len</code> is out of range.
      */
-    public void append(final char[] b, int off, int len) {
+    public void append(final char[] b, final int off, final int len) {
         if (b == null) {
             return;
         }
@@ -88,7 +86,7 @@ public final class CharArrayBuffer implements Serializable {
         if (len == 0) {
             return;
         }
-        int newlen = this.len + len;
+        final int newlen = this.len + len;
         if (newlen > this.buffer.length) {
             expand(newlen);
         }
@@ -102,16 +100,14 @@ public final class CharArrayBuffer implements Serializable {
      *
      * @param str    the string.
      */
-    public void append(String str) {
-        if (str == null) {
-            str = "null";
-        }
-        int strlen = str.length();
-        int newlen = this.len + strlen;
+    public void append(final String str) {
+        final String s = str != null ? str : "null";
+        final int strlen = s.length();
+        final int newlen = this.len + strlen;
         if (newlen > this.buffer.length) {
             expand(newlen);
         }
-        str.getChars(0, strlen, this.buffer, this.len);
+        s.getChars(0, strlen, this.buffer, this.len);
         this.len = newlen;
     }
 
@@ -128,7 +124,7 @@ public final class CharArrayBuffer implements Serializable {
      * range, <code>len</code> is negative, or
      * <code>off</code> + <code>len</code> is out of range.
      */
-    public void append(final CharArrayBuffer b, int off, int len) {
+    public void append(final CharArrayBuffer b, final int off, final int len) {
         if (b == null) {
             return;
         }
@@ -155,8 +151,8 @@ public final class CharArrayBuffer implements Serializable {
      *
      * @param   ch        the char to be appended.
      */
-    public void append(char ch) {
-        int newlen = this.len + 1;
+    public void append(final char ch) {
+        final int newlen = this.len + 1;
         if (newlen > this.buffer.length) {
             expand(newlen);
         }
@@ -178,7 +174,7 @@ public final class CharArrayBuffer implements Serializable {
      * range, <code>len</code> is negative, or
      * <code>off</code> + <code>len</code> is out of range.
      */
-    public void append(final byte[] b, int off, int len) {
+    public void append(final byte[] b, final int off, final int len) {
         if (b == null) {
             return;
         }
@@ -189,8 +185,8 @@ public final class CharArrayBuffer implements Serializable {
         if (len == 0) {
             return;
         }
-        int oldlen = this.len;
-        int newlen = oldlen + len;
+        final int oldlen = this.len;
+        final int newlen = oldlen + len;
         if (newlen > this.buffer.length) {
             expand(newlen);
         }
@@ -214,7 +210,7 @@ public final class CharArrayBuffer implements Serializable {
      * range, <code>len</code> is negative, or
      * <code>off</code> + <code>len</code> is out of range.
      */
-    public void append(final ByteArrayBuffer b, int off, int len) {
+    public void append(final ByteArrayBuffer b, final int off, final int len) {
         if (b == null) {
             return;
         }
@@ -245,7 +241,7 @@ public final class CharArrayBuffer implements Serializable {
      * @return char array
      */
     public char[] toCharArray() {
-        char[] b = new char[this.len];
+        final char[] b = new char[this.len];
         if (this.len > 0) {
             System.arraycopy(this.buffer, 0, b, 0, this.len);
         }
@@ -262,7 +258,7 @@ public final class CharArrayBuffer implements Serializable {
      * @throws     IndexOutOfBoundsException  if <code>index</code> is
      *             negative or greater than or equal to {@link #length()}.
      */
-    public char charAt(int i) {
+    public char charAt(final int i) {
         return this.buffer[i];
     }
 
@@ -303,11 +299,11 @@ public final class CharArrayBuffer implements Serializable {
      *
      * @param   required   the minimum required capacity.
      */
-    public void ensureCapacity(int required) {
+    public void ensureCapacity(final int required) {
         if (required <= 0) {
             return;
         }
-        int available = this.buffer.length - this.len;
+        final int available = this.buffer.length - this.len;
         if (required > available) {
             expand(this.len + required);
         }
@@ -323,7 +319,7 @@ public final class CharArrayBuffer implements Serializable {
      *               <code>len</code> argument is greater than the current
      *               capacity of the buffer or less than <code>0</code>.
      */
-    public void setLength(int len) {
+    public void setLength(final int len) {
         if (len < 0 || len > this.buffer.length) {
             throw new IndexOutOfBoundsException("len: "+len+" < 0 or > buffer len: "+this.buffer.length);
         }
@@ -364,17 +360,19 @@ public final class CharArrayBuffer implements Serializable {
      * {@link #length()}. If the <code>beginIndex</code> is greater than
      * the <code>endIndex</code>, <code>-1</code> is returned.
      *
-     * @param   ch          the char to search for.
-     * @param   beginIndex   the index to start the search from.
-     * @param   endIndex   the index to finish the search at.
+     * @param   ch     the char to search for.
+     * @param   from   the index to start the search from.
+     * @param   to     the index to finish the search at.
      * @return  the index of the first occurrence of the character in the buffer
      *   within the given bounds, or <code>-1</code> if the character does
      *   not occur.
      */
-    public int indexOf(int ch, int beginIndex, int endIndex) {
+    public int indexOf(final int ch, final int from, final int to) {
+        int beginIndex = from;
         if (beginIndex < 0) {
             beginIndex = 0;
         }
+        int endIndex = to;
         if (endIndex > this.len) {
             endIndex = this.len;
         }
@@ -399,7 +397,7 @@ public final class CharArrayBuffer implements Serializable {
      * @return  the index of the first occurrence of the character in the
      *   buffer, or <code>-1</code> if the character does not occur.
      */
-    public int indexOf(int ch) {
+    public int indexOf(final int ch) {
         return indexOf(ch, 0, this.len);
     }
 
@@ -417,7 +415,7 @@ public final class CharArrayBuffer implements Serializable {
      *             buffer, or <code>beginIndex</code> is larger than
      *             <code>endIndex</code>.
      */
-    public String substring(int beginIndex, int endIndex) {
+    public String substring(final int beginIndex, final int endIndex) {
         return new String(this.buffer, beginIndex, endIndex - beginIndex);
     }
 
@@ -428,8 +426,8 @@ public final class CharArrayBuffer implements Serializable {
      * non-whitespace character with the index lesser than
      * <code>endIndex</code>.
      *
-     * @param      beginIndex   the beginning index, inclusive.
-     * @param      endIndex     the ending index, exclusive.
+     * @param      from   the beginning index, inclusive.
+     * @param      to     the ending index, exclusive.
      * @return     the specified substring.
      * @exception  IndexOutOfBoundsException  if the
      *             <code>beginIndex</code> is negative, or
@@ -437,7 +435,9 @@ public final class CharArrayBuffer implements Serializable {
      *             buffer, or <code>beginIndex</code> is larger than
      *             <code>endIndex</code>.
      */
-    public String substringTrimmed(int beginIndex, int endIndex) {
+    public String substringTrimmed(final int from, final int to) {
+        int beginIndex = from;
+        int endIndex = to;
         if (beginIndex < 0) {
             throw new IndexOutOfBoundsException("Negative beginIndex: "+beginIndex);
         }
diff --git a/httpcore-contrib/src/main/java/org/apache/http/contrib/compress/RequestAcceptEncoding.java b/httpcore/src/main/java/org/apache/http/util/CharsetUtils.java
similarity index 60%
copy from httpcore-contrib/src/main/java/org/apache/http/contrib/compress/RequestAcceptEncoding.java
copy to httpcore/src/main/java/org/apache/http/util/CharsetUtils.java
index 14b3afd..33546f8 100644
--- a/httpcore-contrib/src/main/java/org/apache/http/contrib/compress/RequestAcceptEncoding.java
+++ b/httpcore/src/main/java/org/apache/http/util/CharsetUtils.java
@@ -25,30 +25,33 @@
  *
  */
 
-package org.apache.http.contrib.compress;
+package org.apache.http.util;
 
-import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.nio.charset.Charset;
+import java.nio.charset.UnsupportedCharsetException;
 
-import org.apache.http.HttpException;
-import org.apache.http.HttpRequest;
-import org.apache.http.HttpRequestInterceptor;
-import org.apache.http.protocol.HttpContext;
+public class CharsetUtils {
 
-/**
- * Client-side interceptor to indicate support for Gzip content compression.
- *
- *
- * @since 4.0
- */
-public class RequestAcceptEncoding implements HttpRequestInterceptor {
-
-    private static final String ACCEPT_ENCODING = "Accept-Encoding";
-    private static final String GZIP_CODEC = "gzip";
+    public static Charset lookup(final String name) {
+        if (name == null) {
+            return null;
+        }
+        try {
+            return Charset.forName(name);
+        } catch (final UnsupportedCharsetException ex) {
+            return null;
+        }
+    }
 
-    public void process(final HttpRequest request, final HttpContext context)
-            throws HttpException, IOException {
-        if (!request.containsHeader(ACCEPT_ENCODING)) {
-            request.addHeader(ACCEPT_ENCODING, GZIP_CODEC);
+    public static Charset get(final String name) throws UnsupportedEncodingException {
+        if (name == null) {
+            return null;
+        }
+        try {
+            return Charset.forName(name);
+        } catch (final UnsupportedCharsetException ex) {
+            throw new UnsupportedEncodingException(name);
         }
     }
 
diff --git a/httpcore/src/main/java/org/apache/http/util/EncodingUtils.java b/httpcore/src/main/java/org/apache/http/util/EncodingUtils.java
index 2eec43b..7ee1130 100644
--- a/httpcore/src/main/java/org/apache/http/util/EncodingUtils.java
+++ b/httpcore/src/main/java/org/apache/http/util/EncodingUtils.java
@@ -51,22 +51,14 @@ public final class EncodingUtils {
      */
     public static String getString(
         final byte[] data,
-        int offset,
-        int length,
-        String charset
-    ) {
-
-        if (data == null) {
-            throw new IllegalArgumentException("Parameter may not be null");
-        }
-
-        if (charset == null || charset.length() == 0) {
-            throw new IllegalArgumentException("charset may not be null or empty");
-        }
-
+        final int offset,
+        final int length,
+        final String charset) {
+        Args.notNull(data, "Input");
+        Args.notEmpty(charset, "Charset");
         try {
             return new String(data, offset, length, charset);
-        } catch (UnsupportedEncodingException e) {
+        } catch (final UnsupportedEncodingException e) {
             return new String(data, offset, length);
         }
     }
@@ -82,9 +74,7 @@ public final class EncodingUtils {
      * @return The result of the conversion.
      */
     public static String getString(final byte[] data, final String charset) {
-        if (data == null) {
-            throw new IllegalArgumentException("Parameter may not be null");
-        }
+        Args.notNull(data, "Input");
         return getString(data, 0, data.length, charset);
     }
 
@@ -97,18 +87,11 @@ public final class EncodingUtils {
      * @return The resulting byte array.
      */
     public static byte[] getBytes(final String data, final String charset) {
-
-        if (data == null) {
-            throw new IllegalArgumentException("data may not be null");
-        }
-
-        if (charset == null || charset.length() == 0) {
-            throw new IllegalArgumentException("charset may not be null or empty");
-        }
-
+        Args.notNull(data, "Input");
+        Args.notEmpty(charset, "Charset");
         try {
             return data.getBytes(charset);
-        } catch (UnsupportedEncodingException e) {
+        } catch (final UnsupportedEncodingException e) {
             return data.getBytes();
         }
     }
@@ -120,15 +103,11 @@ public final class EncodingUtils {
      * @return The string as a byte array.
      */
     public static byte[] getAsciiBytes(final String data) {
-
-        if (data == null) {
-            throw new IllegalArgumentException("Parameter may not be null");
-        }
-
+        Args.notNull(data, "Input");
         try {
             return data.getBytes(Consts.ASCII.name());
-        } catch (UnsupportedEncodingException e) {
-            throw new Error("HttpClient requires ASCII support");
+        } catch (final UnsupportedEncodingException e) {
+            throw new Error("ASCII not supported");
         }
     }
 
@@ -142,16 +121,12 @@ public final class EncodingUtils {
      * @param length the number of bytes to encode
      * @return The string representation of the byte array
      */
-    public static String getAsciiString(final byte[] data, int offset, int length) {
-
-        if (data == null) {
-            throw new IllegalArgumentException("Parameter may not be null");
-        }
-
+    public static String getAsciiString(final byte[] data, final int offset, final int length) {
+        Args.notNull(data, "Input");
         try {
             return new String(data, offset, length, Consts.ASCII.name());
-        } catch (UnsupportedEncodingException e) {
-            throw new Error("HttpClient requires ASCII support");
+        } catch (final UnsupportedEncodingException e) {
+            throw new Error("ASCII not supported");
         }
     }
 
@@ -164,9 +139,7 @@ public final class EncodingUtils {
      * @return The string representation of the byte array
      */
     public static String getAsciiString(final byte[] data) {
-        if (data == null) {
-            throw new IllegalArgumentException("Parameter may not be null");
-        }
+        Args.notNull(data, "Input");
         return getAsciiString(data, 0, data.length);
     }
 
diff --git a/httpcore/src/main/java/org/apache/http/util/EntityUtils.java b/httpcore/src/main/java/org/apache/http/util/EntityUtils.java
index 85bc830..ccadeff 100644
--- a/httpcore/src/main/java/org/apache/http/util/EntityUtils.java
+++ b/httpcore/src/main/java/org/apache/http/util/EntityUtils.java
@@ -37,6 +37,7 @@ import java.nio.charset.UnsupportedCharsetException;
 
 import org.apache.http.HeaderElement;
 import org.apache.http.HttpEntity;
+import org.apache.http.HttpResponse;
 import org.apache.http.NameValuePair;
 import org.apache.http.ParseException;
 import org.apache.http.entity.ContentType;
@@ -56,7 +57,7 @@ public final class EntityUtils {
      * Ensures that the entity content is fully consumed and the content stream, if exists,
      * is closed. The process is done, <i>quietly</i> , without throwing any IOException.
      *
-     * @param entity
+     * @param entity the entity to consume.
      *
      *
      * @since 4.2
@@ -64,7 +65,7 @@ public final class EntityUtils {
     public static void consumeQuietly(final HttpEntity entity) {
         try {
           consume(entity);
-        } catch (IOException ioex) {
+        } catch (final IOException ignore) {
         }
     }
 
@@ -72,7 +73,7 @@ public final class EntityUtils {
      * Ensures that the entity content is fully consumed and the content stream, if exists,
      * is closed.
      *
-     * @param entity
+     * @param entity the entity to consume.
      * @throws IOException if an error occurs reading the input stream
      *
      * @since 4.1
@@ -82,7 +83,7 @@ public final class EntityUtils {
             return;
         }
         if (entity.isStreaming()) {
-            InputStream instream = entity.getContent();
+            final InputStream instream = entity.getContent();
             if (instream != null) {
                 instream.close();
             }
@@ -90,32 +91,47 @@ public final class EntityUtils {
     }
 
     /**
+     * Updates an entity in a response by first consuming an existing entity, then setting the new one.
+     *
+     * @param response the response with an entity to update; must not be null.
+     * @param entity the entity to set in the response.
+     * @throws IOException if an error occurs while reading the input stream on the existing
+     * entity.
+     * @throws IllegalArgumentException if response is null.
+     *
+     * @since 4.3
+     */
+    public static void updateEntity(
+            final HttpResponse response, final HttpEntity entity) throws IOException {
+        Args.notNull(response, "Response");
+        consume(response.getEntity());
+        response.setEntity(entity);
+    }
+
+    /**
      * Read the contents of an entity and return it as a byte array.
      *
-     * @param entity
+     * @param entity the entity to read from=
      * @return byte array containing the entity content. May be null if
      *   {@link HttpEntity#getContent()} is null.
      * @throws IOException if an error occurs reading the input stream
      * @throws IllegalArgumentException if entity is null or if content length > Integer.MAX_VALUE
      */
     public static byte[] toByteArray(final HttpEntity entity) throws IOException {
-        if (entity == null) {
-            throw new IllegalArgumentException("HTTP entity may not be null");
-        }
-        InputStream instream = entity.getContent();
+        Args.notNull(entity, "Entity");
+        final InputStream instream = entity.getContent();
         if (instream == null) {
             return null;
         }
         try {
-            if (entity.getContentLength() > Integer.MAX_VALUE) {
-                throw new IllegalArgumentException("HTTP entity too large to be buffered in memory");
-            }
+            Args.check(entity.getContentLength() <= Integer.MAX_VALUE,
+                    "HTTP entity too large to be buffered in memory");
             int i = (int)entity.getContentLength();
             if (i < 0) {
                 i = 4096;
             }
-            ByteArrayBuffer buffer = new ByteArrayBuffer(i);
-            byte[] tmp = new byte[4096];
+            final ByteArrayBuffer buffer = new ByteArrayBuffer(i);
+            final byte[] tmp = new byte[4096];
             int l;
             while((l = instream.read(tmp)) != -1) {
                 buffer.append(tmp, 0, l);
@@ -138,14 +154,12 @@ public final class EntityUtils {
      */
     @Deprecated
     public static String getContentCharSet(final HttpEntity entity) throws ParseException {
-        if (entity == null) {
-            throw new IllegalArgumentException("HTTP entity may not be null");
-        }
+        Args.notNull(entity, "Entity");
         String charset = null;
         if (entity.getContentType() != null) {
-            HeaderElement values[] = entity.getContentType().getElements();
+            final HeaderElement values[] = entity.getContentType().getElements();
             if (values.length > 0) {
-                NameValuePair param = values[0].getParameterByName("charset");
+                final NameValuePair param = values[0].getParameterByName("charset");
                 if (param != null) {
                     charset = param.getValue();
                 }
@@ -168,12 +182,10 @@ public final class EntityUtils {
      */
     @Deprecated
     public static String getContentMimeType(final HttpEntity entity) throws ParseException {
-        if (entity == null) {
-            throw new IllegalArgumentException("HTTP entity may not be null");
-        }
+        Args.notNull(entity, "Entity");
         String mimeType = null;
         if (entity.getContentType() != null) {
-            HeaderElement values[] = entity.getContentType().getElements();
+            final HeaderElement values[] = entity.getContentType().getElements();
             if (values.length > 0) {
                 mimeType = values[0].getName();
             }
@@ -193,27 +205,26 @@ public final class EntityUtils {
      * @throws ParseException if header elements cannot be parsed
      * @throws IllegalArgumentException if entity is null or if content length > Integer.MAX_VALUE
      * @throws IOException if an error occurs reading the input stream
+     * @throws UnsupportedCharsetException Thrown when the named charset is not available in
+     * this instance of the Java virtual machine
      */
     public static String toString(
             final HttpEntity entity, final Charset defaultCharset) throws IOException, ParseException {
-        if (entity == null) {
-            throw new IllegalArgumentException("HTTP entity may not be null");
-        }
-        InputStream instream = entity.getContent();
+        Args.notNull(entity, "Entity");
+        final InputStream instream = entity.getContent();
         if (instream == null) {
             return null;
         }
         try {
-            if (entity.getContentLength() > Integer.MAX_VALUE) {
-                throw new IllegalArgumentException("HTTP entity too large to be buffered in memory");
-            }
+            Args.check(entity.getContentLength() <= Integer.MAX_VALUE,
+                    "HTTP entity too large to be buffered in memory");
             int i = (int)entity.getContentLength();
             if (i < 0) {
                 i = 4096;
             }
             Charset charset = null;
             try {
-                ContentType contentType = ContentType.get(entity);
+                final ContentType contentType = ContentType.get(entity);
                 if (contentType != null) {
                     charset = contentType.getCharset();
                 }
@@ -226,9 +237,9 @@ public final class EntityUtils {
             if (charset == null) {
                 charset = HTTP.DEF_CONTENT_CHARSET;
             }
-            Reader reader = new InputStreamReader(instream, charset);
-            CharArrayBuffer buffer = new CharArrayBuffer(i);
-            char[] tmp = new char[1024];
+            final Reader reader = new InputStreamReader(instream, charset);
+            final CharArrayBuffer buffer = new CharArrayBuffer(i);
+            final char[] tmp = new char[1024];
             int l;
             while((l = reader.read(tmp)) != -1) {
                 buffer.append(tmp, 0, l);
@@ -251,6 +262,8 @@ public final class EntityUtils {
      * @throws ParseException if header elements cannot be parsed
      * @throws IllegalArgumentException if entity is null or if content length > Integer.MAX_VALUE
      * @throws IOException if an error occurs reading the input stream
+     * @throws UnsupportedCharsetException Thrown when the named charset is not available in
+     * this instance of the Java virtual machine
      */
     public static String toString(
             final HttpEntity entity, final String defaultCharset) throws IOException, ParseException {
@@ -262,11 +275,13 @@ public final class EntityUtils {
      * The content is converted using the character set from the entity (if any),
      * failing that, "ISO-8859-1" is used.
      *
-     * @param entity
+     * @param entity the entity to convert to a string; must not be null
      * @return String containing the content.
      * @throws ParseException if header elements cannot be parsed
      * @throws IllegalArgumentException if entity is null or if content length > Integer.MAX_VALUE
      * @throws IOException if an error occurs reading the input stream
+     * @throws UnsupportedCharsetException Thrown when the named charset is not available in
+     * this instance of the Java virtual machine
      */
     public static String toString(final HttpEntity entity)
         throws IOException, ParseException {
diff --git a/httpcore/src/main/java/org/apache/http/util/LangUtils.java b/httpcore/src/main/java/org/apache/http/util/LangUtils.java
index f2f0f38..33732d7 100644
--- a/httpcore/src/main/java/org/apache/http/util/LangUtils.java
+++ b/httpcore/src/main/java/org/apache/http/util/LangUtils.java
@@ -83,11 +83,7 @@ public final class LangUtils {
      */
     public static boolean equals(final Object[] a1, final Object[] a2) {
         if (a1 == null) {
-            if (a2 == null) {
-                return true;
-            } else {
-                return false;
-            }
+            return a2 == null;
         } else {
             if (a2 != null && a1.length == a2.length) {
                 for (int i = 0; i < a1.length; i++) {
diff --git a/httpcore-contrib/src/main/java/org/apache/http/contrib/compress/RequestAcceptEncoding.java b/httpcore/src/main/java/org/apache/http/util/NetUtils.java
similarity index 60%
rename from httpcore-contrib/src/main/java/org/apache/http/contrib/compress/RequestAcceptEncoding.java
rename to httpcore/src/main/java/org/apache/http/util/NetUtils.java
index 14b3afd..6304b16 100644
--- a/httpcore-contrib/src/main/java/org/apache/http/contrib/compress/RequestAcceptEncoding.java
+++ b/httpcore/src/main/java/org/apache/http/util/NetUtils.java
@@ -25,30 +25,29 @@
  *
  */
 
-package org.apache.http.contrib.compress;
+package org.apache.http.util;
 
-import java.io.IOException;
-
-import org.apache.http.HttpException;
-import org.apache.http.HttpRequest;
-import org.apache.http.HttpRequestInterceptor;
-import org.apache.http.protocol.HttpContext;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.SocketAddress;
 
 /**
- * Client-side interceptor to indicate support for Gzip content compression.
- *
- *
- * @since 4.0
+ * @since 4.3
  */
-public class RequestAcceptEncoding implements HttpRequestInterceptor {
-
-    private static final String ACCEPT_ENCODING = "Accept-Encoding";
-    private static final String GZIP_CODEC = "gzip";
+public final class NetUtils {
 
-    public void process(final HttpRequest request, final HttpContext context)
-            throws HttpException, IOException {
-        if (!request.containsHeader(ACCEPT_ENCODING)) {
-            request.addHeader(ACCEPT_ENCODING, GZIP_CODEC);
+    public static void formatAddress(
+            final StringBuilder buffer,
+            final SocketAddress socketAddress) {
+        Args.notNull(buffer, "Buffer");
+        Args.notNull(socketAddress, "Socket address");
+        if (socketAddress instanceof InetSocketAddress) {
+            final InetSocketAddress socketaddr = ((InetSocketAddress) socketAddress);
+            final InetAddress inetaddr = socketaddr.getAddress();
+            buffer.append(inetaddr != null ? inetaddr.getHostAddress() : inetaddr)
+                .append(':').append(socketaddr.getPort());
+        } else {
+            buffer.append(socketAddress);
         }
     }
 
diff --git a/httpcore-nio/src/test/java/org/apache/http/SimpleIOReactorExceptionHandler.java b/httpcore/src/main/java/org/apache/http/util/TextUtils.java
similarity index 70%
rename from httpcore-nio/src/test/java/org/apache/http/SimpleIOReactorExceptionHandler.java
rename to httpcore/src/main/java/org/apache/http/util/TextUtils.java
index e349be5..3960c43 100644
--- a/httpcore-nio/src/test/java/org/apache/http/SimpleIOReactorExceptionHandler.java
+++ b/httpcore/src/main/java/org/apache/http/util/TextUtils.java
@@ -24,24 +24,31 @@
  * <http://www.apache.org/>.
  *
  */
-package org.apache.http;
 
-import java.io.IOException;
+package org.apache.http.util;
 
-import org.apache.http.nio.reactor.IOReactorExceptionHandler;
-
-class SimpleIOReactorExceptionHandler implements IOReactorExceptionHandler {
+/**
+ * @since 4.3
+ */
+public final class TextUtils {
 
-    public boolean handle(final RuntimeException ex) {
-        if (!(ex instanceof OoopsieRuntimeException)) {
-            ex.printStackTrace(System.out);
+    public static boolean isEmpty(final CharSequence s) {
+        if (s == null) {
+            return true;
         }
-        return false;
+        return s.length() == 0;
     }
 
-    public boolean handle(final IOException ex) {
-        ex.printStackTrace(System.out);
-        return false;
+    public static boolean isBlank(final CharSequence s) {
+        if (s == null) {
+            return true;
+        }
+        for (int i = 0; i < s.length(); i++) {
+            if (!Character.isWhitespace(s.charAt(i))) {
+                return false;
+            }
+        }
+        return true;
     }
 
 }
diff --git a/httpcore/src/main/java/org/apache/http/util/VersionInfo.java b/httpcore/src/main/java/org/apache/http/util/VersionInfo.java
index 5e0adcc..e870dbc 100644
--- a/httpcore/src/main/java/org/apache/http/util/VersionInfo.java
+++ b/httpcore/src/main/java/org/apache/http/util/VersionInfo.java
@@ -29,11 +29,10 @@ package org.apache.http.util;
 
 import java.io.IOException;
 import java.io.InputStream;
+import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
 import java.util.Properties;
-import java.util.ArrayList;
-
 
 /**
  * Provides access to version information for HTTP components.
@@ -86,13 +85,9 @@ public class VersionInfo {
      * @param time      the build time, or <code>null</code>
      * @param clsldr    the class loader, or <code>null</code>
      */
-    protected VersionInfo(String pckg, String module,
-                          String release, String time, String clsldr) {
-        if (pckg == null) {
-            throw new IllegalArgumentException
-                ("Package identifier must not be null.");
-        }
-
+    protected VersionInfo(final String pckg, final String module,
+                          final String release, final String time, final String clsldr) {
+        Args.notNull(pckg, "Package identifier");
         infoPackage     = pckg;
         infoModule      = (module  != null) ? module  : UNAVAILABLE;
         infoRelease     = (release != null) ? release : UNAVAILABLE;
@@ -161,7 +156,7 @@ public class VersionInfo {
      */
     @Override
     public String toString() {
-        StringBuilder sb = new StringBuilder
+        final StringBuilder sb = new StringBuilder
             (20 + infoPackage.length() + infoModule.length() +
              infoRelease.length() + infoTimestamp.length() +
              infoClassloader.length());
@@ -171,15 +166,18 @@ public class VersionInfo {
 
         // If version info is missing, a single "UNAVAILABLE" for the module
         // is sufficient. Everything else just clutters the output.
-        if (!UNAVAILABLE.equals(infoRelease))
+        if (!UNAVAILABLE.equals(infoRelease)) {
             sb.append(':').append(infoRelease);
-        if (!UNAVAILABLE.equals(infoTimestamp))
+        }
+        if (!UNAVAILABLE.equals(infoTimestamp)) {
             sb.append(':').append(infoTimestamp);
+        }
 
         sb.append(')');
 
-        if (!UNAVAILABLE.equals(infoClassloader))
+        if (!UNAVAILABLE.equals(infoClassloader)) {
             sb.append('@').append(infoClassloader);
+        }
 
         return sb.toString();
     }
@@ -195,18 +193,15 @@ public class VersionInfo {
      * @return  the version information for all packages found,
      *          never <code>null</code>
      */
-    public final static VersionInfo[] loadVersionInfo(String[] pckgs,
-                                                      ClassLoader clsldr) {
-        if (pckgs == null) {
-            throw new IllegalArgumentException
-                ("Package identifier list must not be null.");
-        }
-
-        List<VersionInfo> vil = new ArrayList<VersionInfo>(pckgs.length);
-        for (int i=0; i<pckgs.length; i++) {
-            VersionInfo vi = loadVersionInfo(pckgs[i], clsldr);
-            if (vi != null)
+    public static VersionInfo[] loadVersionInfo(final String[] pckgs,
+                                                      final ClassLoader clsldr) {
+        Args.notNull(pckgs, "Package identifier array");
+        final List<VersionInfo> vil = new ArrayList<VersionInfo>(pckgs.length);
+        for (final String pckg : pckgs) {
+            final VersionInfo vi = loadVersionInfo(pckg, clsldr);
+            if (vi != null) {
                 vil.add(vi);
+            }
         }
 
         return vil.toArray(new VersionInfo[vil.size()]);
@@ -225,38 +220,34 @@ public class VersionInfo {
      * @return  the version information for the argument package, or
      *          <code>null</code> if not available
      */
-    public final static VersionInfo loadVersionInfo(final String pckg,
-                                                    ClassLoader clsldr) {
-        if (pckg == null) {
-            throw new IllegalArgumentException
-                ("Package identifier must not be null.");
-        }
-
-        if (clsldr == null)
-            clsldr = Thread.currentThread().getContextClassLoader();
+    public static VersionInfo loadVersionInfo(final String pckg,
+                                              final ClassLoader clsldr) {
+        Args.notNull(pckg, "Package identifier");
+        final ClassLoader cl = clsldr != null ? clsldr : Thread.currentThread().getContextClassLoader();
 
         Properties vip = null; // version info properties, if available
         try {
             // org.apache.http      becomes
             // org/apache/http/version.properties
-            InputStream is = clsldr.getResourceAsStream
+            final InputStream is = cl.getResourceAsStream
                 (pckg.replace('.', '/') + "/" + VERSION_PROPERTY_FILE);
             if (is != null) {
                 try {
-                    Properties props = new Properties();
+                    final Properties props = new Properties();
                     props.load(is);
                     vip = props;
                 } finally {
                     is.close();
                 }
             }
-        } catch (IOException ex) {
+        } catch (final IOException ex) {
             // shamelessly munch this exception
         }
 
         VersionInfo result = null;
-        if (vip != null)
-            result = fromMap(pckg, vip, clsldr);
+        if (vip != null) {
+            result = fromMap(pckg, vip, cl);
+        }
 
         return result;
     }
@@ -272,40 +263,62 @@ public class VersionInfo {
      *
      * @return  the version information
      */
-    protected final static VersionInfo fromMap(String pckg, Map<?, ?> info,
-                                               ClassLoader clsldr) {
-        if (pckg == null) {
-            throw new IllegalArgumentException
-                ("Package identifier must not be null.");
-        }
-
+    protected static VersionInfo fromMap(final String pckg, final Map<?, ?> info,
+                                               final ClassLoader clsldr) {
+        Args.notNull(pckg, "Package identifier");
         String module = null;
         String release = null;
         String timestamp = null;
 
         if (info != null) {
             module = (String) info.get(PROPERTY_MODULE);
-            if ((module != null) && (module.length() < 1))
+            if ((module != null) && (module.length() < 1)) {
                 module = null;
+            }
 
             release = (String) info.get(PROPERTY_RELEASE);
             if ((release != null) && ((release.length() < 1) ||
-                                      (release.equals("${pom.version}"))))
+                                      (release.equals("${pom.version}")))) {
                 release = null;
+            }
 
             timestamp = (String) info.get(PROPERTY_TIMESTAMP);
             if ((timestamp != null) &&
                 ((timestamp.length() < 1) ||
                  (timestamp.equals("${mvn.timestamp}")))
-                )
+                ) {
                 timestamp = null;
+            }
         } // if info
 
         String clsldrstr = null;
-        if (clsldr != null)
+        if (clsldr != null) {
             clsldrstr = clsldr.toString();
+        }
 
         return new VersionInfo(pckg, module, release, timestamp, clsldrstr);
     }
 
+    /**
+     * Sets the user agent to {@code "<name>/<release> (Java 1.5 minimum; Java/<java.version>)"}.
+     * <p/>
+     * For example:
+     * <pre>"Apache-HttpClient/4.3 (Java 1.5 minimum; Java/1.6.0_35)"</pre>
+     *
+     * @param name the component name, like "Apache-HttpClient".
+     * @param pkg
+     *            the package for which to load version information, for example "org.apache.http". The package name
+     *            should NOT end with a dot.
+     * @param cls
+     *            the class' class loader to load from, or <code>null</code> for the thread context class loader
+     * @since 4.3
+     */
+    public static String getUserAgent(final String name, final String pkg, final Class<?> cls) {
+        // determine the release version from packaged version info
+        final VersionInfo vi = VersionInfo.loadVersionInfo(pkg, cls.getClassLoader());
+        final String release = (vi != null) ? vi.getRelease() : VersionInfo.UNAVAILABLE;
+        final String javaVersion = System.getProperty("java.version");
+        return name + "/" + release + " (Java 1.5 minimum; Java/" + javaVersion + ")";
+    }
+
 } // class VersionInfo
diff --git a/httpcore/src/main/resources/org/apache/http/version.properties b/httpcore/src/main/resources/org/apache/http/version.properties
index 985bfbe..592fba3 100644
--- a/httpcore/src/main/resources/org/apache/http/version.properties
+++ b/httpcore/src/main/resources/org/apache/http/version.properties
@@ -14,7 +14,7 @@
 # "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.    
+# under the License.
 #
 info.module    = httpcore
 info.release   = ${pom.version}
diff --git a/httpcore/src/site/apt/index.apt b/httpcore/src/site/apt/index.apt
deleted file mode 100644
index f06d39e..0000000
--- a/httpcore/src/site/apt/index.apt
+++ /dev/null
@@ -1,44 +0,0 @@
-~~ ====================================================================
-~~ Licensed to the Apache Software Foundation (ASF) under one
-~~ or more contributor license agreements.  See the NOTICE file
-~~ distributed with this work for additional information
-~~ regarding copyright ownership.  The ASF licenses this file
-~~ to you 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.
-~~ ====================================================================
-~~ 
-~~ This software consists of voluntary contributions made by many
-~~ individuals on behalf of the Apache Software Foundation.  For more
-~~ information on the Apache Software Foundation, please see
-~~ <http://www.apache.org/>.
-
-    ----------
-    HttpComponents HttpCore Base Module
-    ----------
-    ----------
-    ----------
-
-HttpCore (base module)
-
-    This is the base module of HttpCore, which contains its public API and the
-    default implementation based on the classic Java I/O model.
-    The HttpCore API and the default implementation require a Java 1.3
-    compatible runtime and have no dependency on any external libraries.
-
-    {{{./apidocs/index.html}Javadocs}}
-    
-    {{{./xref/index.html}Project sources}}
-    
-    {{{./dependencies.html}Dependencies}}    
-    
-    {{{./issue-tracking.html}Issue Tracking}}    
diff --git a/httpcore/src/site/resources/css/site.css b/httpcore/src/site/resources/css/site.css
deleted file mode 100644
index 017b79d..0000000
--- a/httpcore/src/site/resources/css/site.css
+++ /dev/null
@@ -1 +0,0 @@
- at import url("../../../css/hc-maven.css");
\ No newline at end of file
diff --git a/httpcore/src/site/site.xml b/httpcore/src/site/site.xml
deleted file mode 100644
index 5c9f5d3..0000000
--- a/httpcore/src/site/site.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="ISO-8859-1"?>
-<!--
-   ====================================================================
-   Licensed to the Apache Software Foundation (ASF) under one
-   or more contributor license agreements.  See the NOTICE file
-   distributed with this work for additional information
-   regarding copyright ownership.  The ASF licenses this file
-   to you 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.
-   ====================================================================
-
-   This software consists of voluntary contributions made by many
-   individuals on behalf of the Apache Software Foundation.  For more
-   information on the Apache Software Foundation, please see
-   <http://www.apache.org/>.
- -->
-
-<project name="HttpCore">
-
-  <body>
-    <menu name="HttpCore Overview">
-      <item name="Description" href="../index.html"/>
-      <item name="Examples" href="../examples.html"/>
-    </menu>
-    <menu name="Modules">
-      <item name="HttpCore" href="index.html"/>
-      <item name="HttpCore NIO" href="../httpcore-nio/index.html"/>
-    </menu>
-  </body>
-</project>
diff --git a/httpcore/src/test/java/org/apache/http/TestHttpExceptions.java b/httpcore/src/test/java/org/apache/http/TestHttpExceptions.java
index 4388f77..e5f4867 100644
--- a/httpcore/src/test/java/org/apache/http/TestHttpExceptions.java
+++ b/httpcore/src/test/java/org/apache/http/TestHttpExceptions.java
@@ -38,7 +38,7 @@ public class TestHttpExceptions {
 
     @Test
     public void testConstructor() {
-        Throwable cause = new Exception();
+        final Throwable cause = new Exception();
         new HttpException();
         new HttpException("Oppsie");
         new HttpException("Oppsie", cause);
diff --git a/httpcore/src/test/java/org/apache/http/TestHttpHost.java b/httpcore/src/test/java/org/apache/http/TestHttpHost.java
index 6f42b20..ef7a910 100644
--- a/httpcore/src/test/java/org/apache/http/TestHttpHost.java
+++ b/httpcore/src/test/java/org/apache/http/TestHttpHost.java
@@ -31,6 +31,7 @@ import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.ObjectInputStream;
 import java.io.ObjectOutputStream;
+import java.net.InetAddress;
 
 import org.junit.Assert;
 import org.junit.Test;
@@ -43,38 +44,45 @@ public class TestHttpHost {
 
     @Test
     public void testConstructor() {
-        HttpHost host1 = new HttpHost("somehost");
+        final HttpHost host1 = new HttpHost("somehost");
         Assert.assertEquals("somehost", host1.getHostName());
         Assert.assertEquals(-1, host1.getPort());
         Assert.assertEquals("http", host1.getSchemeName());
-        HttpHost host2 = new HttpHost("somehost", 8080);
+        final HttpHost host2 = new HttpHost("somehost", 8080);
         Assert.assertEquals("somehost", host2.getHostName());
         Assert.assertEquals(8080, host2.getPort());
         Assert.assertEquals("http", host2.getSchemeName());
-        HttpHost host3 = new HttpHost("somehost", -1);
+        final HttpHost host3 = new HttpHost("somehost", -1);
         Assert.assertEquals("somehost", host3.getHostName());
         Assert.assertEquals(-1, host3.getPort());
         Assert.assertEquals("http", host3.getSchemeName());
-        HttpHost host4 = new HttpHost("somehost", 443, "https");
+        final HttpHost host4 = new HttpHost("somehost", 443, "https");
         Assert.assertEquals("somehost", host4.getHostName());
         Assert.assertEquals(443, host4.getPort());
         Assert.assertEquals("https", host4.getSchemeName());
         try {
-            new HttpHost(null, -1, null);
+            new HttpHost((String) null, -1, null);
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
-            //expected
+        } catch (final IllegalArgumentException expected) {
+        }
+        try {
+            new HttpHost((InetAddress) null, -1, null);
+            Assert.fail("IllegalArgumentException should have been thrown");
+        } catch (final IllegalArgumentException expected) {
         }
     }
 
     @Test
-    public void testHashCode() {
-        HttpHost host1 = new HttpHost("somehost", 8080, "http");
-        HttpHost host2 = new HttpHost("somehost", 80, "http");
-        HttpHost host3 = new HttpHost("someotherhost", 8080, "http");
-        HttpHost host4 = new HttpHost("somehost", 80, "http");
-        HttpHost host5 = new HttpHost("SomeHost", 80, "http");
-        HttpHost host6 = new HttpHost("SomeHost", 80, "myhttp");
+    public void testHashCode() throws Exception {
+        final HttpHost host1 = new HttpHost("somehost", 8080, "http");
+        final HttpHost host2 = new HttpHost("somehost", 80, "http");
+        final HttpHost host3 = new HttpHost("someotherhost", 8080, "http");
+        final HttpHost host4 = new HttpHost("somehost", 80, "http");
+        final HttpHost host5 = new HttpHost("SomeHost", 80, "http");
+        final HttpHost host6 = new HttpHost("SomeHost", 80, "myhttp");
+        final HttpHost host7 = new HttpHost(
+                InetAddress.getByAddress(new byte[] {127,0,0,1}), 80, "http");
+        final HttpHost host8 = new HttpHost("127.0.0.1", 80, "http");
 
         Assert.assertTrue(host1.hashCode() == host1.hashCode());
         Assert.assertTrue(host1.hashCode() != host2.hashCode());
@@ -82,16 +90,20 @@ public class TestHttpHost {
         Assert.assertTrue(host2.hashCode() == host4.hashCode());
         Assert.assertTrue(host2.hashCode() == host5.hashCode());
         Assert.assertTrue(host5.hashCode() != host6.hashCode());
+        Assert.assertTrue(host7.hashCode() == host8.hashCode());
     }
 
     @Test
-    public void testEquals() {
-        HttpHost host1 = new HttpHost("somehost", 8080, "http");
-        HttpHost host2 = new HttpHost("somehost", 80, "http");
-        HttpHost host3 = new HttpHost("someotherhost", 8080, "http");
-        HttpHost host4 = new HttpHost("somehost", 80, "http");
-        HttpHost host5 = new HttpHost("SomeHost", 80, "http");
-        HttpHost host6 = new HttpHost("SomeHost", 80, "myhttp");
+    public void testEquals() throws Exception {
+        final HttpHost host1 = new HttpHost("somehost", 8080, "http");
+        final HttpHost host2 = new HttpHost("somehost", 80, "http");
+        final HttpHost host3 = new HttpHost("someotherhost", 8080, "http");
+        final HttpHost host4 = new HttpHost("somehost", 80, "http");
+        final HttpHost host5 = new HttpHost("SomeHost", 80, "http");
+        final HttpHost host6 = new HttpHost("SomeHost", 80, "myhttp");
+        final HttpHost host7 = new HttpHost(
+                InetAddress.getByAddress(new byte[] {127,0,0,1}), 80, "http");
+        final HttpHost host8 = new HttpHost("127.0.0.1", 80, "http");
 
         Assert.assertTrue(host1.equals(host1));
         Assert.assertFalse(host1.equals(host2));
@@ -99,56 +111,60 @@ public class TestHttpHost {
         Assert.assertTrue(host2.equals(host4));
         Assert.assertTrue(host2.equals(host5));
         Assert.assertFalse(host5.equals(host6));
+        Assert.assertTrue(host7.equals(host8));
         Assert.assertFalse(host1.equals(null));
         Assert.assertFalse(host1.equals("http://somehost"));
     }
 
     @Test
-    public void testToString() {
-        HttpHost host1 = new HttpHost("somehost");
+    public void testToString() throws Exception {
+        final HttpHost host1 = new HttpHost("somehost");
         Assert.assertEquals("http://somehost", host1.toString());
-        HttpHost host2 = new HttpHost("somehost", -1);
+        final HttpHost host2 = new HttpHost("somehost", -1);
         Assert.assertEquals("http://somehost", host2.toString());
-        HttpHost host3 = new HttpHost("somehost", -1);
+        final HttpHost host3 = new HttpHost("somehost", -1);
         Assert.assertEquals("http://somehost", host3.toString());
-        HttpHost host4 = new HttpHost("somehost", 8888);
+        final HttpHost host4 = new HttpHost("somehost", 8888);
         Assert.assertEquals("http://somehost:8888", host4.toString());
-        HttpHost host5 = new HttpHost("somehost", -1, "myhttp");
+        final HttpHost host5 = new HttpHost("somehost", -1, "myhttp");
         Assert.assertEquals("myhttp://somehost", host5.toString());
-        HttpHost host6 = new HttpHost("somehost", 80, "myhttp");
+        final HttpHost host6 = new HttpHost("somehost", 80, "myhttp");
         Assert.assertEquals("myhttp://somehost:80", host6.toString());
+        final HttpHost host7 = new HttpHost(
+                InetAddress.getByAddress(new byte[] {127,0,0,1}), 80, "http");
+        Assert.assertEquals("http://127.0.0.1:80", host7.toString());
     }
 
     @Test
     public void testToHostString() {
-        HttpHost host1 = new HttpHost("somehost");
+        final HttpHost host1 = new HttpHost("somehost");
         Assert.assertEquals("somehost", host1.toHostString());
-        HttpHost host2 = new HttpHost("somehost");
+        final HttpHost host2 = new HttpHost("somehost");
         Assert.assertEquals("somehost", host2.toHostString());
-        HttpHost host3 = new HttpHost("somehost", -1);
+        final HttpHost host3 = new HttpHost("somehost", -1);
         Assert.assertEquals("somehost", host3.toHostString());
-        HttpHost host4 = new HttpHost("somehost", 8888);
+        final HttpHost host4 = new HttpHost("somehost", 8888);
         Assert.assertEquals("somehost:8888", host4.toHostString());
     }
 
     @Test
     public void testCloning() throws Exception {
-        HttpHost orig = new HttpHost("somehost", 8080, "https");
-        HttpHost clone = (HttpHost) orig.clone();
+        final HttpHost orig = new HttpHost("somehost", 8080, "https");
+        final HttpHost clone = (HttpHost) orig.clone();
         Assert.assertEquals(orig, clone);
     }
 
     @Test
     public void testSerialization() throws Exception {
-        HttpHost orig = new HttpHost("somehost", 8080, "https");
-        ByteArrayOutputStream outbuffer = new ByteArrayOutputStream();
-        ObjectOutputStream outstream = new ObjectOutputStream(outbuffer);
+        final HttpHost orig = new HttpHost("somehost", 8080, "https");
+        final ByteArrayOutputStream outbuffer = new ByteArrayOutputStream();
+        final ObjectOutputStream outstream = new ObjectOutputStream(outbuffer);
         outstream.writeObject(orig);
         outstream.close();
-        byte[] raw = outbuffer.toByteArray();
-        ByteArrayInputStream inbuffer = new ByteArrayInputStream(raw);
-        ObjectInputStream instream = new ObjectInputStream(inbuffer);
-        HttpHost clone = (HttpHost) instream.readObject();
+        final byte[] raw = outbuffer.toByteArray();
+        final ByteArrayInputStream inbuffer = new ByteArrayInputStream(raw);
+        final ObjectInputStream instream = new ObjectInputStream(inbuffer);
+        final HttpHost clone = (HttpHost) instream.readObject();
         Assert.assertEquals(orig, clone);
     }
 
diff --git a/httpcore/src/test/java/org/apache/http/TestHttpVersion.java b/httpcore/src/test/java/org/apache/http/TestHttpVersion.java
index 493f5f5..121cbca 100644
--- a/httpcore/src/test/java/org/apache/http/TestHttpVersion.java
+++ b/httpcore/src/test/java/org/apache/http/TestHttpVersion.java
@@ -46,21 +46,21 @@ public class TestHttpVersion {
         try {
             new HttpVersion(-1, -1);
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException e) {
+        } catch (final IllegalArgumentException e) {
             // expected
         }
         try {
             new HttpVersion(0, -1);
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException e) {
+        } catch (final IllegalArgumentException e) {
             // expected
         }
     }
 
     @Test
     public void testHttpVersionEquality() throws Exception {
-        HttpVersion ver1 = new HttpVersion(1, 1);
-        HttpVersion ver2 = new HttpVersion(1, 1);
+        final HttpVersion ver1 = new HttpVersion(1, 1);
+        final HttpVersion ver2 = new HttpVersion(1, 1);
 
         Assert.assertEquals(ver1.hashCode(), ver2.hashCode());
         Assert.assertTrue(ver1.equals(ver1));
@@ -107,22 +107,22 @@ public class TestHttpVersion {
 
     @Test
     public void testCloning() throws Exception {
-        HttpVersion orig = HttpVersion.HTTP_1_1;
-        HttpVersion clone = (HttpVersion) orig.clone();
+        final HttpVersion orig = HttpVersion.HTTP_1_1;
+        final HttpVersion clone = (HttpVersion) orig.clone();
         Assert.assertEquals(orig, clone);
     }
 
     @Test
     public void testSerialization() throws Exception {
-        HttpVersion orig = HttpVersion.HTTP_1_1;
-        ByteArrayOutputStream outbuffer = new ByteArrayOutputStream();
-        ObjectOutputStream outstream = new ObjectOutputStream(outbuffer);
+        final HttpVersion orig = HttpVersion.HTTP_1_1;
+        final ByteArrayOutputStream outbuffer = new ByteArrayOutputStream();
+        final ObjectOutputStream outstream = new ObjectOutputStream(outbuffer);
         outstream.writeObject(orig);
         outstream.close();
-        byte[] raw = outbuffer.toByteArray();
-        ByteArrayInputStream inbuffer = new ByteArrayInputStream(raw);
-        ObjectInputStream instream = new ObjectInputStream(inbuffer);
-        HttpVersion clone = (HttpVersion) instream.readObject();
+        final byte[] raw = outbuffer.toByteArray();
+        final ByteArrayInputStream inbuffer = new ByteArrayInputStream(raw);
+        final ObjectInputStream instream = new ObjectInputStream(inbuffer);
+        final HttpVersion clone = (HttpVersion) instream.readObject();
         Assert.assertEquals(orig, clone);
     }
 
diff --git a/httpcore/src/test/java/org/apache/http/concurrent/TestBasicFuture.java b/httpcore/src/test/java/org/apache/http/concurrent/TestBasicFuture.java
index 8e61166..65dfd23 100644
--- a/httpcore/src/test/java/org/apache/http/concurrent/TestBasicFuture.java
+++ b/httpcore/src/test/java/org/apache/http/concurrent/TestBasicFuture.java
@@ -30,21 +30,20 @@ import java.util.concurrent.ExecutionException;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
 
-import junit.framework.Assert;
-
+import org.junit.Assert;
 import org.junit.Test;
 
 public class TestBasicFuture {
 
     @Test
     public void testCompleted() throws Exception {
-        BasicFutureCallback<Object> callback = new BasicFutureCallback<Object>();
-        BasicFuture<Object> future = new BasicFuture<Object>(callback);
+        final BasicFutureCallback<Object> callback = new BasicFutureCallback<Object>();
+        final BasicFuture<Object> future = new BasicFuture<Object>(callback);
 
         Assert.assertFalse(future.isDone());
 
-        Object result = new Object();
-        Exception boom = new Exception();
+        final Object result = new Object();
+        final Exception boom = new Exception();
         future.completed(result);
         future.failed(boom);
         Assert.assertTrue(callback.isCompleted());
@@ -61,13 +60,13 @@ public class TestBasicFuture {
 
     @Test
     public void testCompletedWithTimeout() throws Exception {
-        BasicFutureCallback<Object> callback = new BasicFutureCallback<Object>();
-        BasicFuture<Object> future = new BasicFuture<Object>(callback);
+        final BasicFutureCallback<Object> callback = new BasicFutureCallback<Object>();
+        final BasicFuture<Object> future = new BasicFuture<Object>(callback);
 
         Assert.assertFalse(future.isDone());
 
-        Object result = new Object();
-        Exception boom = new Exception();
+        final Object result = new Object();
+        final Exception boom = new Exception();
         future.completed(result);
         future.failed(boom);
         Assert.assertTrue(callback.isCompleted());
@@ -83,10 +82,10 @@ public class TestBasicFuture {
 
     @Test
     public void testFailed() throws Exception {
-        BasicFutureCallback<Object> callback = new BasicFutureCallback<Object>();
-        BasicFuture<Object> future = new BasicFuture<Object>(callback);
-        Object result = new Object();
-        Exception boom = new Exception();
+        final BasicFutureCallback<Object> callback = new BasicFutureCallback<Object>();
+        final BasicFuture<Object> future = new BasicFuture<Object>(callback);
+        final Object result = new Object();
+        final Exception boom = new Exception();
         future.failed(boom);
         future.completed(result);
         Assert.assertFalse(callback.isCompleted());
@@ -97,7 +96,7 @@ public class TestBasicFuture {
 
         try {
             future.get();
-        } catch (ExecutionException ex) {
+        } catch (final ExecutionException ex) {
             Assert.assertSame(boom, ex.getCause());
         }
         Assert.assertTrue(future.isDone());
@@ -106,10 +105,10 @@ public class TestBasicFuture {
 
     @Test
     public void testCancelled() throws Exception {
-        BasicFutureCallback<Object> callback = new BasicFutureCallback<Object>();
-        BasicFuture<Object> future = new BasicFuture<Object>(callback);
-        Object result = new Object();
-        Exception boom = new Exception();
+        final BasicFutureCallback<Object> callback = new BasicFutureCallback<Object>();
+        final BasicFuture<Object> future = new BasicFuture<Object>(callback);
+        final Object result = new Object();
+        final Exception boom = new Exception();
         future.cancel(true);
         future.failed(boom);
         future.completed(result);
@@ -129,14 +128,14 @@ public class TestBasicFuture {
         final BasicFuture<Object> future = new BasicFuture<Object>(null);
         final Object result = new Object();
 
-        Thread t = new Thread() {
+        final Thread t = new Thread() {
 
             @Override
             public void run() {
                 try {
                     Thread.sleep(100);
                     future.completed(result);
-                } catch (InterruptedException boom) {
+                } catch (final InterruptedException boom) {
                 }
             }
 
@@ -153,14 +152,14 @@ public class TestBasicFuture {
         final BasicFuture<Object> future = new BasicFuture<Object>(null);
         final Exception boom = new Exception();
 
-        Thread t = new Thread() {
+        final Thread t = new Thread() {
 
             @Override
             public void run() {
                 try {
                     Thread.sleep(100);
                     future.failed(boom);
-                } catch (InterruptedException ex) {
+                } catch (final InterruptedException ex) {
                 }
             }
 
@@ -169,7 +168,7 @@ public class TestBasicFuture {
         t.start();
         try {
             future.get(60, TimeUnit.SECONDS);
-        } catch (ExecutionException ex) {
+        } catch (final ExecutionException ex) {
             Assert.assertSame(boom, ex.getCause());
         }
         Assert.assertTrue(future.isDone());
@@ -180,14 +179,14 @@ public class TestBasicFuture {
     public void testAsyncCancelled() throws Exception {
         final BasicFuture<Object> future = new BasicFuture<Object>(null);
 
-        Thread t = new Thread() {
+        final Thread t = new Thread() {
 
             @Override
             public void run() {
                 try {
                     Thread.sleep(100);
                     future.cancel(true);
-                } catch (InterruptedException ex) {
+                } catch (final InterruptedException ex) {
                 }
             }
 
@@ -204,14 +203,14 @@ public class TestBasicFuture {
         final BasicFuture<Object> future = new BasicFuture<Object>(null);
         final Object result = new Object();
 
-        Thread t = new Thread() {
+        final Thread t = new Thread() {
 
             @Override
             public void run() {
                 try {
                     Thread.sleep(200);
                     future.completed(result);
-                } catch (InterruptedException ex) {
+                } catch (final InterruptedException ex) {
                 }
             }
 
diff --git a/httpcore-nio/src/main/java/org/apache/http/nio/util/HeapByteBufferAllocator.java b/httpcore/src/test/java/org/apache/http/config/TestRegistry.java
similarity index 70%
copy from httpcore-nio/src/main/java/org/apache/http/nio/util/HeapByteBufferAllocator.java
copy to httpcore/src/test/java/org/apache/http/config/TestRegistry.java
index f3638ce..feb8e33 100644
--- a/httpcore-nio/src/main/java/org/apache/http/nio/util/HeapByteBufferAllocator.java
+++ b/httpcore/src/test/java/org/apache/http/config/TestRegistry.java
@@ -24,24 +24,20 @@
  * <http://www.apache.org/>.
  *
  */
+package org.apache.http.config;
 
-package org.apache.http.nio.util;
+import org.junit.Assert;
+import org.junit.Test;
 
-import java.nio.ByteBuffer;
+public class TestRegistry {
 
-import org.apache.http.annotation.Immutable;
-
-/**
- * Allocates {@link ByteBuffer} instances using
- * {@link ByteBuffer#allocate(int)}.
- *
- * @since 4.0
- */
- at Immutable
-public class HeapByteBufferAllocator implements ByteBufferAllocator {
-
-    public ByteBuffer allocate(int size) {
-        return ByteBuffer.allocate(size);
+    @Test
+    public void testCompleted() throws Exception {
+        final Registry<String> reg = RegistryBuilder.<String>create().register("Stuff", "Stuff").build();
+        Assert.assertEquals("Stuff", reg.lookup("Stuff"));
+        Assert.assertEquals("Stuff", reg.lookup("stuff"));
+        Assert.assertEquals(null, reg.lookup("miss"));
+        Assert.assertEquals(null, reg.lookup(null));
     }
 
 }
diff --git a/httpcore/src/test/java/org/apache/http/entity/TestAbstractHttpEntity.java b/httpcore/src/test/java/org/apache/http/entity/TestAbstractHttpEntity.java
index 5de850a..861b59c 100644
--- a/httpcore/src/test/java/org/apache/http/entity/TestAbstractHttpEntity.java
+++ b/httpcore/src/test/java/org/apache/http/entity/TestAbstractHttpEntity.java
@@ -41,7 +41,7 @@ public class TestAbstractHttpEntity {
 
     @Test
     public void testContentType() throws Exception {
-        BasicHttpEntity httpentity = new BasicHttpEntity();
+        final BasicHttpEntity httpentity = new BasicHttpEntity();
         httpentity.setContentType(new BasicHeader(HTTP.CONTENT_TYPE, "blah"));
         Assert.assertEquals(HTTP.CONTENT_TYPE, httpentity.getContentType().getName());
         Assert.assertEquals("blah", httpentity.getContentType().getValue());
@@ -58,7 +58,7 @@ public class TestAbstractHttpEntity {
 
     @Test
     public void testContentEncoding() throws Exception {
-        BasicHttpEntity httpentity = new BasicHttpEntity();
+        final BasicHttpEntity httpentity = new BasicHttpEntity();
         httpentity.setContentEncoding(new BasicHeader(HTTP.CONTENT_ENCODING, "gzip"));
         Assert.assertEquals(HTTP.CONTENT_ENCODING, httpentity.getContentEncoding().getName());
         Assert.assertEquals("gzip", httpentity.getContentEncoding().getValue());
@@ -75,7 +75,7 @@ public class TestAbstractHttpEntity {
 
     @Test
     public void testChunkingFlag() throws Exception {
-        BasicHttpEntity httpentity = new BasicHttpEntity();
+        final BasicHttpEntity httpentity = new BasicHttpEntity();
         Assert.assertFalse(httpentity.isChunked());
         httpentity.setChunked(true);
         Assert.assertTrue(httpentity.isChunked());
diff --git a/httpcore/src/test/java/org/apache/http/entity/TestBasicHttpEntity.java b/httpcore/src/test/java/org/apache/http/entity/TestBasicHttpEntity.java
index c255320..079e42a 100644
--- a/httpcore/src/test/java/org/apache/http/entity/TestBasicHttpEntity.java
+++ b/httpcore/src/test/java/org/apache/http/entity/TestBasicHttpEntity.java
@@ -44,9 +44,9 @@ public class TestBasicHttpEntity {
     @Test
     public void testBasics() throws Exception {
 
-        byte[] bytes = "Message content".getBytes(Consts.ASCII.name());
-        InputStream content = new ByteArrayInputStream(bytes);
-        BasicHttpEntity httpentity = new BasicHttpEntity();
+        final byte[] bytes = "Message content".getBytes(Consts.ASCII.name());
+        final InputStream content = new ByteArrayInputStream(bytes);
+        final BasicHttpEntity httpentity = new BasicHttpEntity();
         httpentity.setContent(content);
         httpentity.setContentLength(bytes.length);
 
@@ -57,13 +57,13 @@ public class TestBasicHttpEntity {
 
     @Test
     public void testContent() throws Exception {
-        byte[] bytes = "Message content".getBytes(Consts.ASCII.name());
-        InputStream content = new ByteArrayInputStream(bytes);
-        BasicHttpEntity httpentity = new BasicHttpEntity();
+        final byte[] bytes = "Message content".getBytes(Consts.ASCII.name());
+        final InputStream content = new ByteArrayInputStream(bytes);
+        final BasicHttpEntity httpentity = new BasicHttpEntity();
         try {
             httpentity.getContent();
             Assert.fail("IllegalStateException should have been thrown");
-        } catch (IllegalStateException ex) {
+        } catch (final IllegalStateException ex) {
             // expected
         }
         httpentity.setContent(content);
@@ -73,21 +73,21 @@ public class TestBasicHttpEntity {
         try {
             httpentity.getContent();
             Assert.fail("IllegalStateException should have been thrown");
-        } catch (IllegalStateException ex) {
+        } catch (final IllegalStateException ex) {
             // expected
         }
     }
 
     @Test
     public void testWriteTo() throws Exception {
-        byte[] bytes = "Message content".getBytes(Consts.ASCII.name());
-        InputStream content = new ByteArrayInputStream(bytes);
-        BasicHttpEntity httpentity = new BasicHttpEntity();
+        final byte[] bytes = "Message content".getBytes(Consts.ASCII.name());
+        final InputStream content = new ByteArrayInputStream(bytes);
+        final BasicHttpEntity httpentity = new BasicHttpEntity();
         httpentity.setContent(content);
 
         ByteArrayOutputStream out = new ByteArrayOutputStream();
         httpentity.writeTo(out);
-        byte[] bytes2 = out.toByteArray();
+        final byte[] bytes2 = out.toByteArray();
         Assert.assertNotNull(bytes2);
         Assert.assertEquals(bytes.length, bytes2.length);
         for (int i = 0; i < bytes.length; i++) {
@@ -98,14 +98,14 @@ public class TestBasicHttpEntity {
         try {
             httpentity.writeTo(out);
             Assert.fail("IllegalStateException should have been thrown");
-        } catch (IllegalStateException ex) {
+        } catch (final IllegalStateException ex) {
             // expected
         }
 
         try {
             httpentity.writeTo(null);
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
             // expected
         }
     }
diff --git a/httpcore/src/test/java/org/apache/http/entity/TestBufferedHttpEntity.java b/httpcore/src/test/java/org/apache/http/entity/TestBufferedHttpEntity.java
index 8ce2eca..5ddeaec 100644
--- a/httpcore/src/test/java/org/apache/http/entity/TestBufferedHttpEntity.java
+++ b/httpcore/src/test/java/org/apache/http/entity/TestBufferedHttpEntity.java
@@ -42,9 +42,9 @@ public class TestBufferedHttpEntity {
 
     @Test
     public void testBufferingEntity() throws Exception {
-        byte[] bytes = "Message content".getBytes(Consts.ASCII.name());
-        InputStreamEntity httpentity = new InputStreamEntity(new ByteArrayInputStream(bytes), -1);
-        BufferedHttpEntity bufentity = new BufferedHttpEntity(httpentity);
+        final byte[] bytes = "Message content".getBytes(Consts.ASCII.name());
+        final InputStreamEntity httpentity = new InputStreamEntity(new ByteArrayInputStream(bytes), -1);
+        final BufferedHttpEntity bufentity = new BufferedHttpEntity(httpentity);
         Assert.assertEquals(bytes.length, bufentity.getContentLength());
         Assert.assertTrue(bufentity.isRepeatable());
         Assert.assertFalse(bufentity.isChunked());
@@ -57,10 +57,10 @@ public class TestBufferedHttpEntity {
 
     @Test
     public void testWrappingEntity() throws Exception {
-        byte[] bytes = "Message content".getBytes(Consts.ASCII.name());
-        ByteArrayEntity httpentity = new ByteArrayEntity(bytes);
+        final byte[] bytes = "Message content".getBytes(Consts.ASCII.name());
+        final ByteArrayEntity httpentity = new ByteArrayEntity(bytes);
         httpentity.setChunked(true);
-        BufferedHttpEntity bufentity = new BufferedHttpEntity(httpentity);
+        final BufferedHttpEntity bufentity = new BufferedHttpEntity(httpentity);
         Assert.assertEquals(bytes.length, bufentity.getContentLength());
         Assert.assertTrue(bufentity.isRepeatable());
         Assert.assertTrue(bufentity.isChunked());
@@ -76,16 +76,16 @@ public class TestBufferedHttpEntity {
         try {
             new BufferedHttpEntity(null);
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
             // expected
         }
     }
 
     @Test
     public void testWriteToBuffered() throws Exception {
-        byte[] bytes = "Message content".getBytes(Consts.ASCII.name());
-        InputStreamEntity httpentity = new InputStreamEntity(new ByteArrayInputStream(bytes), -1);
-        BufferedHttpEntity bufentity = new BufferedHttpEntity(httpentity);
+        final byte[] bytes = "Message content".getBytes(Consts.ASCII.name());
+        final InputStreamEntity httpentity = new InputStreamEntity(new ByteArrayInputStream(bytes), -1);
+        final BufferedHttpEntity bufentity = new BufferedHttpEntity(httpentity);
 
         ByteArrayOutputStream out = new ByteArrayOutputStream();
         bufentity.writeTo(out);
@@ -108,16 +108,16 @@ public class TestBufferedHttpEntity {
         try {
             bufentity.writeTo(null);
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
             // expected
         }
     }
 
     @Test
     public void testWriteToWrapped() throws Exception {
-        byte[] bytes = "Message content".getBytes(Consts.ASCII.name());
-        ByteArrayEntity httpentity = new ByteArrayEntity(bytes);
-        BufferedHttpEntity bufentity = new BufferedHttpEntity(httpentity);
+        final byte[] bytes = "Message content".getBytes(Consts.ASCII.name());
+        final ByteArrayEntity httpentity = new ByteArrayEntity(bytes);
+        final BufferedHttpEntity bufentity = new BufferedHttpEntity(httpentity);
 
         ByteArrayOutputStream out = new ByteArrayOutputStream();
         bufentity.writeTo(out);
@@ -140,7 +140,7 @@ public class TestBufferedHttpEntity {
         try {
             bufentity.writeTo(null);
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
             // expected
         }
     }
diff --git a/httpcore/src/test/java/org/apache/http/entity/TestByteArrayEntity.java b/httpcore/src/test/java/org/apache/http/entity/TestByteArrayEntity.java
index c36cb67..da8fecb 100644
--- a/httpcore/src/test/java/org/apache/http/entity/TestByteArrayEntity.java
+++ b/httpcore/src/test/java/org/apache/http/entity/TestByteArrayEntity.java
@@ -41,8 +41,8 @@ public class TestByteArrayEntity {
 
     @Test
     public void testBasics() throws Exception {
-        byte[] bytes = "Message content".getBytes(Consts.ASCII.name());
-        ByteArrayEntity httpentity = new ByteArrayEntity(bytes);
+        final byte[] bytes = "Message content".getBytes(Consts.ASCII.name());
+        final ByteArrayEntity httpentity = new ByteArrayEntity(bytes);
 
         Assert.assertEquals(bytes.length, httpentity.getContentLength());
         Assert.assertNotNull(httpentity.getContent());
@@ -52,8 +52,8 @@ public class TestByteArrayEntity {
 
     @Test
     public void testBasicOffLen() throws Exception {
-        byte[] bytes = "Message content".getBytes(Consts.ASCII.name());
-        ByteArrayEntity httpentity = new ByteArrayEntity(bytes, 8, 7);
+        final byte[] bytes = "Message content".getBytes(Consts.ASCII.name());
+        final ByteArrayEntity httpentity = new ByteArrayEntity(bytes, 8, 7);
 
         Assert.assertEquals(7, httpentity.getContentLength());
         Assert.assertNotNull(httpentity.getContent());
@@ -68,26 +68,26 @@ public class TestByteArrayEntity {
 
     @Test(expected=IndexOutOfBoundsException.class)
     public void testIllegalConstructorBadLen() throws Exception {
-        byte[] bytes = "Message content".getBytes(Consts.ASCII.name());
+        final byte[] bytes = "Message content".getBytes(Consts.ASCII.name());
         new ByteArrayEntity(bytes, 0, bytes.length + 1);
     }
 
     @Test(expected=IndexOutOfBoundsException.class)
     public void testIllegalConstructorBadOff1() throws Exception {
-        byte[] bytes = "Message content".getBytes(Consts.ASCII.name());
+        final byte[] bytes = "Message content".getBytes(Consts.ASCII.name());
         new ByteArrayEntity(bytes, -1, bytes.length);
     }
 
     @Test(expected=IndexOutOfBoundsException.class)
     public void testIllegalConstructorBadOff2() throws Exception {
-        byte[] bytes = "Message content".getBytes(Consts.ASCII.name());
+        final byte[] bytes = "Message content".getBytes(Consts.ASCII.name());
         new ByteArrayEntity(bytes, bytes.length + 1, bytes.length);
     }
 
     @Test
     public void testWriteTo() throws Exception {
-        byte[] bytes = "Message content".getBytes(Consts.ASCII.name());
-        ByteArrayEntity httpentity = new ByteArrayEntity(bytes);
+        final byte[] bytes = "Message content".getBytes(Consts.ASCII.name());
+        final ByteArrayEntity httpentity = new ByteArrayEntity(bytes);
 
         ByteArrayOutputStream out = new ByteArrayOutputStream();
         httpentity.writeTo(out);
@@ -110,17 +110,17 @@ public class TestByteArrayEntity {
         try {
             httpentity.writeTo(null);
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
             // expected
         }
     }
 
     @Test
     public void testWriteToOffLen() throws Exception {
-        byte[] bytes = "Message content".getBytes(Consts.ASCII.name());
-        int off = 8;
-        int len = 7;
-        ByteArrayEntity httpentity = new ByteArrayEntity(bytes, off, len);
+        final byte[] bytes = "Message content".getBytes(Consts.ASCII.name());
+        final int off = 8;
+        final int len = 7;
+        final ByteArrayEntity httpentity = new ByteArrayEntity(bytes, off, len);
 
         ByteArrayOutputStream out = new ByteArrayOutputStream();
         httpentity.writeTo(out);
@@ -143,7 +143,7 @@ public class TestByteArrayEntity {
         try {
             httpentity.writeTo(null);
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
             // expected
         }
     }
diff --git a/httpcore/src/test/java/org/apache/http/entity/TestContentType.java b/httpcore/src/test/java/org/apache/http/entity/TestContentType.java
index 087e5f5..738ae6e 100644
--- a/httpcore/src/test/java/org/apache/http/entity/TestContentType.java
+++ b/httpcore/src/test/java/org/apache/http/entity/TestContentType.java
@@ -27,9 +27,10 @@
 
 package org.apache.http.entity;
 
+import java.nio.charset.Charset;
+
 import org.apache.http.Header;
 import org.apache.http.ParseException;
-import org.apache.http.entity.BasicHttpEntity;
 import org.apache.http.message.BasicHeader;
 import org.junit.Assert;
 import org.junit.Test;
@@ -42,15 +43,39 @@ public class TestContentType {
 
     @Test
     public void testBasis() throws Exception {
+        final ContentType contentType = ContentType.create("text/plain", "US-ASCII");
+        Assert.assertEquals("text/plain", contentType.getMimeType());
+        Assert.assertEquals("US-ASCII", contentType.getCharset().name());
+        Assert.assertEquals("text/plain; charset=US-ASCII", contentType.toString());
+    }
+
+    @Test
+    public void testWithCharset() throws Exception {
+        ContentType contentType = ContentType.create("text/plain", "US-ASCII");
+        Assert.assertEquals("text/plain", contentType.getMimeType());
+        Assert.assertEquals("US-ASCII", contentType.getCharset().name());
+        Assert.assertEquals("text/plain; charset=US-ASCII", contentType.toString());
+        contentType = contentType.withCharset(Charset.forName("UTF-8"));
+        Assert.assertEquals("text/plain", contentType.getMimeType());
+        Assert.assertEquals("UTF-8", contentType.getCharset().name());
+        Assert.assertEquals("text/plain; charset=UTF-8", contentType.toString());
+    }
+
+    @Test
+    public void testWithCharsetString() throws Exception {
         ContentType contentType = ContentType.create("text/plain", "US-ASCII");
         Assert.assertEquals("text/plain", contentType.getMimeType());
         Assert.assertEquals("US-ASCII", contentType.getCharset().name());
         Assert.assertEquals("text/plain; charset=US-ASCII", contentType.toString());
+        contentType = contentType.withCharset("UTF-8");
+        Assert.assertEquals("text/plain", contentType.getMimeType());
+        Assert.assertEquals("UTF-8", contentType.getCharset().name());
+        Assert.assertEquals("text/plain; charset=UTF-8", contentType.toString());
     }
 
     @Test
     public void testLowCaseText() throws Exception {
-        ContentType contentType = ContentType.create("Text/Plain", "ascii");
+        final ContentType contentType = ContentType.create("Text/Plain", "ascii");
         Assert.assertEquals("text/plain", contentType.getMimeType());
         Assert.assertEquals("US-ASCII", contentType.getCharset().name());
     }
@@ -60,35 +85,56 @@ public class TestContentType {
         try {
             ContentType.create(null, (String) null);
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
             // expected
         }
         try {
             ContentType.create("  ", (String) null);
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
             // expected
         }
         try {
             ContentType.create("stuff;", (String) null);
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
             // expected
         }
         try {
             ContentType.create("text/plain", ",");
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
             // expected
         }
     }
 
     @Test
     public void testParse() throws Exception {
-        ContentType contentType = ContentType.parse("text/plain; charset=\"ascii\"");
+        final ContentType contentType = ContentType.parse("text/plain; charset=\"ascii\"");
         Assert.assertEquals("text/plain", contentType.getMimeType());
         Assert.assertEquals("US-ASCII", contentType.getCharset().name());
-        Assert.assertEquals("text/plain; charset=US-ASCII", contentType.toString());
+        Assert.assertEquals("text/plain; charset=ascii", contentType.toString());
+    }
+
+    @Test
+    public void testParseMultiparam() throws Exception {
+        final ContentType contentType = ContentType.parse("text/plain; charset=\"ascii\"; " +
+                "p0 ; p1 = \"blah-blah\"  ; p2 = \" yada yada \" ");
+        Assert.assertEquals("text/plain", contentType.getMimeType());
+        Assert.assertEquals("US-ASCII", contentType.getCharset().name());
+        Assert.assertEquals("text/plain; charset=ascii; p0; p1=blah-blah; p2=\" yada yada \"",
+                contentType.toString());
+        Assert.assertEquals(null, contentType.getParameter("p0"));
+        Assert.assertEquals("blah-blah", contentType.getParameter("p1"));
+        Assert.assertEquals(" yada yada ", contentType.getParameter("p2"));
+        Assert.assertEquals(null, contentType.getParameter("p3"));
+    }
+
+    @Test
+    public void testParseEmptyCharset() throws Exception {
+        final ContentType contentType = ContentType.parse("text/plain; charset=\" \"");
+        Assert.assertEquals("text/plain", contentType.getMimeType());
+        Assert.assertEquals(null, contentType.getCharset());
     }
 
     @Test
@@ -96,13 +142,13 @@ public class TestContentType {
         try {
             ContentType.parse(null);
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
             // expected
         }
         try {
             ContentType.parse(";");
             Assert.fail("ParseException should have been thrown");
-        } catch (ParseException ex) {
+        } catch (final ParseException ex) {
             // expected
         }
     }
@@ -114,16 +160,16 @@ public class TestContentType {
 
     @Test
     public void testExtractNullContentType() throws Exception {
-        BasicHttpEntity httpentity = new BasicHttpEntity();
+        final BasicHttpEntity httpentity = new BasicHttpEntity();
         httpentity.setContentType((Header)null);
         Assert.assertNull(ContentType.get(httpentity));
     }
 
     @Test
     public void testExtract() throws Exception {
-        BasicHttpEntity httpentity = new BasicHttpEntity();
+        final BasicHttpEntity httpentity = new BasicHttpEntity();
         httpentity.setContentType(new BasicHeader("Content-Type", "text/plain; charset = UTF-8"));
-        ContentType contentType = ContentType.get(httpentity);
+        final ContentType contentType = ContentType.get(httpentity);
         Assert.assertNotNull(contentType);
         Assert.assertEquals("text/plain", contentType.getMimeType());
         Assert.assertEquals("UTF-8", contentType.getCharset().name());
@@ -131,9 +177,9 @@ public class TestContentType {
 
     @Test
     public void testExtractNoCharset() throws Exception {
-        BasicHttpEntity httpentity = new BasicHttpEntity();
+        final BasicHttpEntity httpentity = new BasicHttpEntity();
         httpentity.setContentType(new BasicHeader("Content-Type", "text/plain; param=yadayada"));
-        ContentType contentType = ContentType.get(httpentity);
+        final ContentType contentType = ContentType.get(httpentity);
         Assert.assertNotNull(contentType);
         Assert.assertEquals("text/plain", contentType.getMimeType());
         Assert.assertNull(contentType.getCharset());
diff --git a/httpcore/src/test/java/org/apache/http/entity/TestEntityTemplate.java b/httpcore/src/test/java/org/apache/http/entity/TestEntityTemplate.java
index 39dd2ca..31ab6b8 100644
--- a/httpcore/src/test/java/org/apache/http/entity/TestEntityTemplate.java
+++ b/httpcore/src/test/java/org/apache/http/entity/TestEntityTemplate.java
@@ -45,7 +45,7 @@ public class TestEntityTemplate {
     @Test
     public void testBasics() throws Exception {
 
-        HttpEntity httpentity = new EntityTemplate(new ContentProducer() {
+        final HttpEntity httpentity = new EntityTemplate(new ContentProducer() {
 
             public void writeTo(final OutputStream outstream) throws IOException {
                 outstream.write('a');
@@ -63,14 +63,14 @@ public class TestEntityTemplate {
         try {
             new EntityTemplate(null);
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
             // expected
         }
     }
 
     @Test
     public void testWriteTo() throws Exception {
-        HttpEntity httpentity = new EntityTemplate(new ContentProducer() {
+        final HttpEntity httpentity = new EntityTemplate(new ContentProducer() {
 
             public void writeTo(final OutputStream outstream) throws IOException {
                 outstream.write('a');
@@ -78,32 +78,32 @@ public class TestEntityTemplate {
 
         });
 
-        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        final ByteArrayOutputStream out = new ByteArrayOutputStream();
         httpentity.writeTo(out);
-        byte[] bytes2 = out.toByteArray();
+        final byte[] bytes2 = out.toByteArray();
         Assert.assertNotNull(bytes2);
         Assert.assertEquals(1, bytes2.length);
 
         try {
             httpentity.writeTo(null);
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
             // expected
         }
     }
 
     @Test
     public void testgetContent() throws Exception {
-        HttpEntity httpentity = new EntityTemplate(new ContentProducer() {
+        final HttpEntity httpentity = new EntityTemplate(new ContentProducer() {
 
             public void writeTo(final OutputStream outstream) throws IOException {
                 outstream.write('a');
             }
 
         });
-        InputStream instream = httpentity.getContent();
+        final InputStream instream = httpentity.getContent();
         Assert.assertNotNull(instream);
-        String s = EntityUtils.toString(httpentity);
+        final String s = EntityUtils.toString(httpentity);
         Assert.assertEquals("a", s);
     }
 
diff --git a/httpcore/src/test/java/org/apache/http/entity/TestFileEntity.java b/httpcore/src/test/java/org/apache/http/entity/TestFileEntity.java
index 32f63df..58d9a9e 100644
--- a/httpcore/src/test/java/org/apache/http/entity/TestFileEntity.java
+++ b/httpcore/src/test/java/org/apache/http/entity/TestFileEntity.java
@@ -43,9 +43,9 @@ public class TestFileEntity {
 
     @Test
     public void testBasics() throws Exception {
-        File tmpfile = File.createTempFile("testfile", ".txt");
+        final File tmpfile = File.createTempFile("testfile", ".txt");
         tmpfile.deleteOnExit();
-        FileEntity httpentity = new FileEntity(tmpfile, ContentType.TEXT_PLAIN);
+        final FileEntity httpentity = new FileEntity(tmpfile, ContentType.TEXT_PLAIN);
 
         Assert.assertEquals(tmpfile.length(), httpentity.getContentLength());
         final InputStream content = httpentity.getContent();
@@ -63,28 +63,28 @@ public class TestFileEntity {
         try {
             new FileEntity(null, ContentType.TEXT_PLAIN);
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
             // expected
         }
     }
 
     @Test
     public void testWriteTo() throws Exception {
-        File tmpfile = File.createTempFile("testfile", ".txt");
+        final File tmpfile = File.createTempFile("testfile", ".txt");
         tmpfile.deleteOnExit();
 
-        FileOutputStream outstream = new FileOutputStream(tmpfile);
+        final FileOutputStream outstream = new FileOutputStream(tmpfile);
         outstream.write(0);
         outstream.write(1);
         outstream.write(2);
         outstream.write(3);
         outstream.close();
 
-        FileEntity httpentity = new FileEntity(tmpfile, ContentType.TEXT_PLAIN);
+        final FileEntity httpentity = new FileEntity(tmpfile, ContentType.TEXT_PLAIN);
 
-        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        final ByteArrayOutputStream out = new ByteArrayOutputStream();
         httpentity.writeTo(out);
-        byte[] bytes = out.toByteArray();
+        final byte[] bytes = out.toByteArray();
         Assert.assertNotNull(bytes);
         Assert.assertEquals(tmpfile.length(), bytes.length);
         for (int i = 0; i < 4; i++) {
@@ -97,7 +97,7 @@ public class TestFileEntity {
         try {
             httpentity.writeTo(null);
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
             // expected
         }
     }
diff --git a/httpcore/src/test/java/org/apache/http/entity/TestHttpEntityWrapper.java b/httpcore/src/test/java/org/apache/http/entity/TestHttpEntityWrapper.java
index bc1f63c..de8da2c 100644
--- a/httpcore/src/test/java/org/apache/http/entity/TestHttpEntityWrapper.java
+++ b/httpcore/src/test/java/org/apache/http/entity/TestHttpEntityWrapper.java
@@ -43,10 +43,10 @@ public class TestHttpEntityWrapper {
 
     @Test
     public void testBasics() throws Exception {
-        String s = "Message content";
-        StringEntity httpentity = new StringEntity(s, ContentType.TEXT_PLAIN);
+        final String s = "Message content";
+        final StringEntity httpentity = new StringEntity(s, ContentType.TEXT_PLAIN);
         httpentity.setContentEncoding(HTTP.IDENTITY_CODING);
-        HttpEntityWrapper wrapped = new HttpEntityWrapper(httpentity);
+        final HttpEntityWrapper wrapped = new HttpEntityWrapper(httpentity);
 
         Assert.assertEquals(httpentity.getContentLength(), wrapped.getContentLength());
         Assert.assertEquals(httpentity.getContentType(), wrapped.getContentType());
@@ -62,17 +62,17 @@ public class TestHttpEntityWrapper {
         try {
             new HttpEntityWrapper(null);
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
             // expected
         }
     }
 
     @Test
     public void testWriteTo() throws Exception {
-        String s = "Message content";
-        byte[] bytes = s.getBytes(Consts.ISO_8859_1.name());
-        StringEntity httpentity = new StringEntity(s);
-        HttpEntityWrapper wrapped = new HttpEntityWrapper(httpentity);
+        final String s = "Message content";
+        final byte[] bytes = s.getBytes(Consts.ISO_8859_1.name());
+        final StringEntity httpentity = new StringEntity(s);
+        final HttpEntityWrapper wrapped = new HttpEntityWrapper(httpentity);
 
         ByteArrayOutputStream out = new ByteArrayOutputStream();
         wrapped.writeTo(out);
@@ -95,16 +95,16 @@ public class TestHttpEntityWrapper {
         try {
             wrapped.writeTo(null);
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
             // expected
         }
     }
 
     @Test
     public void testConsumeContent() throws Exception {
-        String s = "Message content";
-        StringEntity httpentity = new StringEntity(s);
-        HttpEntityWrapper wrapped = new HttpEntityWrapper(httpentity);
+        final String s = "Message content";
+        final StringEntity httpentity = new StringEntity(s);
+        final HttpEntityWrapper wrapped = new HttpEntityWrapper(httpentity);
         EntityUtils.consume(wrapped);
         EntityUtils.consume(wrapped);
     }
diff --git a/httpcore/src/test/java/org/apache/http/entity/TestInputStreamEntity.java b/httpcore/src/test/java/org/apache/http/entity/TestInputStreamEntity.java
index c42c03d..df7d86f 100644
--- a/httpcore/src/test/java/org/apache/http/entity/TestInputStreamEntity.java
+++ b/httpcore/src/test/java/org/apache/http/entity/TestInputStreamEntity.java
@@ -43,9 +43,9 @@ public class TestInputStreamEntity {
 
     @Test
     public void testBasics() throws Exception {
-        byte[] bytes = "Message content".getBytes(Consts.ISO_8859_1.name());
-        InputStream instream = new ByteArrayInputStream(bytes);
-        InputStreamEntity httpentity = new InputStreamEntity(instream, bytes.length);
+        final byte[] bytes = "Message content".getBytes(Consts.ISO_8859_1.name());
+        final InputStream instream = new ByteArrayInputStream(bytes);
+        final InputStreamEntity httpentity = new InputStreamEntity(instream, bytes.length);
 
         Assert.assertEquals(bytes.length, httpentity.getContentLength());
         Assert.assertEquals(instream, httpentity.getContent());
@@ -54,52 +54,74 @@ public class TestInputStreamEntity {
         Assert.assertTrue(httpentity.isStreaming());
     }
 
-    @Test
+    @Test(expected = IllegalArgumentException.class)
     public void testIllegalConstructor() throws Exception {
-        try {
-            new InputStreamEntity(null, 0);
-            Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
-            // expected
-        }
+        new InputStreamEntity(null, 0);
+    }
+
+    @Test
+    public void testUnknownLengthConstructor() throws Exception {
+        final InputStream instream = new ByteArrayInputStream(new byte[0]);
+        final InputStreamEntity httpentity = new InputStreamEntity(instream);
+        Assert.assertEquals(-1, httpentity.getContentLength());
     }
 
     @Test
     public void testWriteTo() throws Exception {
-        byte[] bytes = "Message content".getBytes(Consts.ISO_8859_1.name());
-        InputStream instream = new ByteArrayInputStream(bytes);
-        InputStreamEntity httpentity = new InputStreamEntity(instream, 7);
+        final String message = "Message content";
+        final byte[] bytes = message.getBytes(Consts.ISO_8859_1.name());
+        final InputStream instream = new ByteArrayInputStream(bytes);
+        final InputStreamEntity httpentity = new InputStreamEntity(instream, bytes.length);
 
-        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        final ByteArrayOutputStream out = new ByteArrayOutputStream();
         httpentity.writeTo(out);
-        byte[] bytes2 = out.toByteArray();
-        Assert.assertNotNull(bytes2);
-        Assert.assertEquals(7, bytes2.length);
-        String s = new String(bytes2, Consts.ISO_8859_1.name());
-        Assert.assertEquals("Message", s);
-
-        instream = new ByteArrayInputStream(bytes);
-        httpentity = new InputStreamEntity(instream, 20);
-        out = new ByteArrayOutputStream();
+        final byte[] writtenBytes = out.toByteArray();
+        Assert.assertNotNull(writtenBytes);
+        Assert.assertEquals(bytes.length, writtenBytes.length);
+
+        final String s = new String(writtenBytes, Consts.ISO_8859_1.name());
+        Assert.assertEquals(message, s);
+    }
+
+    @Test
+    public void testWriteToPartialContent() throws Exception {
+        final String message = "Message content";
+        final byte[] bytes = message.getBytes(Consts.ISO_8859_1.name());
+        final InputStream instream = new ByteArrayInputStream(bytes);
+        final int contentLength = 7;
+        final InputStreamEntity httpentity = new InputStreamEntity(instream, contentLength);
+
+        final ByteArrayOutputStream out = new ByteArrayOutputStream();
         httpentity.writeTo(out);
-        bytes2 = out.toByteArray();
-        Assert.assertNotNull(bytes2);
-        Assert.assertEquals(bytes.length, bytes2.length);
+        final byte[] writtenBytes = out.toByteArray();
+        Assert.assertNotNull(writtenBytes);
+        Assert.assertEquals(contentLength, writtenBytes.length);
+
+        final String s = new String(writtenBytes, Consts.ISO_8859_1.name());
+        Assert.assertEquals(message.substring(0, contentLength), s);
+    }
 
-        instream = new ByteArrayInputStream(bytes);
-        httpentity = new InputStreamEntity(instream, -1);
-        out = new ByteArrayOutputStream();
+    @Test
+    public void testWriteToUnknownLength() throws Exception {
+        final String message = "Message content";
+        final byte[] bytes = message.getBytes(Consts.ISO_8859_1.name());
+        final InputStream instream = new ByteArrayInputStream(bytes);
+        final InputStreamEntity httpentity = new InputStreamEntity(instream);
+
+        final ByteArrayOutputStream out = new ByteArrayOutputStream();
         httpentity.writeTo(out);
-        bytes2 = out.toByteArray();
-        Assert.assertNotNull(bytes2);
-        Assert.assertEquals(bytes.length, bytes2.length);
-
-        try {
-            httpentity.writeTo(null);
-            Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
-            // expected
-        }
+        final byte[] writtenBytes = out.toByteArray();
+        Assert.assertNotNull(writtenBytes);
+        Assert.assertEquals(bytes.length, writtenBytes.length);
+
+        final String s = new String(writtenBytes, Consts.ISO_8859_1.name());
+        Assert.assertEquals(message, s);
     }
 
+    @Test(expected = IllegalArgumentException.class)
+    public void testWriteToNull() throws Exception {
+        final InputStream instream = new ByteArrayInputStream(new byte[0]);
+        final InputStreamEntity httpentity = new InputStreamEntity(instream, 0);
+        httpentity.writeTo(null);
+    }
 }
diff --git a/httpcore/src/test/java/org/apache/http/entity/TestSerializableEntity.java b/httpcore/src/test/java/org/apache/http/entity/TestSerializableEntity.java
index f71f000..9a7c60d 100644
--- a/httpcore/src/test/java/org/apache/http/entity/TestSerializableEntity.java
+++ b/httpcore/src/test/java/org/apache/http/entity/TestSerializableEntity.java
@@ -51,13 +51,13 @@ public class TestSerializableEntity {
 
     @Test
     public void testBasicsBuff() throws Exception {
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        ObjectOutputStream out = new ObjectOutputStream(baos);
+        final ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        final ObjectOutputStream out = new ObjectOutputStream(baos);
 
-        Serializable serializableObj = new SerializableObject();
+        final Serializable serializableObj = new SerializableObject();
         out.writeObject(serializableObj);
 
-        SerializableEntity httpentity = new SerializableEntity(serializableObj, true);
+        final SerializableEntity httpentity = new SerializableEntity(serializableObj, true);
 
         Assert.assertEquals(baos.toByteArray().length, httpentity.getContentLength());
         Assert.assertNotNull(httpentity.getContent());
@@ -67,13 +67,13 @@ public class TestSerializableEntity {
 
     @Test
     public void testBasicsDirect() throws Exception {
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        ObjectOutputStream out = new ObjectOutputStream(baos);
+        final ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        final ObjectOutputStream out = new ObjectOutputStream(baos);
 
-        Serializable serializableObj = new SerializableObject();
+        final Serializable serializableObj = new SerializableObject();
         out.writeObject(serializableObj);
 
-        SerializableEntity httpentity = new SerializableEntity(serializableObj, false);
+        final SerializableEntity httpentity = new SerializableEntity(serializableObj, false);
 
         Assert.assertEquals(-1, httpentity.getContentLength());
         Assert.assertNotNull(httpentity.getContent());
@@ -86,53 +86,53 @@ public class TestSerializableEntity {
         try {
             new SerializableEntity(null, false);
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
             // expected
         }
     }
 
     @Test
     public void testWriteToBuff() throws Exception {
-        Serializable serializableObj = new SerializableObject();
-        SerializableEntity httpentity = new SerializableEntity(serializableObj, true);
+        final Serializable serializableObj = new SerializableObject();
+        final SerializableEntity httpentity = new SerializableEntity(serializableObj, true);
 
-        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        final ByteArrayOutputStream out = new ByteArrayOutputStream();
         httpentity.writeTo(out);
-        byte[] bytes = out.toByteArray();
+        final byte[] bytes = out.toByteArray();
         Assert.assertNotNull(bytes);
-        ObjectInputStream oin = new ObjectInputStream(new ByteArrayInputStream(
+        final ObjectInputStream oin = new ObjectInputStream(new ByteArrayInputStream(
                 bytes));
-        SerializableObject serIn = (SerializableObject) oin.readObject();
+        final SerializableObject serIn = (SerializableObject) oin.readObject();
         Assert.assertEquals(4, serIn.intValue);
         Assert.assertEquals("Hello", serIn.stringValue);
 
         try {
             httpentity.writeTo(null);
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
             // expected
         }
     }
 
     @Test
     public void testWriteToDirect() throws Exception {
-        Serializable serializableObj = new SerializableObject();
-        SerializableEntity httpentity = new SerializableEntity(serializableObj, false);
+        final Serializable serializableObj = new SerializableObject();
+        final SerializableEntity httpentity = new SerializableEntity(serializableObj, false);
 
-        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        final ByteArrayOutputStream out = new ByteArrayOutputStream();
         httpentity.writeTo(out);
-        byte[] bytes = out.toByteArray();
+        final byte[] bytes = out.toByteArray();
         Assert.assertNotNull(bytes);
-        ObjectInputStream oin = new ObjectInputStream(new ByteArrayInputStream(
+        final ObjectInputStream oin = new ObjectInputStream(new ByteArrayInputStream(
                 bytes));
-        SerializableObject serIn = (SerializableObject) oin.readObject();
+        final SerializableObject serIn = (SerializableObject) oin.readObject();
         Assert.assertEquals(4, serIn.intValue);
         Assert.assertEquals("Hello", serIn.stringValue);
 
         try {
             httpentity.writeTo(null);
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
             // expected
         }
     }
diff --git a/httpcore/src/test/java/org/apache/http/entity/TestStringEntity.java b/httpcore/src/test/java/org/apache/http/entity/TestStringEntity.java
index 5c083bf..5eb973a 100644
--- a/httpcore/src/test/java/org/apache/http/entity/TestStringEntity.java
+++ b/httpcore/src/test/java/org/apache/http/entity/TestStringEntity.java
@@ -42,10 +42,10 @@ public class TestStringEntity {
 
     @Test
     public void testBasics() throws Exception {
-        String s = "Message content";
-        StringEntity httpentity = new StringEntity(s, ContentType.TEXT_PLAIN);
+        final String s = "Message content";
+        final StringEntity httpentity = new StringEntity(s, ContentType.TEXT_PLAIN);
 
-        byte[] bytes = s.getBytes(Consts.ISO_8859_1.name());
+        final byte[] bytes = s.getBytes(Consts.ISO_8859_1.name());
         Assert.assertEquals(bytes.length, httpentity.getContentLength());
         Assert.assertNotNull(httpentity.getContent());
         Assert.assertTrue(httpentity.isRepeatable());
@@ -57,14 +57,14 @@ public class TestStringEntity {
         try {
             new StringEntity(null);
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
             // expected
         }
     }
 
     @Test
     public void testDefaultContent() throws Exception {
-        String s = "Message content";
+        final String s = "Message content";
         StringEntity httpentity = new StringEntity(s, ContentType.create("text/csv", "ANSI_X3.4-1968"));
         Assert.assertEquals("text/csv; charset=US-ASCII",
                 httpentity.getContentType().getValue());
@@ -79,11 +79,11 @@ public class TestStringEntity {
                 httpentity.getContentType().getValue());
     }
 
-    private static String constructString(int [] unicodeChars) {
-        StringBuilder buffer = new StringBuilder();
+    private static String constructString(final int [] unicodeChars) {
+        final StringBuilder buffer = new StringBuilder();
         if (unicodeChars != null) {
-            for (int i = 0; i < unicodeChars.length; i++) {
-                buffer.append((char)unicodeChars[i]);
+            for (final int unicodeChar : unicodeChars) {
+                buffer.append((char)unicodeChar);
             }
         }
         return buffer.toString();
@@ -95,7 +95,7 @@ public class TestStringEntity {
 
     @Test
     public void testNullCharset() throws Exception {
-        String s = constructString(SWISS_GERMAN_HELLO);
+        final String s = constructString(SWISS_GERMAN_HELLO);
         StringEntity httpentity = new StringEntity(s, ContentType.create("text/plain", (Charset) null));
         Assert.assertNotNull(httpentity.getContentType());
         Assert.assertEquals("text/plain", httpentity.getContentType().getValue());
@@ -112,9 +112,9 @@ public class TestStringEntity {
 
     @Test
     public void testWriteTo() throws Exception {
-        String s = "Message content";
-        byte[] bytes = s.getBytes(Consts.ISO_8859_1.name());
-        StringEntity httpentity = new StringEntity(s);
+        final String s = "Message content";
+        final byte[] bytes = s.getBytes(Consts.ISO_8859_1.name());
+        final StringEntity httpentity = new StringEntity(s);
 
         ByteArrayOutputStream out = new ByteArrayOutputStream();
         httpentity.writeTo(out);
@@ -137,7 +137,7 @@ public class TestStringEntity {
         try {
             httpentity.writeTo(null);
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
             // expected
         }
     }
diff --git a/httpcore/src/test/java/org/apache/http/impl/SessionInputBufferMock.java b/httpcore/src/test/java/org/apache/http/impl/SessionInputBufferMock.java
index c7910ce..60f09d1 100644
--- a/httpcore/src/test/java/org/apache/http/impl/SessionInputBufferMock.java
+++ b/httpcore/src/test/java/org/apache/http/impl/SessionInputBufferMock.java
@@ -31,90 +31,80 @@ import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.UnsupportedEncodingException;
+import java.nio.charset.Charset;
+import java.nio.charset.CharsetDecoder;
 
-import org.apache.http.impl.io.AbstractSessionInputBuffer;
-import org.apache.http.params.BasicHttpParams;
-import org.apache.http.params.HttpParams;
+import org.apache.http.config.MessageConstraints;
+import org.apache.http.impl.io.HttpTransportMetricsImpl;
+import org.apache.http.impl.io.SessionInputBufferImpl;
 
 /**
  * {@link org.apache.http.io.SessionInputBuffer} mockup implementation.
  */
-public class SessionInputBufferMock extends AbstractSessionInputBuffer {
+public class SessionInputBufferMock extends SessionInputBufferImpl {
 
     public static final int BUFFER_SIZE = 16;
 
     public SessionInputBufferMock(
             final InputStream instream,
-            int buffersize,
-            final HttpParams params) {
-        super();
-        init(instream, buffersize, params);
+            final int buffersize,
+            final MessageConstraints constrains,
+            final CharsetDecoder decoder) {
+        super(new HttpTransportMetricsImpl(), buffersize, -1, constrains, decoder);
+        bind(instream);
     }
 
     public SessionInputBufferMock(
             final InputStream instream,
-            int buffersize) {
-        this(instream, buffersize, new BasicHttpParams());
+            final int buffersize) {
+        this(instream, buffersize, null, null);
     }
 
     public SessionInputBufferMock(
             final byte[] bytes,
-            final HttpParams params) {
-        this(bytes, BUFFER_SIZE, params);
-    }
-
-    public SessionInputBufferMock(
-            final byte[] bytes) {
-        this(bytes, BUFFER_SIZE, new BasicHttpParams());
+            final int buffersize,
+            final MessageConstraints constrains,
+            final CharsetDecoder decoder) {
+        this(new ByteArrayInputStream(bytes), buffersize, constrains, decoder);
     }
 
     public SessionInputBufferMock(
             final byte[] bytes,
-            int buffersize,
-            final HttpParams params) {
-        this(new ByteArrayInputStream(bytes), buffersize, params);
+            final int buffersize,
+            final MessageConstraints constrains) {
+        this(new ByteArrayInputStream(bytes), buffersize, constrains, null);
     }
 
     public SessionInputBufferMock(
             final byte[] bytes,
-            int buffersize) {
-        this(new ByteArrayInputStream(bytes), buffersize, new BasicHttpParams());
+            final int buffersize) {
+        this(new ByteArrayInputStream(bytes), buffersize);
     }
 
     public SessionInputBufferMock(
-            final String s,
-            final String charset,
-            int buffersize,
-            final HttpParams params)
-        throws UnsupportedEncodingException {
-        this(s.getBytes(charset), buffersize, params);
+            final byte[] bytes) {
+        this(bytes, BUFFER_SIZE);
     }
 
     public SessionInputBufferMock(
-            final String s,
-            final String charset,
-            int buffersize)
-        throws UnsupportedEncodingException {
-        this(s.getBytes(charset), buffersize, new BasicHttpParams());
+            final byte[] bytes, final Charset charset) {
+        this(bytes, BUFFER_SIZE, null, charset != null ? charset.newDecoder() : null);
     }
 
     public SessionInputBufferMock(
-            final String s,
-            final String charset,
-            final HttpParams params)
-        throws UnsupportedEncodingException {
-        this(s.getBytes(charset), params);
+            final byte[] bytes,
+            final CharsetDecoder decoder) {
+        this(bytes, BUFFER_SIZE, null, decoder);
     }
 
     public SessionInputBufferMock(
             final String s,
-            final String charset)
-        throws UnsupportedEncodingException {
-        this(s.getBytes(charset), new BasicHttpParams());
-
+            final Charset charset) throws UnsupportedEncodingException {
+        this(s.getBytes(charset.name()), charset);
     }
 
-    public boolean isDataAvailable(int timeout) throws IOException {
+    @Override
+    public boolean isDataAvailable(final int timeout) throws IOException {
         return true;
     }
 
diff --git a/httpcore/src/test/java/org/apache/http/impl/SessionOutputBufferMock.java b/httpcore/src/test/java/org/apache/http/impl/SessionOutputBufferMock.java
index a6949d9..9354c25 100644
--- a/httpcore/src/test/java/org/apache/http/impl/SessionOutputBufferMock.java
+++ b/httpcore/src/test/java/org/apache/http/impl/SessionOutputBufferMock.java
@@ -28,54 +28,55 @@
 package org.apache.http.impl;
 
 import java.io.ByteArrayOutputStream;
-import java.io.OutputStream;
+import java.nio.charset.Charset;
+import java.nio.charset.CharsetEncoder;
 
-import org.apache.http.impl.io.AbstractSessionOutputBuffer;
-import org.apache.http.params.BasicHttpParams;
-import org.apache.http.params.HttpParams;
+import org.apache.http.impl.io.HttpTransportMetricsImpl;
+import org.apache.http.impl.io.SessionOutputBufferImpl;
 
 /**
  * {@link org.apache.http.io.SessionOutputBuffer} mockup implementation.
  *
  */
-public class SessionOutputBufferMock extends AbstractSessionOutputBuffer {
+public class SessionOutputBufferMock extends SessionOutputBufferImpl {
 
-    private ByteArrayOutputStream buffer = new ByteArrayOutputStream();
     public static final int BUFFER_SIZE = 16;
 
+    private final ByteArrayOutputStream buffer;
+
     public SessionOutputBufferMock(
-            final OutputStream outstream,
-            int buffersize,
-            final HttpParams params) {
-        super();
-        init(outstream, buffersize, params);
+            final ByteArrayOutputStream buffer,
+            final int buffersize,
+            final int fragementSizeHint,
+            final CharsetEncoder encoder) {
+        super(new HttpTransportMetricsImpl(), buffersize, fragementSizeHint, encoder);
+        bind(buffer);
+        this.buffer = buffer;
     }
 
     public SessionOutputBufferMock(
-            final OutputStream outstream,
-            int buffersize) {
-        this(outstream, buffersize, new BasicHttpParams());
+            final ByteArrayOutputStream buffer,
+            final int buffersize) {
+        this(buffer, buffersize, buffersize, null);
     }
 
     public SessionOutputBufferMock(
-            final ByteArrayOutputStream buffer,
-            final HttpParams params) {
-        this(buffer, BUFFER_SIZE, params);
-        this.buffer = buffer;
+            final CharsetEncoder encoder) {
+        this(new ByteArrayOutputStream(), BUFFER_SIZE, BUFFER_SIZE, encoder);
     }
 
     public SessionOutputBufferMock(
-            final ByteArrayOutputStream buffer) {
-        this(buffer, BUFFER_SIZE, new BasicHttpParams());
-        this.buffer = buffer;
+            final Charset charset) {
+        this(new ByteArrayOutputStream(), BUFFER_SIZE, BUFFER_SIZE,
+                charset != null ? charset.newEncoder() : null);
     }
 
-    public SessionOutputBufferMock(final HttpParams params) {
-        this(new ByteArrayOutputStream(), params);
+    public SessionOutputBufferMock(final ByteArrayOutputStream buffer) {
+        this(buffer, BUFFER_SIZE, BUFFER_SIZE, null);
     }
 
     public SessionOutputBufferMock() {
-        this(new ByteArrayOutputStream(), new BasicHttpParams());
+        this(new ByteArrayOutputStream());
     }
 
     public byte[] getData() {
diff --git a/httpcore/src/test/java/org/apache/http/impl/TestBHttpConnectionBase.java b/httpcore/src/test/java/org/apache/http/impl/TestBHttpConnectionBase.java
new file mode 100644
index 0000000..9117c39
--- /dev/null
+++ b/httpcore/src/test/java/org/apache/http/impl/TestBHttpConnectionBase.java
@@ -0,0 +1,390 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+package org.apache.http.impl;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.Socket;
+import java.net.SocketException;
+import java.net.SocketTimeoutException;
+
+import junit.framework.Assert;
+
+import org.apache.http.Header;
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpResponse;
+import org.apache.http.HttpVersion;
+import org.apache.http.config.MessageConstraints;
+import org.apache.http.impl.entity.LaxContentLengthStrategy;
+import org.apache.http.impl.entity.StrictContentLengthStrategy;
+import org.apache.http.impl.io.ChunkedInputStream;
+import org.apache.http.impl.io.ChunkedOutputStream;
+import org.apache.http.impl.io.ContentLengthInputStream;
+import org.apache.http.impl.io.ContentLengthOutputStream;
+import org.apache.http.impl.io.IdentityInputStream;
+import org.apache.http.impl.io.IdentityOutputStream;
+import org.apache.http.message.BasicHttpResponse;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+
+public class TestBHttpConnectionBase {
+
+    @Mock
+    private Socket socket;
+
+    private BHttpConnectionBase conn;
+
+    @Before
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+        conn = new BHttpConnectionBase(1024, 1024,
+            null, null,
+            MessageConstraints.DEFAULT,
+            LaxContentLengthStrategy.INSTANCE,
+            StrictContentLengthStrategy.INSTANCE);
+    }
+
+    @Test
+    public void testBasics() throws Exception {
+        Assert.assertFalse(conn.isOpen());
+        Assert.assertEquals(-1, conn.getLocalPort());
+        Assert.assertEquals(-1, conn.getRemotePort());
+        Assert.assertEquals(null, conn.getLocalAddress());
+        Assert.assertEquals(null, conn.getRemoteAddress());
+        Assert.assertEquals("[Not bound]", conn.toString());
+    }
+
+    @Test
+    public void testSocketBind() throws Exception {
+        final InetAddress localAddress = InetAddress.getByAddress(new byte[] {127, 0, 0, 1});
+        final int localPort = 8888;
+        final InetAddress remoteAddress = InetAddress.getByAddress(new byte[] {10, 0, 0, 2});
+        final int remotePort = 80;
+        final InetSocketAddress localSockAddress = new InetSocketAddress(localAddress, localPort);
+        final InetSocketAddress remoteSockAddress = new InetSocketAddress(remoteAddress, remotePort);
+        Mockito.when(socket.getLocalSocketAddress()).thenReturn(localSockAddress);
+        Mockito.when(socket.getRemoteSocketAddress()).thenReturn(remoteSockAddress);
+        Mockito.when(socket.getLocalAddress()).thenReturn(localAddress);
+        Mockito.when(socket.getLocalPort()).thenReturn(localPort);
+        Mockito.when(socket.getInetAddress()).thenReturn(remoteAddress);
+        Mockito.when(socket.getPort()).thenReturn(remotePort);
+        conn.bind(socket);
+
+        Assert.assertEquals("127.0.0.1:8888<->10.0.0.2:80", conn.toString());
+        Assert.assertTrue(conn.isOpen());
+        Assert.assertEquals(8888, conn.getLocalPort());
+        Assert.assertEquals(80, conn.getRemotePort());
+        Assert.assertEquals(InetAddress.getByAddress(new byte[] {127, 0, 0, 1}), conn.getLocalAddress());
+        Assert.assertEquals(InetAddress.getByAddress(new byte[] {10, 0, 0, 2}), conn.getRemoteAddress());
+    }
+
+    @Test
+    public void testConnectionClose() throws Exception {
+        final InputStream instream = Mockito.mock(InputStream.class);
+        final OutputStream outstream = Mockito.mock(OutputStream.class);
+
+        Mockito.when(socket.getInputStream()).thenReturn(instream);
+        Mockito.when(socket.getOutputStream()).thenReturn(outstream);
+
+        conn.bind(socket);
+        conn.ensureOpen();
+        conn.getSessionOutputBuffer().write(0);
+
+        Assert.assertTrue(conn.isOpen());
+
+        conn.close();
+
+        Assert.assertFalse(conn.isOpen());
+
+        Mockito.verify(outstream, Mockito.times(1)).write(
+                Mockito.<byte []>any(), Mockito.anyInt(), Mockito.anyInt());
+        Mockito.verify(socket, Mockito.times(1)).shutdownInput();
+        Mockito.verify(socket, Mockito.times(1)).shutdownOutput();
+        Mockito.verify(socket, Mockito.times(1)).close();
+
+        conn.close();
+        Mockito.verify(socket, Mockito.times(1)).close();
+        Mockito.verify(outstream, Mockito.times(1)).write(
+                Mockito.<byte []>any(), Mockito.anyInt(), Mockito.anyInt());
+    }
+
+    @Test
+    public void testConnectionShutdown() throws Exception {
+        final InputStream instream = Mockito.mock(InputStream.class);
+        final OutputStream outstream = Mockito.mock(OutputStream.class);
+        Mockito.when(socket.getInputStream()).thenReturn(instream);
+        Mockito.when(socket.getOutputStream()).thenReturn(outstream);
+
+        conn.bind(socket);
+        conn.ensureOpen();
+        conn.getSessionOutputBuffer().write(0);
+
+        Assert.assertTrue(conn.isOpen());
+
+        conn.shutdown();
+
+        Assert.assertFalse(conn.isOpen());
+
+        Mockito.verify(outstream, Mockito.never()).write(
+                Mockito.<byte []>any(), Mockito.anyInt(), Mockito.anyInt());
+        Mockito.verify(socket, Mockito.never()).shutdownInput();
+        Mockito.verify(socket, Mockito.never()).shutdownOutput();
+        Mockito.verify(socket, Mockito.times(1)).close();
+
+        conn.close();
+        Mockito.verify(socket, Mockito.times(1)).close();
+
+        conn.shutdown();
+        Mockito.verify(socket, Mockito.times(2)).close();
+    }
+
+    @Test
+    public void testPrepareInputLengthDelimited() throws Exception {
+        final HttpResponse message = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
+        message.addHeader("Content-Length", "10");
+        message.addHeader("Content-Type", "stuff");
+        message.addHeader("Content-Encoding", "identity");
+        final HttpEntity entity = conn.prepareInput(message);
+        Assert.assertNotNull(entity);
+        Assert.assertFalse(entity.isChunked());
+        Assert.assertEquals(10, entity.getContentLength());
+        final Header ct = entity.getContentType();
+        Assert.assertNotNull(ct);
+        Assert.assertEquals("stuff", ct.getValue());
+        final Header ce = entity.getContentEncoding();
+        Assert.assertNotNull(ce);
+        Assert.assertEquals("identity", ce.getValue());
+        final InputStream instream = entity.getContent();
+        Assert.assertNotNull(instream);
+        Assert.assertTrue((instream instanceof ContentLengthInputStream));
+    }
+
+    @Test
+    public void testPrepareInputChunked() throws Exception {
+        final HttpResponse message = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
+        message.addHeader("Transfer-Encoding", "chunked");
+        final HttpEntity entity = conn.prepareInput(message);
+        Assert.assertNotNull(entity);
+        Assert.assertTrue(entity.isChunked());
+        Assert.assertEquals(-1, entity.getContentLength());
+        final InputStream instream = entity.getContent();
+        Assert.assertNotNull(instream);
+        Assert.assertTrue((instream instanceof ChunkedInputStream));
+    }
+
+    @Test
+    public void testPrepareInputIdentity() throws Exception {
+        final HttpResponse message = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
+        final HttpEntity entity = conn.prepareInput(message);
+        Assert.assertNotNull(entity);
+        Assert.assertFalse(entity.isChunked());
+        Assert.assertEquals(-1, entity.getContentLength());
+        final InputStream instream = entity.getContent();
+        Assert.assertNotNull(instream);
+        Assert.assertTrue((instream instanceof IdentityInputStream));
+    }
+
+    @Test
+    public void testPrepareOutputLengthDelimited() throws Exception {
+        final HttpResponse message = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
+        message.addHeader("Content-Length", "10");
+        final OutputStream outstream = conn.prepareOutput(message);
+        Assert.assertNotNull(outstream);
+        Assert.assertTrue((outstream instanceof ContentLengthOutputStream));
+    }
+
+    @Test
+    public void testPrepareOutputChunked() throws Exception {
+        final HttpResponse message = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
+        message.addHeader("Transfer-Encoding", "chunked");
+        final OutputStream outstream = conn.prepareOutput(message);
+        Assert.assertNotNull(outstream);
+        Assert.assertTrue((outstream instanceof ChunkedOutputStream));
+    }
+
+    @Test
+    public void testPrepareOutputIdentity() throws Exception {
+        final HttpResponse message = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
+        final OutputStream outstream = conn.prepareOutput(message);
+        Assert.assertNotNull(outstream);
+        Assert.assertTrue((outstream instanceof IdentityOutputStream));
+    }
+
+    @Test
+    public void testSetSocketTimeout() throws Exception {
+        conn.bind(socket);
+
+        conn.setSocketTimeout(123);
+
+        Mockito.verify(socket, Mockito.times(1)).setSoTimeout(123);
+    }
+
+    @Test
+    public void testSetSocketTimeoutException() throws Exception {
+        conn.bind(socket);
+
+        Mockito.doThrow(new SocketException()).when(socket).setSoTimeout(Mockito.anyInt());
+
+        conn.setSocketTimeout(123);
+
+        Mockito.verify(socket, Mockito.times(1)).setSoTimeout(123);
+    }
+
+    @Test
+    public void testGetSocketTimeout() throws Exception {
+        Assert.assertEquals(-1, conn.getSocketTimeout());
+
+        Mockito.when(socket.getSoTimeout()).thenReturn(345);
+        conn.bind(socket);
+
+        Assert.assertEquals(345, conn.getSocketTimeout());
+    }
+
+    @Test
+    public void testGetSocketTimeoutException() throws Exception {
+        Assert.assertEquals(-1, conn.getSocketTimeout());
+
+        Mockito.when(socket.getSoTimeout()).thenThrow(new SocketException());
+        conn.bind(socket);
+
+        Assert.assertEquals(-1, conn.getSocketTimeout());
+    }
+
+    @Test
+    public void testAwaitInputInBuffer() throws Exception {
+        final ByteArrayInputStream instream = Mockito.spy(new ByteArrayInputStream(
+                new byte[] {1, 2, 3, 4, 5}));
+        Mockito.when(socket.getInputStream()).thenReturn(instream);
+
+        conn.bind(socket);
+        conn.ensureOpen();
+        conn.getSessionInputBuffer().read();
+
+        Assert.assertTrue(conn.awaitInput(432));
+
+        Mockito.verify(socket, Mockito.never()).setSoTimeout(Mockito.anyInt());
+        Mockito.verify(instream, Mockito.times(1)).read(
+                Mockito.<byte []>any(), Mockito.anyInt(), Mockito.anyInt());
+    }
+
+    @Test
+    public void testAwaitInputInSocket() throws Exception {
+        final ByteArrayInputStream instream = Mockito.spy(new ByteArrayInputStream(
+                new byte[] {1, 2, 3, 4, 5}));
+        Mockito.when(socket.getInputStream()).thenReturn(instream);
+        Mockito.when(socket.getSoTimeout()).thenReturn(345);
+
+        conn.bind(socket);
+        conn.ensureOpen();
+
+        Assert.assertTrue(conn.awaitInput(432));
+
+        Mockito.verify(socket, Mockito.times(1)).setSoTimeout(432);
+        Mockito.verify(socket, Mockito.times(1)).setSoTimeout(345);
+        Mockito.verify(instream, Mockito.times(1)).read(
+                Mockito.<byte []>any(), Mockito.anyInt(), Mockito.anyInt());
+    }
+
+    @Test
+    public void testAwaitInputNoData() throws Exception {
+        final InputStream instream = Mockito.mock(InputStream.class);
+        Mockito.when(socket.getInputStream()).thenReturn(instream);
+        Mockito.when(instream.read(Mockito.<byte []>any(), Mockito.anyInt(), Mockito.anyInt()))
+            .thenReturn(-1);
+
+        conn.bind(socket);
+        conn.ensureOpen();
+
+        Assert.assertFalse(conn.awaitInput(432));
+    }
+
+    @Test
+    public void testStaleWhenClosed() throws Exception {
+        conn.bind(socket);
+        conn.ensureOpen();
+        conn.close();
+        Assert.assertTrue(conn.isStale());
+    }
+
+    @Test
+    public void testNotStaleWhenHasData() throws Exception {
+        final ByteArrayInputStream instream = Mockito.spy(new ByteArrayInputStream(
+                new byte[] {1, 2, 3, 4, 5}));
+        Mockito.when(socket.getInputStream()).thenReturn(instream);
+
+        conn.bind(socket);
+        conn.ensureOpen();
+
+        Assert.assertFalse(conn.isStale());
+    }
+
+    @Test
+    public void testStaleWhenEndOfStream() throws Exception {
+        final InputStream instream = Mockito.mock(InputStream.class);
+        Mockito.when(socket.getInputStream()).thenReturn(instream);
+        Mockito.when(instream.read(Mockito.<byte []>any(), Mockito.anyInt(), Mockito.anyInt()))
+            .thenReturn(-1);
+
+        conn.bind(socket);
+        conn.ensureOpen();
+
+        Assert.assertTrue(conn.isStale());
+    }
+
+    @Test
+    public void testNotStaleWhenTimeout() throws Exception {
+        final InputStream instream = Mockito.mock(InputStream.class);
+        Mockito.when(socket.getInputStream()).thenReturn(instream);
+        Mockito.when(instream.read(Mockito.<byte []>any(), Mockito.anyInt(), Mockito.anyInt()))
+            .thenThrow(new SocketTimeoutException());
+
+        conn.bind(socket);
+        conn.ensureOpen();
+
+        Assert.assertFalse(conn.isStale());
+    }
+
+    @Test
+    public void testStaleWhenIOError() throws Exception {
+        final InputStream instream = Mockito.mock(InputStream.class);
+        Mockito.when(socket.getInputStream()).thenReturn(instream);
+        Mockito.when(instream.read(Mockito.<byte []>any(), Mockito.anyInt(), Mockito.anyInt()))
+            .thenThrow(new SocketException());
+
+        conn.bind(socket);
+        conn.ensureOpen();
+
+        Assert.assertTrue(conn.isStale());
+    }
+
+}
diff --git a/httpcore/src/test/java/org/apache/http/impl/TestBasicRequest.java b/httpcore/src/test/java/org/apache/http/impl/TestBasicRequest.java
index 32d4a69..6945d5a 100644
--- a/httpcore/src/test/java/org/apache/http/impl/TestBasicRequest.java
+++ b/httpcore/src/test/java/org/apache/http/impl/TestBasicRequest.java
@@ -30,7 +30,6 @@ package org.apache.http.impl;
 import org.apache.http.HttpRequest;
 import org.apache.http.HttpVersion;
 import org.apache.http.message.BasicHttpRequest;
-import org.apache.http.params.CoreProtocolPNames;
 import org.junit.Assert;
 import org.junit.Test;
 
@@ -43,30 +42,20 @@ public class TestBasicRequest {
         try {
             new BasicHttpRequest(null, "/stuff");
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
             // expected
         }
         try {
             new BasicHttpRequest("GET", null);
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
             // expected
         }
     }
 
     @Test
     public void testRequestLine() throws Exception {
-        HttpRequest request = new BasicHttpRequest("GET", "/stuff");
-        request.getParams().setParameter(
-                CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_0);
-        Assert.assertEquals("GET", request.getRequestLine().getMethod());
-        Assert.assertEquals("/stuff", request.getRequestLine().getUri());
-        Assert.assertEquals(HttpVersion.HTTP_1_0, request.getRequestLine().getProtocolVersion());
-    }
-
-    @Test
-    public void testRequestLine2() throws Exception {
-        HttpRequest request = new BasicHttpRequest("GET", "/stuff", HttpVersion.HTTP_1_0);
+        final HttpRequest request = new BasicHttpRequest("GET", "/stuff", HttpVersion.HTTP_1_0);
         Assert.assertEquals("GET", request.getRequestLine().getMethod());
         Assert.assertEquals("/stuff", request.getRequestLine().getUri());
         Assert.assertEquals(HttpVersion.HTTP_1_0, request.getRequestLine().getProtocolVersion());
diff --git a/httpcore/src/test/java/org/apache/http/impl/TestDefaultBHttpClientConnection.java b/httpcore/src/test/java/org/apache/http/impl/TestDefaultBHttpClientConnection.java
new file mode 100644
index 0000000..e7c2e3e
--- /dev/null
+++ b/httpcore/src/test/java/org/apache/http/impl/TestDefaultBHttpClientConnection.java
@@ -0,0 +1,168 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+package org.apache.http.impl;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.net.Socket;
+
+import junit.framework.Assert;
+
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpEntityEnclosingRequest;
+import org.apache.http.HttpRequest;
+import org.apache.http.HttpResponse;
+import org.apache.http.HttpVersion;
+import org.apache.http.config.MessageConstraints;
+import org.apache.http.entity.ContentType;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.entity.LaxContentLengthStrategy;
+import org.apache.http.impl.entity.StrictContentLengthStrategy;
+import org.apache.http.impl.io.DefaultHttpRequestWriterFactory;
+import org.apache.http.impl.io.DefaultHttpResponseParserFactory;
+import org.apache.http.message.BasicHttpEntityEnclosingRequest;
+import org.apache.http.message.BasicHttpRequest;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+
+public class TestDefaultBHttpClientConnection {
+
+    @Mock
+    private Socket socket;
+
+    private DefaultBHttpClientConnection conn;
+
+    @Before
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+        conn = new DefaultBHttpClientConnection(1024, 1024,
+            null, null,
+            MessageConstraints.DEFAULT,
+            LaxContentLengthStrategy.INSTANCE,
+            StrictContentLengthStrategy.INSTANCE,
+            DefaultHttpRequestWriterFactory.INSTANCE,
+            DefaultHttpResponseParserFactory.INSTANCE);
+    }
+
+    @Test
+    public void testBasics() throws Exception {
+        Assert.assertFalse(conn.isOpen());
+        Assert.assertEquals("[Not bound]", conn.toString());
+    }
+
+    @Test
+    public void testReadRequestHead() throws Exception {
+        final String s = "HTTP/1.1 200 OK\r\nUser-Agent: test\r\n\r\n";
+        final ByteArrayInputStream instream = new ByteArrayInputStream(s.getBytes("ASCII"));
+        Mockito.when(socket.getInputStream()).thenReturn(instream);
+
+        conn.bind(socket);
+
+        Assert.assertEquals(0, conn.getMetrics().getResponseCount());
+
+        final HttpResponse response = conn.receiveResponseHeader();
+        Assert.assertNotNull(response);
+        Assert.assertEquals(HttpVersion.HTTP_1_1, response.getProtocolVersion());
+        Assert.assertEquals(200, response.getStatusLine().getStatusCode());
+        Assert.assertTrue(response.containsHeader("User-Agent"));
+        Assert.assertEquals(1, conn.getMetrics().getResponseCount());
+    }
+
+    @Test
+    public void testReadRequestEntity() throws Exception {
+        final String s = "HTTP/1.1 200 OK\r\nUser-Agent: test\r\nContent-Length: 3\r\n\r\n123";
+        final ByteArrayInputStream instream = new ByteArrayInputStream(s.getBytes("ASCII"));
+        Mockito.when(socket.getInputStream()).thenReturn(instream);
+
+        conn.bind(socket);
+
+        Assert.assertEquals(0, conn.getMetrics().getResponseCount());
+
+        final HttpResponse response = conn.receiveResponseHeader();
+
+        Assert.assertNotNull(response);
+        Assert.assertEquals(HttpVersion.HTTP_1_1, response.getProtocolVersion());
+        Assert.assertEquals(200, response.getStatusLine().getStatusCode());
+        Assert.assertTrue(response.containsHeader("User-Agent"));
+        Assert.assertEquals(1, conn.getMetrics().getResponseCount());
+
+        conn.receiveResponseEntity(response);
+
+        final HttpEntity entity = response.getEntity();
+        Assert.assertNotNull(entity);
+        Assert.assertEquals(3, entity.getContentLength());
+        Assert.assertEquals(1, conn.getMetrics().getResponseCount());
+    }
+
+    @Test
+    public void testWriteResponseHead() throws Exception {
+        final ByteArrayOutputStream outstream = new ByteArrayOutputStream();
+        Mockito.when(socket.getOutputStream()).thenReturn(outstream);
+
+        conn.bind(socket);
+
+        Assert.assertEquals(0, conn.getMetrics().getRequestCount());
+
+        final HttpRequest request = new BasicHttpRequest("GET", "/stuff", HttpVersion.HTTP_1_1);
+        request.addHeader("User-Agent", "test");
+
+        conn.sendRequestHeader(request);
+        conn.flush();
+
+        Assert.assertEquals(1, conn.getMetrics().getRequestCount());
+        final String s = new String(outstream.toByteArray(), "ASCII");
+        Assert.assertEquals("GET /stuff HTTP/1.1\r\nUser-Agent: test\r\n\r\n", s);
+    }
+
+    @Test
+    public void testWriteResponseEntity() throws Exception {
+        final ByteArrayOutputStream outstream = new ByteArrayOutputStream();
+        Mockito.when(socket.getOutputStream()).thenReturn(outstream);
+
+        conn.bind(socket);
+
+        Assert.assertEquals(0, conn.getMetrics().getRequestCount());
+
+        final HttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST",
+                "/stuff", HttpVersion.HTTP_1_1);
+        request.addHeader("User-Agent", "test");
+        request.addHeader("Content-Length", "3");
+        request.setEntity(new StringEntity("123", ContentType.TEXT_PLAIN));
+
+        conn.sendRequestHeader(request);
+        conn.sendRequestEntity(request);
+        conn.flush();
+
+        Assert.assertEquals(1, conn.getMetrics().getRequestCount());
+        final String s = new String(outstream.toByteArray(), "ASCII");
+        Assert.assertEquals("POST /stuff HTTP/1.1\r\nUser-Agent: test\r\nContent-Length: 3\r\n\r\n123", s);
+    }
+
+}
diff --git a/httpcore/src/test/java/org/apache/http/impl/TestDefaultBHttpServerConnection.java b/httpcore/src/test/java/org/apache/http/impl/TestDefaultBHttpServerConnection.java
new file mode 100644
index 0000000..be7f8d8
--- /dev/null
+++ b/httpcore/src/test/java/org/apache/http/impl/TestDefaultBHttpServerConnection.java
@@ -0,0 +1,188 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+package org.apache.http.impl;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.net.Socket;
+
+import junit.framework.Assert;
+
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpEntityEnclosingRequest;
+import org.apache.http.HttpRequest;
+import org.apache.http.HttpResponse;
+import org.apache.http.HttpVersion;
+import org.apache.http.config.MessageConstraints;
+import org.apache.http.entity.ContentType;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.entity.LaxContentLengthStrategy;
+import org.apache.http.impl.entity.StrictContentLengthStrategy;
+import org.apache.http.impl.io.DefaultHttpRequestParserFactory;
+import org.apache.http.impl.io.DefaultHttpResponseWriterFactory;
+import org.apache.http.message.BasicHttpResponse;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+
+public class TestDefaultBHttpServerConnection {
+
+    @Mock
+    private Socket socket;
+
+    private DefaultBHttpServerConnection conn;
+
+    @Before
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+        conn = new DefaultBHttpServerConnection(1024, 1024,
+            null, null,
+            MessageConstraints.DEFAULT,
+            LaxContentLengthStrategy.INSTANCE,
+            StrictContentLengthStrategy.INSTANCE,
+            DefaultHttpRequestParserFactory.INSTANCE,
+            DefaultHttpResponseWriterFactory.INSTANCE);
+    }
+
+    @Test
+    public void testBasics() throws Exception {
+        Assert.assertFalse(conn.isOpen());
+        Assert.assertEquals("[Not bound]", conn.toString());
+    }
+
+    @Test
+    public void testReadRequestHead() throws Exception {
+        final String s = "GET / HTTP/1.1\r\nUser-Agent: test\r\n\r\n";
+        final ByteArrayInputStream instream = new ByteArrayInputStream(s.getBytes("ASCII"));
+        Mockito.when(socket.getInputStream()).thenReturn(instream);
+
+        conn.bind(socket);
+
+        Assert.assertEquals(0, conn.getMetrics().getRequestCount());
+
+        final HttpRequest request = conn.receiveRequestHeader();
+        Assert.assertNotNull(request);
+        Assert.assertEquals(HttpVersion.HTTP_1_1, request.getProtocolVersion());
+        Assert.assertEquals("/", request.getRequestLine().getUri());
+        Assert.assertEquals("GET", request.getRequestLine().getMethod());
+        Assert.assertTrue(request.containsHeader("User-Agent"));
+        Assert.assertEquals(1, conn.getMetrics().getRequestCount());
+    }
+
+    @Test
+    public void testReadRequestEntity() throws Exception {
+        final String s = "POST / HTTP/1.1\r\nUser-Agent: test\r\nContent-Length: 3\r\n\r\n123";
+        final ByteArrayInputStream instream = new ByteArrayInputStream(s.getBytes("ASCII"));
+        Mockito.when(socket.getInputStream()).thenReturn(instream);
+
+        conn.bind(socket);
+
+        Assert.assertEquals(0, conn.getMetrics().getRequestCount());
+
+        final HttpEntityEnclosingRequest request = (HttpEntityEnclosingRequest) conn.receiveRequestHeader();
+
+        Assert.assertNotNull(request);
+        Assert.assertEquals(HttpVersion.HTTP_1_1, request.getProtocolVersion());
+        Assert.assertEquals("/", request.getRequestLine().getUri());
+        Assert.assertEquals("POST", request.getRequestLine().getMethod());
+        Assert.assertTrue(request.containsHeader("User-Agent"));
+        Assert.assertNull(request.getEntity());
+        Assert.assertEquals(1, conn.getMetrics().getRequestCount());
+
+        conn.receiveRequestEntity(request);
+
+        final HttpEntity entity = request.getEntity();
+        Assert.assertNotNull(entity);
+        Assert.assertEquals(3, entity.getContentLength());
+        Assert.assertEquals(1, conn.getMetrics().getRequestCount());
+    }
+
+    @Test
+    public void testWriteResponseHead() throws Exception {
+        final ByteArrayOutputStream outstream = new ByteArrayOutputStream();
+        Mockito.when(socket.getOutputStream()).thenReturn(outstream);
+
+        conn.bind(socket);
+
+        Assert.assertEquals(0, conn.getMetrics().getResponseCount());
+
+        final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
+        response.addHeader("User-Agent", "test");
+
+        conn.sendResponseHeader(response);
+        conn.flush();
+
+        Assert.assertEquals(1, conn.getMetrics().getResponseCount());
+        final String s = new String(outstream.toByteArray(), "ASCII");
+        Assert.assertEquals("HTTP/1.1 200 OK\r\nUser-Agent: test\r\n\r\n", s);
+    }
+
+    @Test
+    public void testWriteResponse100Head() throws Exception {
+        final ByteArrayOutputStream outstream = new ByteArrayOutputStream();
+        Mockito.when(socket.getOutputStream()).thenReturn(outstream);
+
+        conn.bind(socket);
+
+        Assert.assertEquals(0, conn.getMetrics().getResponseCount());
+
+        final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 100, "Go on");
+
+        conn.sendResponseHeader(response);
+        conn.flush();
+
+        Assert.assertEquals(0, conn.getMetrics().getResponseCount());
+        final String s = new String(outstream.toByteArray(), "ASCII");
+        Assert.assertEquals("HTTP/1.1 100 Go on\r\n\r\n", s);
+    }
+
+    @Test
+    public void testWriteResponseEntity() throws Exception {
+        final ByteArrayOutputStream outstream = new ByteArrayOutputStream();
+        Mockito.when(socket.getOutputStream()).thenReturn(outstream);
+
+        conn.bind(socket);
+
+        Assert.assertEquals(0, conn.getMetrics().getResponseCount());
+
+        final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
+        response.addHeader("User-Agent", "test");
+        response.addHeader("Content-Length", "3");
+        response.setEntity(new StringEntity("123", ContentType.TEXT_PLAIN));
+
+        conn.sendResponseHeader(response);
+        conn.sendResponseEntity(response);
+        conn.flush();
+
+        Assert.assertEquals(1, conn.getMetrics().getResponseCount());
+        final String s = new String(outstream.toByteArray(), "ASCII");
+        Assert.assertEquals("HTTP/1.1 200 OK\r\nUser-Agent: test\r\nContent-Length: 3\r\n\r\n123", s);
+    }
+
+}
diff --git a/httpcore/src/test/java/org/apache/http/impl/TestDefaultConnectionReuseStrategy.java b/httpcore/src/test/java/org/apache/http/impl/TestDefaultConnectionReuseStrategy.java
index 9a0099a..aad37ab 100644
--- a/httpcore/src/test/java/org/apache/http/impl/TestDefaultConnectionReuseStrategy.java
+++ b/httpcore/src/test/java/org/apache/http/impl/TestDefaultConnectionReuseStrategy.java
@@ -48,7 +48,7 @@ public class TestDefaultConnectionReuseStrategy {
 
     @Before
     public void setUp() {
-        reuseStrategy = new DefaultConnectionReuseStrategy();
+        reuseStrategy = DefaultConnectionReuseStrategy.INSTANCE;
         context = new BasicHttpContext(null);
     }
 
@@ -59,32 +59,32 @@ public class TestDefaultConnectionReuseStrategy {
 
     @Test(expected=IllegalArgumentException.class)
     public void testIllegalContextArg() throws Exception {
-        HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
+        final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
         reuseStrategy.keepAlive(response, null);
     }
 
     @Test
     public void testNoContentLengthResponseHttp1_0() throws Exception {
-        HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_0, 200, "OK");
+        final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_0, 200, "OK");
         Assert.assertFalse(reuseStrategy.keepAlive(response, context));
     }
 
     @Test
     public void testNoContentLengthResponseHttp1_1() throws Exception {
-        HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
+        final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
         Assert.assertFalse(reuseStrategy.keepAlive(response, context));
     }
 
     @Test
     public void testChunkedContent() throws Exception {
-        HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
+        final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
         response.addHeader("Transfer-Encoding", "chunked");
         Assert.assertTrue(reuseStrategy.keepAlive(response, context));
     }
 
     @Test
     public void testIgnoreInvalidKeepAlive() throws Exception {
-        HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_0, 200, "OK");
+        final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_0, 200, "OK");
         response.addHeader("Connection", "keep-alive");
         Assert.assertFalse(reuseStrategy.keepAlive(response, context));
     }
@@ -92,7 +92,7 @@ public class TestDefaultConnectionReuseStrategy {
     @Test
     public void testExplicitClose() throws Exception {
         // Use HTTP 1.1
-        HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
+        final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
         response.addHeader("Transfer-Encoding", "chunked");
         response.addHeader("Connection", "close");
         Assert.assertFalse(reuseStrategy.keepAlive(response, context));
@@ -101,7 +101,7 @@ public class TestDefaultConnectionReuseStrategy {
     @Test
     public void testExplicitKeepAlive() throws Exception {
         // Use HTTP 1.0
-        HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_0, 200, "OK");
+        final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_0, 200, "OK");
         response.addHeader("Content-Length", "10");
         response.addHeader("Connection", "keep-alive");
 
@@ -110,21 +110,21 @@ public class TestDefaultConnectionReuseStrategy {
 
     @Test
     public void testHTTP10Default() throws Exception {
-        HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_0, 200, "OK");
+        final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_0, 200, "OK");
         response.addHeader("Content-Length", "10");
         Assert.assertFalse(reuseStrategy.keepAlive(response, context));
     }
 
     @Test
     public void testHTTP11Default() throws Exception {
-        HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
+        final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
         response.addHeader("Content-Length", "10");
         Assert.assertTrue(reuseStrategy.keepAlive(response, context));
     }
 
     @Test
     public void testFutureHTTP() throws Exception {
-        HttpResponse response = new BasicHttpResponse(new HttpVersion(3, 45), 200, "OK");
+        final HttpResponse response = new BasicHttpResponse(new HttpVersion(3, 45), 200, "OK");
         response.addHeader("Content-Length", "10");
         Assert.assertTrue(reuseStrategy.keepAlive(response, context));
     }
@@ -132,7 +132,7 @@ public class TestDefaultConnectionReuseStrategy {
     @Test
     public void testBrokenConnectionDirective1() throws Exception {
         // Use HTTP 1.0
-        HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_0, 200, "OK");
+        final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_0, 200, "OK");
         response.addHeader("Content-Length", "10");
         response.addHeader("Connection", "keep--alive");
         Assert.assertFalse(reuseStrategy.keepAlive(response, context));
@@ -141,7 +141,7 @@ public class TestDefaultConnectionReuseStrategy {
     @Test
     public void testBrokenConnectionDirective2() throws Exception {
         // Use HTTP 1.0
-        HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_0, 200, "OK");
+        final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_0, 200, "OK");
         response.addHeader("Content-Length", "10");
         response.addHeader("Connection", null);
         Assert.assertFalse(reuseStrategy.keepAlive(response, context));
@@ -150,7 +150,7 @@ public class TestDefaultConnectionReuseStrategy {
     @Test
     public void testConnectionTokens1() throws Exception {
         // Use HTTP 1.1
-        HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
+        final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
         response.addHeader("Transfer-Encoding", "chunked");
         response.addHeader("Connection", "yadda, cLOSe, dumdy");
         Assert.assertFalse(reuseStrategy.keepAlive(response, context));
@@ -159,7 +159,7 @@ public class TestDefaultConnectionReuseStrategy {
     @Test
     public void testConnectionTokens2() throws Exception {
         // Use HTTP 1.1
-        HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
+        final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
         response.addHeader("Transfer-Encoding", "chunked");
         response.addHeader("Connection", "yadda, kEEP-alive, dumdy");
         Assert.assertTrue(reuseStrategy.keepAlive(response, context));
@@ -168,7 +168,7 @@ public class TestDefaultConnectionReuseStrategy {
     @Test
     public void testConnectionTokens3() throws Exception {
         // Use HTTP 1.1
-        HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
+        final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
         response.addHeader("Transfer-Encoding", "chunked");
         response.addHeader("Connection", "yadda, keep-alive, close, dumdy");
         Assert.assertFalse(reuseStrategy.keepAlive(response, context));
@@ -177,7 +177,7 @@ public class TestDefaultConnectionReuseStrategy {
     @Test
     public void testConnectionTokens4() throws Exception {
         // Use HTTP 1.1
-        HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
+        final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
         response.addHeader("Transfer-Encoding", "chunked");
         response.addHeader("Connection", "yadda, close, dumdy");
         response.addHeader("Proxy-Connection", "keep-alive");
@@ -188,7 +188,7 @@ public class TestDefaultConnectionReuseStrategy {
     @Test
     public void testConnectionTokens5() throws Exception {
         // Use HTTP 1.1
-        HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
+        final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
         response.addHeader("Transfer-Encoding", "chunked");
         response.addHeader("Connection", "yadda, dumdy");
         response.addHeader("Proxy-Connection", "close");
@@ -201,7 +201,7 @@ public class TestDefaultConnectionReuseStrategy {
     @Test
     public void testConnectionTokens6() throws Exception {
         // Use HTTP 1.1
-        HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
+        final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
         response.addHeader("Transfer-Encoding", "chunked");
         response.addHeader("Connection", "");
         response.addHeader("Proxy-Connection", "close");
@@ -213,7 +213,7 @@ public class TestDefaultConnectionReuseStrategy {
     @Test
     public void testConnectionTokensInvalid() throws Exception {
         // Use HTTP 1.1
-        HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
+        final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
         response.addHeader("Transfer-Encoding", "chunked");
         response.addHeader("Connection", "keep-alive=true");
         Assert.assertFalse(reuseStrategy.keepAlive(response, context));
@@ -222,7 +222,7 @@ public class TestDefaultConnectionReuseStrategy {
     @Test
     public void testMultipleContentLength() throws Exception {
         // Use HTTP 1.1
-        HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
+        final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
         response.addHeader("Content-Length", "10");
         response.addHeader("Content-Length", "11");
         Assert.assertFalse(reuseStrategy.keepAlive(response, context));
@@ -231,7 +231,7 @@ public class TestDefaultConnectionReuseStrategy {
     @Test
     public void testInvalidContentLength() throws Exception {
         // Use HTTP 1.1
-        HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
+        final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
         response.addHeader("Content-Length", "crap");
         Assert.assertFalse(reuseStrategy.keepAlive(response, context));
     }
@@ -239,7 +239,7 @@ public class TestDefaultConnectionReuseStrategy {
     @Test
     public void testInvalidNegativeContentLength() throws Exception {
         // Use HTTP 1.1
-        HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
+        final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
         response.addHeader("Content-Length", "-10");
         Assert.assertFalse(reuseStrategy.keepAlive(response, context));
     }
@@ -247,7 +247,7 @@ public class TestDefaultConnectionReuseStrategy {
     @Test
     public void testNoContentResponse() throws Exception {
         // Use HTTP 1.1
-        HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 
+        final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1,
                 HttpStatus.SC_NO_CONTENT, "No Content");
         Assert.assertTrue(reuseStrategy.keepAlive(response, context));
     }
@@ -255,7 +255,7 @@ public class TestDefaultConnectionReuseStrategy {
     @Test
     public void testNoContentResponseHttp10() throws Exception {
         // Use HTTP 1.0
-        HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_0, 
+        final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_0,
                 HttpStatus.SC_NO_CONTENT, "No Content");
         Assert.assertFalse(reuseStrategy.keepAlive(response, context));
     }
diff --git a/httpcore/src/test/java/org/apache/http/impl/TestEnglishReasonPhraseCatalog.java b/httpcore/src/test/java/org/apache/http/impl/TestEnglishReasonPhraseCatalog.java
index 9c1eb7e..3dbdc4a 100644
--- a/httpcore/src/test/java/org/apache/http/impl/TestEnglishReasonPhraseCatalog.java
+++ b/httpcore/src/test/java/org/apache/http/impl/TestEnglishReasonPhraseCatalog.java
@@ -43,16 +43,13 @@ public class TestEnglishReasonPhraseCatalog {
 
     @Test
     public void testReasonPhrases() throws IllegalAccessException {
-    Field[] publicFields = HttpStatus.class.getFields();
+    final Field[] publicFields = HttpStatus.class.getFields();
 
     Assert.assertNotNull( publicFields );
 
     Assert.assertTrue( publicFields.length > 0 );
 
-    for (int i = 0; i < publicFields.length; i++)
-    {
-        final Field f = publicFields[i];
-
+    for (final Field f : publicFields) {
         final int modifiers = f.getModifiers();
 
         if ( (f.getType() == int.class)
@@ -75,17 +72,17 @@ public class TestEnglishReasonPhraseCatalog {
         try {
             EnglishReasonPhraseCatalog.INSTANCE.getReason(-1, null);
             Assert.fail("IllegalArgumentException must have been thrown (-1)");
-        } catch (IllegalArgumentException expected) {
+        } catch (final IllegalArgumentException expected) {
         }
         try {
             EnglishReasonPhraseCatalog.INSTANCE.getReason(99, null);
             Assert.fail("IllegalArgumentException must have been thrown (99)");
-        } catch (IllegalArgumentException expected) {
+        } catch (final IllegalArgumentException expected) {
         }
         try {
             EnglishReasonPhraseCatalog.INSTANCE.getReason(600, null);
             Assert.fail("IllegalArgumentException must have been thrown (600)");
-        } catch (IllegalArgumentException expected) {
+        } catch (final IllegalArgumentException expected) {
         }
     }
 
diff --git a/httpcore/src/test/java/org/apache/http/impl/TestNoConnectionReuseStrategy.java b/httpcore/src/test/java/org/apache/http/impl/TestNoConnectionReuseStrategy.java
index 1994af1..b3dcbae 100644
--- a/httpcore/src/test/java/org/apache/http/impl/TestNoConnectionReuseStrategy.java
+++ b/httpcore/src/test/java/org/apache/http/impl/TestNoConnectionReuseStrategy.java
@@ -27,10 +27,9 @@
 
 package org.apache.http.impl;
 
-import junit.framework.Assert;
-
 import org.apache.http.HttpResponse;
 import org.apache.http.protocol.HttpContext;
+import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
 import org.mockito.Mock;
@@ -38,7 +37,7 @@ import org.mockito.MockitoAnnotations;
 
 public class TestNoConnectionReuseStrategy {
 
-    private NoConnectionReuseStrategy strat = new NoConnectionReuseStrategy();
+    private final NoConnectionReuseStrategy strat = new NoConnectionReuseStrategy();
     @Mock private HttpResponse response;
     @Mock private HttpContext context;
 
@@ -47,16 +46,6 @@ public class TestNoConnectionReuseStrategy {
         MockitoAnnotations.initMocks(this);
     }
 
-    @Test(expected=IllegalArgumentException.class)
-    public void testNullResponse() throws Exception {
-        strat.keepAlive(null, context);
-    }
-
-    @Test(expected=IllegalArgumentException.class)
-    public void testNullContext() throws Exception {
-        strat.keepAlive(response, null);
-    }
-
     @Test
     public void testGoodcall() throws Exception {
         Assert.assertFalse(strat.keepAlive(response, context));
diff --git a/httpcore/src/test/java/org/apache/http/impl/entity/DummyHttpMessage.java b/httpcore/src/test/java/org/apache/http/impl/entity/DummyHttpMessage.java
index ac66482..e3b4f70 100644
--- a/httpcore/src/test/java/org/apache/http/impl/entity/DummyHttpMessage.java
+++ b/httpcore/src/test/java/org/apache/http/impl/entity/DummyHttpMessage.java
@@ -27,18 +27,25 @@
 
 package org.apache.http.impl.entity;
 
+import org.apache.http.HttpVersion;
 import org.apache.http.ProtocolVersion;
 import org.apache.http.message.AbstractHttpMessage;
-import org.apache.http.params.HttpProtocolParams;
 
 class DummyHttpMessage extends AbstractHttpMessage {
 
-    public DummyHttpMessage() {
+    private final ProtocolVersion ver;
+
+    public DummyHttpMessage(final ProtocolVersion ver) {
         super();
+        this.ver = ver != null ? ver : HttpVersion.HTTP_1_1;
+    }
+
+    public DummyHttpMessage() {
+        this(HttpVersion.HTTP_1_1);
     }
 
     public ProtocolVersion getProtocolVersion() {
-        return HttpProtocolParams.getVersion(this.getParams());
+        return ver;
     }
 
 }
diff --git a/httpcore/src/test/java/org/apache/http/impl/entity/TestDisallowIdentityContentLengthStrategy.java b/httpcore/src/test/java/org/apache/http/impl/entity/TestDisallowIdentityContentLengthStrategy.java
index 7965a70..155c3de 100644
--- a/httpcore/src/test/java/org/apache/http/impl/entity/TestDisallowIdentityContentLengthStrategy.java
+++ b/httpcore/src/test/java/org/apache/http/impl/entity/TestDisallowIdentityContentLengthStrategy.java
@@ -38,19 +38,19 @@ public class TestDisallowIdentityContentLengthStrategy {
 
     @Test
     public void testZeroLength() throws Exception {
-        ContentLengthStrategy strat1 = Mockito.mock(ContentLengthStrategy.class);
-        HttpMessage message = new DummyHttpMessage();
+        final ContentLengthStrategy strat1 = Mockito.mock(ContentLengthStrategy.class);
+        final HttpMessage message = new DummyHttpMessage();
         Mockito.when(strat1.determineLength(message)).thenReturn(0L);
-        DisallowIdentityContentLengthStrategy strat2 = new DisallowIdentityContentLengthStrategy(strat1);
+        final DisallowIdentityContentLengthStrategy strat2 = new DisallowIdentityContentLengthStrategy(strat1);
         Assert.assertEquals(0L, strat2.determineLength(message));
     }
 
     @Test(expected=ProtocolException.class)
     public void testIdentity() throws Exception {
-        ContentLengthStrategy strat1 = Mockito.mock(ContentLengthStrategy.class);
-        HttpMessage message = new DummyHttpMessage();
+        final ContentLengthStrategy strat1 = Mockito.mock(ContentLengthStrategy.class);
+        final HttpMessage message = new DummyHttpMessage();
         Mockito.when(strat1.determineLength(message)).thenReturn((long) ContentLengthStrategy.IDENTITY);
-        DisallowIdentityContentLengthStrategy strat2 = new DisallowIdentityContentLengthStrategy(strat1);
+        final DisallowIdentityContentLengthStrategy strat2 = new DisallowIdentityContentLengthStrategy(strat1);
         strat2.determineLength(message);
     }
 
diff --git a/httpcore/src/test/java/org/apache/http/impl/entity/TestEntityDeserializer.java b/httpcore/src/test/java/org/apache/http/impl/entity/TestEntityDeserializer.java
deleted file mode 100644
index 33160f7..0000000
--- a/httpcore/src/test/java/org/apache/http/impl/entity/TestEntityDeserializer.java
+++ /dev/null
@@ -1,356 +0,0 @@
-/*
- * ====================================================================
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- *
- */
-
-package org.apache.http.impl.entity;
-
-import java.io.InputStream;
-
-import org.apache.http.HttpEntity;
-import org.apache.http.HttpMessage;
-import org.apache.http.ProtocolException;
-import org.apache.http.impl.SessionInputBufferMock;
-import org.apache.http.impl.io.ChunkedInputStream;
-import org.apache.http.impl.io.ContentLengthInputStream;
-import org.apache.http.impl.io.IdentityInputStream;
-import org.apache.http.io.SessionInputBuffer;
-import org.apache.http.params.CoreProtocolPNames;
-import org.junit.Assert;
-import org.junit.Test;
-
-public class TestEntityDeserializer {
-
-    @Test
-    public void testIllegalGenerateArg() throws Exception {
-        EntityDeserializer entitygen = new EntityDeserializer(
-                new LaxContentLengthStrategy());
-        try {
-            entitygen.deserialize(null, null);
-            Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
-            // expected
-        }
-        try {
-            entitygen.deserialize(new SessionInputBufferMock(new byte[] {}) , null);
-            Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
-            // expected
-        }
-    }
-
-    @Test
-    public void testEntityWithTransferEncoding() throws Exception {
-        SessionInputBuffer inbuffer = new SessionInputBufferMock("0\r\n", "US-ASCII");
-        HttpMessage message = new DummyHttpMessage();
-
-        // lenient mode
-        message.getParams().setBooleanParameter(CoreProtocolPNames.STRICT_TRANSFER_ENCODING, false);
-        message.addHeader("Content-Type", "unknown");
-        message.addHeader("Transfer-Encoding", "identity, chunked");
-        message.addHeader("Content-Length", "plain wrong");
-        EntityDeserializer entitygen = new EntityDeserializer(
-                new LaxContentLengthStrategy());
-        HttpEntity entity = entitygen.deserialize(inbuffer, message);
-        Assert.assertNotNull(entity);
-        Assert.assertEquals(-1, entity.getContentLength());
-        Assert.assertTrue(entity.isChunked());
-        Assert.assertTrue(entity.getContent() instanceof ChunkedInputStream);
-
-        // strict mode
-        message.getParams().setBooleanParameter(CoreProtocolPNames.STRICT_TRANSFER_ENCODING, true);
-        entity = entitygen.deserialize(inbuffer, message);
-        Assert.assertNotNull(entity);
-        Assert.assertEquals(-1, entity.getContentLength());
-        Assert.assertTrue(entity.isChunked());
-        Assert.assertTrue(entity.getContent() instanceof ChunkedInputStream);
-    }
-
-    @Test
-    public void testEntityWithIdentityTransferEncoding() throws Exception {
-        SessionInputBuffer inbuffer =
-            new SessionInputBufferMock(new byte[] {});
-        HttpMessage message = new DummyHttpMessage();
-
-        // lenient mode
-        message.getParams().setBooleanParameter(CoreProtocolPNames.STRICT_TRANSFER_ENCODING, false);
-        message.addHeader("Content-Type", "unknown");
-        message.addHeader("Transfer-Encoding", "identity");
-        message.addHeader("Content-Length", "plain wrong");
-        EntityDeserializer entitygen = new EntityDeserializer(
-                new LaxContentLengthStrategy());
-        HttpEntity entity = entitygen.deserialize(inbuffer, message);
-        Assert.assertNotNull(entity);
-        Assert.assertEquals(-1, entity.getContentLength());
-        Assert.assertFalse(entity.isChunked());
-    }
-
-    @Test
-    public void testEntityWithUnsupportedTransferEncoding() throws Exception {
-        SessionInputBuffer inbuffer = new SessionInputBufferMock("0\r\n", "US-ASCII");
-        HttpMessage message = new DummyHttpMessage();
-
-        // lenient mode
-        message.getParams().setBooleanParameter(CoreProtocolPNames.STRICT_TRANSFER_ENCODING, false);
-        message.addHeader("Content-Type", "unknown");
-        message.addHeader("Transfer-Encoding", "whatever; param=value, chunked");
-        message.addHeader("Content-Length", "plain wrong");
-        EntityDeserializer entitygen = new EntityDeserializer(
-                new LaxContentLengthStrategy());
-        HttpEntity entity = entitygen.deserialize(inbuffer, message);
-        Assert.assertNotNull(entity);
-        Assert.assertEquals(-1, entity.getContentLength());
-        Assert.assertTrue(entity.isChunked());
-        Assert.assertTrue(entity.getContent() instanceof ChunkedInputStream);
-
-        // strict mode
-        message.getParams().setBooleanParameter(CoreProtocolPNames.STRICT_TRANSFER_ENCODING, true);
-        try {
-            entitygen.deserialize(inbuffer, message);
-            Assert.fail("ProtocolException should have been thrown");
-        } catch (ProtocolException ex) {
-            // expected
-        }
-    }
-
-    @Test
-    public void testChunkedTransferEncodingMustBeLast() throws Exception {
-        SessionInputBuffer inbuffer = new SessionInputBufferMock("0\r\n", "US-ASCII");
-        HttpMessage message = new DummyHttpMessage();
-
-        // lenient mode
-        message.getParams().setBooleanParameter(CoreProtocolPNames.STRICT_TRANSFER_ENCODING, false);
-        message.addHeader("Content-Type", "unknown");
-        message.addHeader("Transfer-Encoding", "chunked, identity");
-        message.addHeader("Content-Length", "plain wrong");
-        EntityDeserializer entitygen = new EntityDeserializer(
-                new LaxContentLengthStrategy());
-        HttpEntity entity = entitygen.deserialize(inbuffer, message);
-        Assert.assertNotNull(entity);
-        Assert.assertEquals(-1, entity.getContentLength());
-        Assert.assertFalse(entity.isChunked());
-        Assert.assertFalse(entity.getContent() instanceof ChunkedInputStream);
-
-        // strict mode
-        message.getParams().setBooleanParameter(CoreProtocolPNames.STRICT_TRANSFER_ENCODING, true);
-        try {
-            entitygen.deserialize(inbuffer, message);
-            Assert.fail("ProtocolException should have been thrown");
-        } catch (ProtocolException ex) {
-            // expected
-        }
-    }
-
-    @Test
-    public void testEntityWithContentLength() throws Exception {
-        SessionInputBuffer inbuffer = new SessionInputBufferMock(new byte[] {});
-        HttpMessage message = new DummyHttpMessage();
-
-        // lenient mode
-        message.getParams().setBooleanParameter(CoreProtocolPNames.STRICT_TRANSFER_ENCODING, false);
-        message.addHeader("Content-Type", "unknown");
-        message.addHeader("Content-Length", "0");
-        EntityDeserializer entitygen = new EntityDeserializer(
-                new LaxContentLengthStrategy());
-        HttpEntity entity = entitygen.deserialize(inbuffer, message);
-        Assert.assertNotNull(entity);
-        Assert.assertEquals(0, entity.getContentLength());
-        Assert.assertFalse(entity.isChunked());
-        Assert.assertTrue(entity.getContent() instanceof ContentLengthInputStream);
-    }
-
-    @Test
-    public void testEntityWithMultipleContentLength() throws Exception {
-        SessionInputBuffer inbuffer = new SessionInputBufferMock(new byte[] {'0'});
-        HttpMessage message = new DummyHttpMessage();
-
-        // lenient mode
-        message.getParams().setBooleanParameter(CoreProtocolPNames.STRICT_TRANSFER_ENCODING, false);
-        message.addHeader("Content-Type", "unknown");
-        message.addHeader("Content-Length", "0");
-        message.addHeader("Content-Length", "0");
-        message.addHeader("Content-Length", "1");
-        EntityDeserializer entitygen = new EntityDeserializer(
-                new LaxContentLengthStrategy());
-        HttpEntity entity = entitygen.deserialize(inbuffer, message);
-        Assert.assertNotNull(entity);
-        Assert.assertEquals(1, entity.getContentLength());
-        Assert.assertFalse(entity.isChunked());
-        InputStream instream = entity.getContent();
-        Assert.assertNotNull(instream);
-        Assert.assertTrue(instream instanceof ContentLengthInputStream);
-
-        // strict mode
-        message.getParams().setBooleanParameter(CoreProtocolPNames.STRICT_TRANSFER_ENCODING, true);
-        try {
-            entitygen.deserialize(inbuffer, message);
-            Assert.fail("ProtocolException should have been thrown");
-        } catch (ProtocolException ex) {
-            // expected
-        }
-    }
-
-    @Test
-    public void testEntityWithMultipleContentLengthSomeWrong() throws Exception {
-        SessionInputBuffer inbuffer = new SessionInputBufferMock(new byte[] {'0'});
-        HttpMessage message = new DummyHttpMessage();
-
-        // lenient mode
-        message.getParams().setBooleanParameter(CoreProtocolPNames.STRICT_TRANSFER_ENCODING, false);
-        message.addHeader("Content-Type", "unknown");
-        message.addHeader("Content-Length", "1");
-        message.addHeader("Content-Length", "yyy");
-        message.addHeader("Content-Length", "xxx");
-        EntityDeserializer entitygen = new EntityDeserializer(
-                new LaxContentLengthStrategy());
-        HttpEntity entity = entitygen.deserialize(inbuffer, message);
-        Assert.assertNotNull(entity);
-        Assert.assertEquals(1, entity.getContentLength());
-        Assert.assertFalse(entity.isChunked());
-        InputStream instream = entity.getContent();
-        Assert.assertNotNull(instream);
-        Assert.assertTrue(instream instanceof ContentLengthInputStream);
-
-        // strict mode
-        message.getParams().setBooleanParameter(CoreProtocolPNames.STRICT_TRANSFER_ENCODING, true);
-        try {
-            entitygen.deserialize(inbuffer, message);
-            Assert.fail("ProtocolException should have been thrown");
-        } catch (ProtocolException ex) {
-            // expected
-        }
-    }
-
-    @Test
-    public void testEntityWithMultipleContentLengthAllWrong() throws Exception {
-        SessionInputBuffer inbuffer = new SessionInputBufferMock(new byte[] {'0'});
-        HttpMessage message = new DummyHttpMessage();
-
-        // lenient mode
-        message.getParams().setBooleanParameter(CoreProtocolPNames.STRICT_TRANSFER_ENCODING, false);
-        message.addHeader("Content-Type", "unknown");
-        message.addHeader("Content-Length", "yyy");
-        message.addHeader("Content-Length", "xxx");
-        EntityDeserializer entitygen = new EntityDeserializer(
-                new LaxContentLengthStrategy());
-        HttpEntity entity = entitygen.deserialize(inbuffer, message);
-        Assert.assertNotNull(entity);
-        Assert.assertEquals(-1, entity.getContentLength());
-        Assert.assertFalse(entity.isChunked());
-        InputStream instream = entity.getContent();
-        Assert.assertNotNull(instream);
-        Assert.assertFalse(instream instanceof ContentLengthInputStream);
-        Assert.assertTrue(instream instanceof IdentityInputStream);
-
-        // strict mode
-        message.getParams().setBooleanParameter(CoreProtocolPNames.STRICT_TRANSFER_ENCODING, true);
-        try {
-            entitygen.deserialize(inbuffer, message);
-            Assert.fail("ProtocolException should have been thrown");
-        } catch (ProtocolException ex) {
-            // expected
-        }
-    }
-
-    @Test
-    public void testEntityWithInvalidContentLength() throws Exception {
-        SessionInputBuffer inbuffer = new SessionInputBufferMock(new byte[] {'0'});
-        HttpMessage message = new DummyHttpMessage();
-
-        // lenient mode
-        message.getParams().setBooleanParameter(CoreProtocolPNames.STRICT_TRANSFER_ENCODING, false);
-        message.addHeader("Content-Type", "unknown");
-        message.addHeader("Content-Length", "xxx");
-        EntityDeserializer entitygen = new EntityDeserializer(
-                new LaxContentLengthStrategy());
-        HttpEntity entity = entitygen.deserialize(inbuffer, message);
-        Assert.assertNotNull(entity);
-        Assert.assertEquals(-1, entity.getContentLength());
-        Assert.assertFalse(entity.isChunked());
-        InputStream instream = entity.getContent();
-        Assert.assertNotNull(instream);
-        Assert.assertFalse(instream instanceof ContentLengthInputStream);
-        Assert.assertTrue(instream instanceof IdentityInputStream);
-
-        // strict mode
-        message.getParams().setBooleanParameter(CoreProtocolPNames.STRICT_TRANSFER_ENCODING, true);
-        try {
-            entitygen.deserialize(inbuffer, message);
-            Assert.fail("ProtocolException should have been thrown");
-        } catch (ProtocolException ex) {
-            // expected
-        }
-    }
-
-    @Test
-    public void testEntityNeitherContentLengthNorTransferEncoding() throws Exception {
-        SessionInputBuffer inbuffer = new SessionInputBufferMock(new byte[] {'0'});
-        HttpMessage message = new DummyHttpMessage();
-
-        // lenient mode
-        message.getParams().setBooleanParameter(CoreProtocolPNames.STRICT_TRANSFER_ENCODING, false);
-        EntityDeserializer entitygen = new EntityDeserializer(
-                new LaxContentLengthStrategy());
-        HttpEntity entity = entitygen.deserialize(inbuffer, message);
-        Assert.assertNotNull(entity);
-        Assert.assertEquals(-1, entity.getContentLength());
-        Assert.assertFalse(entity.isChunked());
-        InputStream instream = entity.getContent();
-        Assert.assertNotNull(instream);
-        Assert.assertFalse(instream instanceof ContentLengthInputStream);
-        Assert.assertFalse(instream instanceof ChunkedInputStream);
-        Assert.assertTrue(instream instanceof IdentityInputStream);
-    }
-
-    @Test
-    public void testEntityContentType() throws Exception {
-        SessionInputBuffer inbuffer = new SessionInputBufferMock(new byte[] {'0'});
-        HttpMessage message = new DummyHttpMessage();
-
-        message.addHeader("Content-Type", "stuff");
-        EntityDeserializer entitygen = new EntityDeserializer(
-                new LaxContentLengthStrategy());
-        HttpEntity entity = entitygen.deserialize(inbuffer, message);
-        Assert.assertNotNull(entity);
-        Assert.assertNotNull(entity.getContentType());
-        Assert.assertEquals("stuff", entity.getContentType().getValue());
-    }
-
-    @Test
-    public void testEntityContentEncoding() throws Exception {
-        SessionInputBuffer inbuffer = new SessionInputBufferMock(new byte[] {'0'});
-        HttpMessage message = new DummyHttpMessage();
-
-        message.addHeader("Content-Encoding", "what not");
-        EntityDeserializer entitygen = new EntityDeserializer(
-                new LaxContentLengthStrategy());
-        HttpEntity entity = entitygen.deserialize(inbuffer, message);
-        Assert.assertNotNull(entity);
-        Assert.assertNotNull(entity.getContentEncoding());
-        Assert.assertEquals("what not", entity.getContentEncoding().getValue());
-    }
-
-}
-
diff --git a/httpcore/src/test/java/org/apache/http/impl/entity/TestEntitySerializer.java b/httpcore/src/test/java/org/apache/http/impl/entity/TestEntitySerializer.java
deleted file mode 100644
index 44edc92..0000000
--- a/httpcore/src/test/java/org/apache/http/impl/entity/TestEntitySerializer.java
+++ /dev/null
@@ -1,188 +0,0 @@
-/*
- * ====================================================================
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- *
- */
-
-package org.apache.http.impl.entity;
-
-import java.io.OutputStream;
-
-import org.apache.http.HttpMessage;
-import org.apache.http.HttpVersion;
-import org.apache.http.ProtocolException;
-import org.apache.http.entity.ByteArrayEntity;
-import org.apache.http.impl.SessionOutputBufferMock;
-import org.apache.http.impl.io.ChunkedOutputStream;
-import org.apache.http.impl.io.ContentLengthOutputStream;
-import org.apache.http.impl.io.IdentityOutputStream;
-import org.apache.http.io.SessionOutputBuffer;
-import org.apache.http.params.CoreProtocolPNames;
-import org.junit.Assert;
-import org.junit.Test;
-
-public class TestEntitySerializer {
-
-    @Test
-    public void testIllegalGenerateArg() throws Exception {
-        EntitySerializer entitywriter = new EntitySerializer(
-                new StrictContentLengthStrategy());
-        try {
-            entitywriter.serialize(null, null, null);
-            Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
-            // expected
-        }
-        try {
-            entitywriter.serialize(new SessionOutputBufferMock() , null, null);
-            Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
-            // expected
-        }
-        try {
-            entitywriter.serialize(new SessionOutputBufferMock() , new DummyHttpMessage(), null);
-            Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
-            // expected
-        }
-    }
-
-    @Test
-    public void testEntityWithChunkTransferEncoding() throws Exception {
-        SessionOutputBuffer outbuffer = new SessionOutputBufferMock();
-        HttpMessage message = new DummyHttpMessage();
-        message.addHeader("Transfer-Encoding", "Chunked");
-
-        EntitySerializer entitywriter = new EntitySerializer(
-                new StrictContentLengthStrategy());
-        OutputStream outstream = entitywriter.doSerialize(outbuffer, message);
-        Assert.assertNotNull(outstream);
-        Assert.assertTrue(outstream instanceof ChunkedOutputStream);
-    }
-
-    @Test
-    public void testEntityWithIdentityTransferEncoding() throws Exception {
-        SessionOutputBuffer outbuffer = new SessionOutputBufferMock();
-        HttpMessage message = new DummyHttpMessage();
-        message.addHeader("Transfer-Encoding", "Identity");
-
-        EntitySerializer entitywriter = new EntitySerializer(
-                new StrictContentLengthStrategy());
-        OutputStream outstream = entitywriter.doSerialize(outbuffer, message);
-        Assert.assertNotNull(outstream);
-        Assert.assertTrue(outstream instanceof IdentityOutputStream);
-    }
-
-    @Test
-    public void testEntityWithInvalidTransferEncoding() throws Exception {
-        SessionOutputBuffer outbuffer = new SessionOutputBufferMock();
-        HttpMessage message = new DummyHttpMessage();
-        message.addHeader("Transfer-Encoding", "whatever");
-
-        EntitySerializer entitywriter = new EntitySerializer(
-                new StrictContentLengthStrategy());
-        try {
-            entitywriter.doSerialize(outbuffer, message);
-            Assert.fail("ProtocolException should have been thrown");
-        } catch (ProtocolException ex) {
-            // expected
-        }
-    }
-
-    @Test
-    public void testEntityWithInvalidChunkEncodingAndHTTP10() throws Exception {
-        SessionOutputBuffer outbuffer = new SessionOutputBufferMock();
-        HttpMessage message = new DummyHttpMessage();
-        message.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION,
-                HttpVersion.HTTP_1_0);
-        message.addHeader("Transfer-Encoding", "chunked");
-
-        EntitySerializer entitywriter = new EntitySerializer(
-                new StrictContentLengthStrategy());
-        try {
-            entitywriter.doSerialize(outbuffer, message);
-            Assert.fail("ProtocolException should have been thrown");
-        } catch (ProtocolException ex) {
-            // expected
-        }
-    }
-
-    @Test
-    public void testEntityWithContentLength() throws Exception {
-        SessionOutputBuffer outbuffer = new SessionOutputBufferMock();
-        HttpMessage message = new DummyHttpMessage();
-        message.addHeader("Content-Length", "100");
-        EntitySerializer entitywriter = new EntitySerializer(
-                new StrictContentLengthStrategy());
-        OutputStream outstream = entitywriter.doSerialize(outbuffer, message);
-        Assert.assertNotNull(outstream);
-        Assert.assertTrue(outstream instanceof ContentLengthOutputStream);
-    }
-
-    @Test
-    public void testEntityWithInvalidContentLength() throws Exception {
-        SessionOutputBuffer outbuffer = new SessionOutputBufferMock();
-        HttpMessage message = new DummyHttpMessage();
-        message.addHeader("Content-Length", "whatever");
-
-        EntitySerializer entitywriter = new EntitySerializer(
-                new StrictContentLengthStrategy());
-        try {
-            entitywriter.doSerialize(outbuffer, message);
-            Assert.fail("ProtocolException should have been thrown");
-        } catch (ProtocolException ex) {
-            // expected
-        }
-    }
-
-    @Test
-    public void testEntityNoContentDelimiter() throws Exception {
-        SessionOutputBuffer outbuffer = new SessionOutputBufferMock();
-        HttpMessage message = new DummyHttpMessage();
-        EntitySerializer entitywriter = new EntitySerializer(
-                new StrictContentLengthStrategy());
-        OutputStream outstream = entitywriter.doSerialize(outbuffer, message);
-        Assert.assertNotNull(outstream);
-        Assert.assertTrue(outstream instanceof IdentityOutputStream);
-    }
-
-    @Test
-    public void testEntitySerialization() throws Exception {
-        byte[] content = new byte[] {1, 2, 3, 4, 5};
-        ByteArrayEntity entity = new ByteArrayEntity(content);
-
-        SessionOutputBufferMock outbuffer = new SessionOutputBufferMock();
-        HttpMessage message = new DummyHttpMessage();
-        message.addHeader("Content-Length", Integer.toString(content.length));
-
-        EntitySerializer entitywriter = new EntitySerializer(
-                new StrictContentLengthStrategy());
-        entitywriter.serialize(outbuffer, message, entity);
-
-        byte[] data = outbuffer.getData();
-        Assert.assertNotNull(data);
-        Assert.assertEquals(content.length, data.length);
-    }
-}
-
diff --git a/httpcore/src/test/java/org/apache/http/impl/entity/TestLaxContentLengthStrategy.java b/httpcore/src/test/java/org/apache/http/impl/entity/TestLaxContentLengthStrategy.java
index 16ce0c4..569c349 100644
--- a/httpcore/src/test/java/org/apache/http/impl/entity/TestLaxContentLengthStrategy.java
+++ b/httpcore/src/test/java/org/apache/http/impl/entity/TestLaxContentLengthStrategy.java
@@ -28,9 +28,7 @@
 package org.apache.http.impl.entity;
 
 import org.apache.http.HttpMessage;
-import org.apache.http.ProtocolException;
 import org.apache.http.entity.ContentLengthStrategy;
-import org.apache.http.params.CoreProtocolPNames;
 import org.junit.Assert;
 import org.junit.Test;
 
@@ -38,28 +36,20 @@ public class TestLaxContentLengthStrategy {
 
     @Test
     public void testEntityWithTransferEncoding() throws Exception {
-        ContentLengthStrategy lenStrategy = new LaxContentLengthStrategy();
-        HttpMessage message = new DummyHttpMessage();
+        final ContentLengthStrategy lenStrategy = new LaxContentLengthStrategy();
+        final HttpMessage message = new DummyHttpMessage();
 
-        // lenient mode
-        message.getParams().setBooleanParameter(CoreProtocolPNames.STRICT_TRANSFER_ENCODING, false);
         message.addHeader("Content-Type", "unknown");
         message.addHeader("Transfer-Encoding", "identity, chunked");
         message.addHeader("Content-Length", "plain wrong");
         Assert.assertEquals(ContentLengthStrategy.CHUNKED, lenStrategy.determineLength(message));
-
-        // strict mode
-        message.getParams().setBooleanParameter(CoreProtocolPNames.STRICT_TRANSFER_ENCODING, true);
-        Assert.assertEquals(ContentLengthStrategy.CHUNKED, lenStrategy.determineLength(message));
     }
 
     @Test
     public void testEntityWithIdentityTransferEncoding() throws Exception {
-        ContentLengthStrategy lenStrategy = new LaxContentLengthStrategy();
-        HttpMessage message = new DummyHttpMessage();
+        final ContentLengthStrategy lenStrategy = new LaxContentLengthStrategy();
+        final HttpMessage message = new DummyHttpMessage();
 
-        // lenient mode
-        message.getParams().setBooleanParameter(CoreProtocolPNames.STRICT_TRANSFER_ENCODING, false);
         message.addHeader("Content-Type", "unknown");
         message.addHeader("Transfer-Encoding", "identity");
         message.addHeader("Content-Length", "plain wrong");
@@ -68,55 +58,31 @@ public class TestLaxContentLengthStrategy {
 
     @Test
     public void testEntityWithUnsupportedTransferEncoding() throws Exception {
-        ContentLengthStrategy lenStrategy = new LaxContentLengthStrategy();
-        HttpMessage message = new DummyHttpMessage();
+        final ContentLengthStrategy lenStrategy = new LaxContentLengthStrategy();
+        final HttpMessage message = new DummyHttpMessage();
 
-        // lenient mode
-        message.getParams().setBooleanParameter(CoreProtocolPNames.STRICT_TRANSFER_ENCODING, false);
         message.addHeader("Content-Type", "unknown");
         message.addHeader("Transfer-Encoding", "whatever; param=value, chunked");
         message.addHeader("Content-Length", "plain wrong");
         Assert.assertEquals(ContentLengthStrategy.CHUNKED, lenStrategy.determineLength(message));
-
-        // strict mode
-        message.getParams().setBooleanParameter(CoreProtocolPNames.STRICT_TRANSFER_ENCODING, true);
-        try {
-            lenStrategy.determineLength(message);
-            Assert.fail("ProtocolException should have been thrown");
-        } catch (ProtocolException ex) {
-            // expected
-        }
     }
 
     @Test
     public void testChunkedTransferEncodingMustBeLast() throws Exception {
-        ContentLengthStrategy lenStrategy = new LaxContentLengthStrategy();
-        HttpMessage message = new DummyHttpMessage();
+        final ContentLengthStrategy lenStrategy = new LaxContentLengthStrategy();
+        final HttpMessage message = new DummyHttpMessage();
 
-        // lenient mode
-        message.getParams().setBooleanParameter(CoreProtocolPNames.STRICT_TRANSFER_ENCODING, false);
         message.addHeader("Content-Type", "unknown");
         message.addHeader("Transfer-Encoding", "chunked, identity");
         message.addHeader("Content-Length", "plain wrong");
         Assert.assertEquals(ContentLengthStrategy.IDENTITY, lenStrategy.determineLength(message));
-
-        // strict mode
-        message.getParams().setBooleanParameter(CoreProtocolPNames.STRICT_TRANSFER_ENCODING, true);
-        try {
-            lenStrategy.determineLength(message);
-            Assert.fail("ProtocolException should have been thrown");
-        } catch (ProtocolException ex) {
-            // expected
-        }
     }
 
     @Test
     public void testEntityWithContentLength() throws Exception {
-        ContentLengthStrategy lenStrategy = new LaxContentLengthStrategy();
-        HttpMessage message = new DummyHttpMessage();
+        final ContentLengthStrategy lenStrategy = new LaxContentLengthStrategy();
+        final HttpMessage message = new DummyHttpMessage();
 
-        // lenient mode
-        message.getParams().setBooleanParameter(CoreProtocolPNames.STRICT_TRANSFER_ENCODING, false);
         message.addHeader("Content-Type", "unknown");
         message.addHeader("Content-Length", "0");
         Assert.assertEquals(0, lenStrategy.determineLength(message));
@@ -124,97 +90,53 @@ public class TestLaxContentLengthStrategy {
 
     @Test
     public void testEntityWithMultipleContentLength() throws Exception {
-        ContentLengthStrategy lenStrategy = new LaxContentLengthStrategy();
-        HttpMessage message = new DummyHttpMessage();
+        final ContentLengthStrategy lenStrategy = new LaxContentLengthStrategy();
+        final HttpMessage message = new DummyHttpMessage();
 
-        // lenient mode
-        message.getParams().setBooleanParameter(CoreProtocolPNames.STRICT_TRANSFER_ENCODING, false);
         message.addHeader("Content-Type", "unknown");
         message.addHeader("Content-Length", "0");
         message.addHeader("Content-Length", "0");
         message.addHeader("Content-Length", "1");
         Assert.assertEquals(1, lenStrategy.determineLength(message));
-
-        // strict mode
-        message.getParams().setBooleanParameter(CoreProtocolPNames.STRICT_TRANSFER_ENCODING, true);
-        try {
-            lenStrategy.determineLength(message);
-            Assert.fail("ProtocolException should have been thrown");
-        } catch (ProtocolException ex) {
-            // expected
-        }
     }
 
     @Test
     public void testEntityWithMultipleContentLengthSomeWrong() throws Exception {
-        ContentLengthStrategy lenStrategy = new LaxContentLengthStrategy();
-        HttpMessage message = new DummyHttpMessage();
+        final ContentLengthStrategy lenStrategy = new LaxContentLengthStrategy();
+        final HttpMessage message = new DummyHttpMessage();
 
-        // lenient mode
-        message.getParams().setBooleanParameter(CoreProtocolPNames.STRICT_TRANSFER_ENCODING, false);
         message.addHeader("Content-Type", "unknown");
         message.addHeader("Content-Length", "1");
         message.addHeader("Content-Length", "yyy");
         message.addHeader("Content-Length", "xxx");
         Assert.assertEquals(1, lenStrategy.determineLength(message));
-
-        // strict mode
-        message.getParams().setBooleanParameter(CoreProtocolPNames.STRICT_TRANSFER_ENCODING, true);
-        try {
-            lenStrategy.determineLength(message);
-            Assert.fail("ProtocolException should have been thrown");
-        } catch (ProtocolException ex) {
-            // expected
-        }
     }
 
     @Test
     public void testEntityWithMultipleContentLengthAllWrong() throws Exception {
-        ContentLengthStrategy lenStrategy = new LaxContentLengthStrategy();
-        HttpMessage message = new DummyHttpMessage();
+        final ContentLengthStrategy lenStrategy = new LaxContentLengthStrategy();
+        final HttpMessage message = new DummyHttpMessage();
 
-        // lenient mode
-        message.getParams().setBooleanParameter(CoreProtocolPNames.STRICT_TRANSFER_ENCODING, false);
         message.addHeader("Content-Type", "unknown");
         message.addHeader("Content-Length", "yyy");
         message.addHeader("Content-Length", "xxx");
         Assert.assertEquals(ContentLengthStrategy.IDENTITY, lenStrategy.determineLength(message));
-
-        // strict mode
-        message.getParams().setBooleanParameter(CoreProtocolPNames.STRICT_TRANSFER_ENCODING, true);
-        try {
-            lenStrategy.determineLength(message);
-            Assert.fail("ProtocolException should have been thrown");
-        } catch (ProtocolException ex) {
-            // expected
-        }
     }
 
     @Test
     public void testEntityWithInvalidContentLength() throws Exception {
-        ContentLengthStrategy lenStrategy = new LaxContentLengthStrategy();
-        HttpMessage message = new DummyHttpMessage();
+        final ContentLengthStrategy lenStrategy = new LaxContentLengthStrategy();
+        final HttpMessage message = new DummyHttpMessage();
 
-        // lenient mode
-        message.getParams().setBooleanParameter(CoreProtocolPNames.STRICT_TRANSFER_ENCODING, false);
         message.addHeader("Content-Type", "unknown");
         message.addHeader("Content-Length", "xxx");
         Assert.assertEquals(ContentLengthStrategy.IDENTITY, lenStrategy.determineLength(message));
-
-        // strict mode
-        message.getParams().setBooleanParameter(CoreProtocolPNames.STRICT_TRANSFER_ENCODING, true);
-        try {
-            lenStrategy.determineLength(message);
-            Assert.fail("ProtocolException should have been thrown");
-        } catch (ProtocolException ex) {
-            // expected
-        }
     }
 
     @Test
     public void testEntityNeitherContentLengthNorTransferEncoding() throws Exception {
-        ContentLengthStrategy lenStrategy = new LaxContentLengthStrategy();
-        HttpMessage message = new DummyHttpMessage();
+        final ContentLengthStrategy lenStrategy = new LaxContentLengthStrategy();
+        final HttpMessage message = new DummyHttpMessage();
 
         // lenient mode
         Assert.assertEquals(ContentLengthStrategy.IDENTITY, lenStrategy.determineLength(message));
diff --git a/httpcore/src/test/java/org/apache/http/impl/entity/TestStrictContentLengthStrategy.java b/httpcore/src/test/java/org/apache/http/impl/entity/TestStrictContentLengthStrategy.java
index 933d0b7..0a5ae14 100644
--- a/httpcore/src/test/java/org/apache/http/impl/entity/TestStrictContentLengthStrategy.java
+++ b/httpcore/src/test/java/org/apache/http/impl/entity/TestStrictContentLengthStrategy.java
@@ -31,7 +31,6 @@ import org.apache.http.HttpMessage;
 import org.apache.http.HttpVersion;
 import org.apache.http.ProtocolException;
 import org.apache.http.entity.ContentLengthStrategy;
-import org.apache.http.params.CoreProtocolPNames;
 import org.junit.Assert;
 import org.junit.Test;
 
@@ -39,8 +38,8 @@ public class TestStrictContentLengthStrategy {
 
     @Test
     public void testEntityWithChunkTransferEncoding() throws Exception {
-        ContentLengthStrategy lenStrategy = new StrictContentLengthStrategy();
-        HttpMessage message = new DummyHttpMessage();
+        final ContentLengthStrategy lenStrategy = new StrictContentLengthStrategy();
+        final HttpMessage message = new DummyHttpMessage();
         message.addHeader("Transfer-Encoding", "Chunked");
 
         Assert.assertEquals(ContentLengthStrategy.CHUNKED, lenStrategy.determineLength(message));
@@ -48,8 +47,8 @@ public class TestStrictContentLengthStrategy {
 
     @Test
     public void testEntityWithIdentityTransferEncoding() throws Exception {
-        ContentLengthStrategy lenStrategy = new StrictContentLengthStrategy();
-        HttpMessage message = new DummyHttpMessage();
+        final ContentLengthStrategy lenStrategy = new StrictContentLengthStrategy();
+        final HttpMessage message = new DummyHttpMessage();
         message.addHeader("Transfer-Encoding", "Identity");
 
         Assert.assertEquals(ContentLengthStrategy.IDENTITY, lenStrategy.determineLength(message));
@@ -57,50 +56,48 @@ public class TestStrictContentLengthStrategy {
 
     @Test(expected=ProtocolException.class)
     public void testEntityWithInvalidTransferEncoding() throws Exception {
-        ContentLengthStrategy lenStrategy = new StrictContentLengthStrategy();
-        HttpMessage message = new DummyHttpMessage();
+        final ContentLengthStrategy lenStrategy = new StrictContentLengthStrategy();
+        final HttpMessage message = new DummyHttpMessage();
         message.addHeader("Transfer-Encoding", "whatever");
         lenStrategy.determineLength(message);
     }
 
     @Test(expected=ProtocolException.class)
     public void testEntityWithInvalidChunkEncodingAndHTTP10() throws Exception {
-        ContentLengthStrategy lenStrategy = new StrictContentLengthStrategy();
-        HttpMessage message = new DummyHttpMessage();
-        message.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION,
-                HttpVersion.HTTP_1_0);
+        final ContentLengthStrategy lenStrategy = new StrictContentLengthStrategy();
+        final HttpMessage message = new DummyHttpMessage(HttpVersion.HTTP_1_0);
         message.addHeader("Transfer-Encoding", "chunked");
         lenStrategy.determineLength(message);
     }
 
     @Test
     public void testEntityWithContentLength() throws Exception {
-        ContentLengthStrategy lenStrategy = new StrictContentLengthStrategy();
-        HttpMessage message = new DummyHttpMessage();
+        final ContentLengthStrategy lenStrategy = new StrictContentLengthStrategy();
+        final HttpMessage message = new DummyHttpMessage();
         message.addHeader("Content-Length", "100");
         Assert.assertEquals(100, lenStrategy.determineLength(message));
     }
 
     @Test(expected=ProtocolException.class)
     public void testEntityWithInvalidContentLength() throws Exception {
-        ContentLengthStrategy lenStrategy = new StrictContentLengthStrategy();
-        HttpMessage message = new DummyHttpMessage();
+        final ContentLengthStrategy lenStrategy = new StrictContentLengthStrategy();
+        final HttpMessage message = new DummyHttpMessage();
         message.addHeader("Content-Length", "whatever");
         lenStrategy.determineLength(message);
     }
 
     @Test(expected=ProtocolException.class)
     public void testEntityWithNegativeContentLength() throws Exception {
-        ContentLengthStrategy lenStrategy = new StrictContentLengthStrategy();
-        HttpMessage message = new DummyHttpMessage();
+        final ContentLengthStrategy lenStrategy = new StrictContentLengthStrategy();
+        final HttpMessage message = new DummyHttpMessage();
         message.addHeader("Content-Length", "-10");
         lenStrategy.determineLength(message);
     }
 
     @Test
     public void testEntityNoContentDelimiter() throws Exception {
-        ContentLengthStrategy lenStrategy = new StrictContentLengthStrategy();
-        HttpMessage message = new DummyHttpMessage();
+        final ContentLengthStrategy lenStrategy = new StrictContentLengthStrategy();
+        final HttpMessage message = new DummyHttpMessage();
         Assert.assertEquals(ContentLengthStrategy.IDENTITY, lenStrategy.determineLength(message));
     }
 
diff --git a/httpcore/src/test/java/org/apache/http/impl/io/TestChunkCoding.java b/httpcore/src/test/java/org/apache/http/impl/io/TestChunkCoding.java
index cbe8806..91898c9 100644
--- a/httpcore/src/test/java/org/apache/http/impl/io/TestChunkCoding.java
+++ b/httpcore/src/test/java/org/apache/http/impl/io/TestChunkCoding.java
@@ -35,6 +35,7 @@ import java.io.OutputStream;
 
 import org.apache.http.Header;
 import org.apache.http.MalformedChunkCodingException;
+import org.apache.http.TruncatedChunkException;
 import org.apache.http.impl.SessionInputBufferMock;
 import org.apache.http.impl.SessionOutputBufferMock;
 import org.apache.http.io.SessionInputBuffer;
@@ -51,7 +52,7 @@ public class TestChunkCoding {
         try {
             new ChunkedInputStream((SessionInputBuffer)null);
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
             // expected
         }
         new MalformedChunkCodingException();
@@ -67,11 +68,11 @@ public class TestChunkCoding {
     // Test for when buffer is larger than chunk size
     @Test
     public void testChunkedInputStreamLargeBuffer() throws IOException {
-        ChunkedInputStream in = new ChunkedInputStream(
+        final ChunkedInputStream in = new ChunkedInputStream(
                 new SessionInputBufferMock(
                         EncodingUtils.getBytes(CHUNKED_INPUT, CONTENT_CHARSET)));
-        byte[] buffer = new byte[300];
-        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        final byte[] buffer = new byte[300];
+        final ByteArrayOutputStream out = new ByteArrayOutputStream();
         int len;
         while ((len = in.read(buffer)) > 0) {
             out.write(buffer, 0, len);
@@ -81,10 +82,10 @@ public class TestChunkCoding {
 
         in.close();
 
-        String result = EncodingUtils.getString(out.toByteArray(), CONTENT_CHARSET);
+        final String result = EncodingUtils.getString(out.toByteArray(), CONTENT_CHARSET);
         Assert.assertEquals(result, CHUNKED_RESULT);
 
-        Header[] footers = in.getFooters();
+        final Header[] footers = in.getFooters();
         Assert.assertNotNull(footers);
         Assert.assertEquals(2, footers.length);
         Assert.assertEquals("Footer1", footers[0].getName());
@@ -96,12 +97,12 @@ public class TestChunkCoding {
     //Test for when buffer is smaller than chunk size.
     @Test
     public void testChunkedInputStreamSmallBuffer() throws IOException {
-        ChunkedInputStream in = new ChunkedInputStream(
+        final ChunkedInputStream in = new ChunkedInputStream(
                 new SessionInputBufferMock(
                             EncodingUtils.getBytes(CHUNKED_INPUT, CONTENT_CHARSET)));
 
-        byte[] buffer = new byte[7];
-        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        final byte[] buffer = new byte[7];
+        final ByteArrayOutputStream out = new ByteArrayOutputStream();
         int len;
         while ((len = in.read(buffer)) > 0) {
             out.write(buffer, 0, len);
@@ -112,7 +113,7 @@ public class TestChunkCoding {
         in.close();
 
         EncodingUtils.getString(out.toByteArray(), CONTENT_CHARSET);
-        Header[] footers = in.getFooters();
+        final Header[] footers = in.getFooters();
         Assert.assertNotNull(footers);
         Assert.assertEquals(2, footers.length);
         Assert.assertEquals("Footer1", footers[0].getName());
@@ -124,8 +125,8 @@ public class TestChunkCoding {
     // One byte read
     @Test
     public void testChunkedInputStreamOneByteRead() throws IOException {
-        String s = "5\r\n01234\r\n5\r\n56789\r\n0\r\n";
-        ChunkedInputStream in = new ChunkedInputStream(
+        final String s = "5\r\n01234\r\n5\r\n56789\r\n0\r\n";
+        final ChunkedInputStream in = new ChunkedInputStream(
                 new SessionInputBufferMock(
                         EncodingUtils.getBytes(s, CONTENT_CHARSET)));
         int ch;
@@ -142,19 +143,20 @@ public class TestChunkCoding {
 
     @Test
     public void testAvailable() throws IOException {
-        String s = "5\r\n12345\r\n0\r\n";
-        ChunkedInputStream in = new ChunkedInputStream(
+        final String s = "5\r\n12345\r\n0\r\n";
+        final ChunkedInputStream in = new ChunkedInputStream(
                 new SessionInputBufferMock(
                         EncodingUtils.getBytes(s, CONTENT_CHARSET)));
         Assert.assertEquals(0, in.available());
         in.read();
         Assert.assertEquals(4, in.available());
+        in.close();
     }
 
     @Test
     public void testChunkedInputStreamClose() throws IOException {
-        String s = "5\r\n01234\r\n5\r\n56789\r\n0\r\n";
-        ChunkedInputStream in = new ChunkedInputStream(
+        final String s = "5\r\n01234\r\n5\r\n56789\r\n0\r\n";
+        final ChunkedInputStream in = new ChunkedInputStream(
                 new SessionInputBufferMock(
                         EncodingUtils.getBytes(s, CONTENT_CHARSET)));
         in.close();
@@ -162,40 +164,40 @@ public class TestChunkCoding {
         try {
             in.read();
             Assert.fail("IOException should have been thrown");
-        } catch (IOException ex) {
+        } catch (final IOException ex) {
             // expected
         }
-        byte[] tmp = new byte[10];
+        final byte[] tmp = new byte[10];
         try {
             in.read(tmp);
             Assert.fail("IOException should have been thrown");
-        } catch (IOException ex) {
+        } catch (final IOException ex) {
             // expected
         }
         try {
             in.read(tmp, 0, tmp.length);
             Assert.fail("IOException should have been thrown");
-        } catch (IOException ex) {
+        } catch (final IOException ex) {
             // expected
         }
     }
 
     @Test
     public void testChunkedOutputStreamClose() throws IOException {
-        ChunkedOutputStream out = new ChunkedOutputStream(
-                new SessionOutputBufferMock());
+        final ChunkedOutputStream out = new ChunkedOutputStream(
+                2048, new SessionOutputBufferMock());
         out.close();
         out.close();
         try {
             out.write(new byte[] {1,2,3});
             Assert.fail("IOException should have been thrown");
-        } catch (IOException ex) {
+        } catch (final IOException ex) {
             // expected
         }
         try {
             out.write(1);
             Assert.fail("IOException should have been thrown");
-        } catch (IOException ex) {
+        } catch (final IOException ex) {
             // expected
         }
     }
@@ -203,31 +205,32 @@ public class TestChunkCoding {
     // Missing closing chunk
     @Test
     public void testChunkedInputStreamNoClosingChunk() throws IOException {
-        String s = "5\r\n01234\r\n";
-        ChunkedInputStream in = new ChunkedInputStream(
+        final String s = "5\r\n01234\r\n";
+        final ChunkedInputStream in = new ChunkedInputStream(
                 new SessionInputBufferMock(
                         EncodingUtils.getBytes(s, CONTENT_CHARSET)));
-        byte[] tmp = new byte[5];
+        final byte[] tmp = new byte[5];
         Assert.assertEquals(5, in.read(tmp));
         Assert.assertEquals(-1, in.read());
-    }
+        in.close();
+}
 
     // Missing \r\n at the end of the first chunk
     @Test
     public void testCorruptChunkedInputStreamMissingCRLF() throws IOException {
-        String s = "5\r\n012345\r\n56789\r\n0\r\n";
-        InputStream in = new ChunkedInputStream(
+        final String s = "5\r\n012345\r\n56789\r\n0\r\n";
+        final InputStream in = new ChunkedInputStream(
                 new SessionInputBufferMock(
                         EncodingUtils.getBytes(s, CONTENT_CHARSET)));
-        byte[] buffer = new byte[300];
-        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        final byte[] buffer = new byte[300];
+        final ByteArrayOutputStream out = new ByteArrayOutputStream();
         int len;
         try {
             while ((len = in.read(buffer)) > 0) {
                 out.write(buffer, 0, len);
             }
             Assert.fail("MalformedChunkCodingException should have been thrown");
-        } catch(MalformedChunkCodingException e) {
+        } catch(final MalformedChunkCodingException e) {
             /* expected exception */
         }
     }
@@ -235,125 +238,138 @@ public class TestChunkCoding {
     // Missing LF
     @Test
     public void testCorruptChunkedInputStreamMissingLF() throws IOException {
-        String s = "5\r01234\r\n5\r\n56789\r\n0\r\n";
-        InputStream in = new ChunkedInputStream(
+        final String s = "5\r01234\r\n5\r\n56789\r\n0\r\n";
+        final InputStream in = new ChunkedInputStream(
                 new SessionInputBufferMock(
                         EncodingUtils.getBytes(s, CONTENT_CHARSET)));
         try {
             in.read();
             Assert.fail("MalformedChunkCodingException should have been thrown");
-        } catch(MalformedChunkCodingException e) {
+        } catch(final MalformedChunkCodingException e) {
             /* expected exception */
         }
-    }
+        in.close();
+}
 
     // Invalid chunk size
     @Test
     public void testCorruptChunkedInputStreamInvalidSize() throws IOException {
-        String s = "whatever\r\n01234\r\n5\r\n56789\r\n0\r\n";
-        InputStream in = new ChunkedInputStream(
+        final String s = "whatever\r\n01234\r\n5\r\n56789\r\n0\r\n";
+        final InputStream in = new ChunkedInputStream(
                 new SessionInputBufferMock(
                         EncodingUtils.getBytes(s, CONTENT_CHARSET)));
         try {
             in.read();
             Assert.fail("MalformedChunkCodingException should have been thrown");
-        } catch(MalformedChunkCodingException e) {
+        } catch(final MalformedChunkCodingException e) {
             /* expected exception */
         }
-    }
+        try {
+            in.close();
+        } catch (TruncatedChunkException expected) {
+        }
+}
 
     // Negative chunk size
     @Test
     public void testCorruptChunkedInputStreamNegativeSize() throws IOException {
-        String s = "-5\r\n01234\r\n5\r\n56789\r\n0\r\n";
-        InputStream in = new ChunkedInputStream(
+        final String s = "-5\r\n01234\r\n5\r\n56789\r\n0\r\n";
+        final InputStream in = new ChunkedInputStream(
                 new SessionInputBufferMock(
                         EncodingUtils.getBytes(s, CONTENT_CHARSET)));
         try {
             in.read();
             Assert.fail("MalformedChunkCodingException should have been thrown");
-        } catch(MalformedChunkCodingException e) {
+        } catch(final MalformedChunkCodingException e) {
             /* expected exception */
         }
-    }
+        try {
+            in.close();
+        } catch (TruncatedChunkException expected) {
+        }
+}
 
     // Truncated chunk
     @Test
     public void testCorruptChunkedInputStreamTruncatedChunk() throws IOException {
-        String s = "3\r\n12";
-        InputStream in = new ChunkedInputStream(
+        final String s = "3\r\n12";
+        final InputStream in = new ChunkedInputStream(
                 new SessionInputBufferMock(
                         EncodingUtils.getBytes(s, CONTENT_CHARSET)));
-        byte[] buffer = new byte[300];
+        final byte[] buffer = new byte[300];
         Assert.assertEquals(2, in.read(buffer));
         try {
             in.read(buffer);
             Assert.fail("MalformedChunkCodingException should have been thrown");
-        } catch(MalformedChunkCodingException e) {
+        } catch(final MalformedChunkCodingException e) {
             /* expected exception */
         }
-    }
+        in.close();
+}
 
     // Invalid footer
     @Test
     public void testCorruptChunkedInputStreamInvalidFooter() throws IOException {
-        String s = "1\r\n0\r\n0\r\nstuff\r\n";
-        InputStream in = new ChunkedInputStream(
+        final String s = "1\r\n0\r\n0\r\nstuff\r\n";
+        final InputStream in = new ChunkedInputStream(
                 new SessionInputBufferMock(
                         EncodingUtils.getBytes(s, CONTENT_CHARSET)));
         try {
             in.read();
             in.read();
             Assert.fail("MalformedChunkCodingException should have been thrown");
-        } catch(MalformedChunkCodingException e) {
+        } catch(final MalformedChunkCodingException e) {
             /* expected exception */
         }
-    }
+        in.close();
+}
 
     @Test
     public void testEmptyChunkedInputStream() throws IOException {
-        String input = "0\r\n";
-        InputStream in = new ChunkedInputStream(
+        final String input = "0\r\n";
+        final InputStream in = new ChunkedInputStream(
                 new SessionInputBufferMock(
                         EncodingUtils.getBytes(input, CONTENT_CHARSET)));
-        byte[] buffer = new byte[300];
-        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        final byte[] buffer = new byte[300];
+        final ByteArrayOutputStream out = new ByteArrayOutputStream();
         int len;
         while ((len = in.read(buffer)) > 0) {
             out.write(buffer, 0, len);
         }
         Assert.assertEquals(0, out.size());
-    }
+        in.close();
+}
 
     @Test
     public void testChunkedConsistence() throws IOException {
-        String input = "76126;27823abcd;:q38a-\nkjc\rk%1ad\tkh/asdui\r\njkh+?\\suweb";
-        ByteArrayOutputStream buffer = new ByteArrayOutputStream();
-        OutputStream out = new ChunkedOutputStream(new SessionOutputBufferMock(buffer));
+        final String input = "76126;27823abcd;:q38a-\nkjc\rk%1ad\tkh/asdui\r\njkh+?\\suweb";
+        final ByteArrayOutputStream buffer = new ByteArrayOutputStream();
+        final OutputStream out = new ChunkedOutputStream(2048, new SessionOutputBufferMock(buffer));
         out.write(EncodingUtils.getBytes(input, CONTENT_CHARSET));
         out.flush();
         out.close();
         out.close();
         buffer.close();
-        InputStream in = new ChunkedInputStream(
+        final InputStream in = new ChunkedInputStream(
                 new SessionInputBufferMock(
                         buffer.toByteArray()));
 
-        byte[] d = new byte[10];
-        ByteArrayOutputStream result = new ByteArrayOutputStream();
+        final byte[] d = new byte[10];
+        final ByteArrayOutputStream result = new ByteArrayOutputStream();
         int len = 0;
         while ((len = in.read(d)) > 0) {
             result.write(d, 0, len);
         }
 
-        String output = EncodingUtils.getString(result.toByteArray(), CONTENT_CHARSET);
+        final String output = EncodingUtils.getString(result.toByteArray(), CONTENT_CHARSET);
         Assert.assertEquals(input, output);
-    }
+        in.close();
+}
 
     @Test
     public void testChunkedOutputStream() throws IOException {
-        SessionOutputBufferMock buffer = new SessionOutputBufferMock();
-        ChunkedOutputStream out = new ChunkedOutputStream(buffer, 2);
+        final SessionOutputBufferMock buffer = new SessionOutputBufferMock();
+        final ChunkedOutputStream out = new ChunkedOutputStream(2, buffer);
         out.write('1');
         out.write('2');
         out.write('3');
@@ -361,7 +377,7 @@ public class TestChunkCoding {
         out.finish();
         out.close();
 
-        byte [] rawdata =  buffer.getData();
+        final byte [] rawdata =  buffer.getData();
 
         Assert.assertEquals(19, rawdata.length);
         Assert.assertEquals('2', rawdata[0]);
@@ -387,13 +403,13 @@ public class TestChunkCoding {
 
     @Test
     public void testChunkedOutputStreamLargeChunk() throws IOException {
-        SessionOutputBufferMock buffer = new SessionOutputBufferMock();
-        ChunkedOutputStream out = new ChunkedOutputStream(buffer, 2);
+        final SessionOutputBufferMock buffer = new SessionOutputBufferMock();
+        final ChunkedOutputStream out = new ChunkedOutputStream(2, buffer);
         out.write(new byte[] {'1', '2', '3', '4'});
         out.finish();
         out.close();
 
-        byte [] rawdata =  buffer.getData();
+        final byte [] rawdata =  buffer.getData();
 
         Assert.assertEquals(14, rawdata.length);
         Assert.assertEquals('4', rawdata[0]);
@@ -414,14 +430,13 @@ public class TestChunkCoding {
 
     @Test
     public void testChunkedOutputStreamSmallChunk() throws IOException {
-        ByteArrayOutputStream buffer = new ByteArrayOutputStream();
-        ChunkedOutputStream out = new ChunkedOutputStream(
-                new SessionOutputBufferMock(buffer), 2);
+        final ByteArrayOutputStream buffer = new ByteArrayOutputStream();
+        final ChunkedOutputStream out = new ChunkedOutputStream(2, new SessionOutputBufferMock(buffer));
         out.write('1');
         out.finish();
         out.close();
 
-        byte [] rawdata =  buffer.toByteArray();
+        final byte [] rawdata =  buffer.toByteArray();
 
         Assert.assertEquals(11, rawdata.length);
         Assert.assertEquals('1', rawdata[0]);
@@ -439,12 +454,12 @@ public class TestChunkCoding {
 
     @Test
     public void testResumeOnSocketTimeoutInData() throws IOException {
-        String s = "5\r\n01234\r\n5\r\n5\0006789\r\na\r\n0123\000456789\r\n0\r\n";
-        SessionInputBuffer sessbuf = new SessionInputBufferMock(
+        final String s = "5\r\n01234\r\n5\r\n5\0006789\r\na\r\n0123\000456789\r\n0\r\n";
+        final SessionInputBuffer sessbuf = new SessionInputBufferMock(
                 new TimeoutByteArrayInputStream(s.getBytes("ISO-8859-1")), 16);
-        InputStream in = new ChunkedInputStream(sessbuf);
+        final InputStream in = new ChunkedInputStream(sessbuf);
 
-        byte[] tmp = new byte[3];
+        final byte[] tmp = new byte[3];
 
         int bytesRead = 0;
         int timeouts = 0;
@@ -456,22 +471,23 @@ public class TestChunkCoding {
                 if (i > 0) {
                     bytesRead += i;
                 }
-            } catch (InterruptedIOException ex) {
+            } catch (final InterruptedIOException ex) {
                 timeouts++;
             }
         }
         Assert.assertEquals(20, bytesRead);
         Assert.assertEquals(2, timeouts);
-    }
+        in.close();
+}
 
     @Test
     public void testResumeOnSocketTimeoutInChunk() throws IOException {
-        String s = "5\000\r\000\n\00001234\r\n\0005\r\n56789\r\na\r\n0123456789\r\n\0000\r\n";
-        SessionInputBuffer sessbuf = new SessionInputBufferMock(
+        final String s = "5\000\r\000\n\00001234\r\n\0005\r\n56789\r\na\r\n0123456789\r\n\0000\r\n";
+        final SessionInputBuffer sessbuf = new SessionInputBufferMock(
                 new TimeoutByteArrayInputStream(s.getBytes("ISO-8859-1")), 16);
-        InputStream in = new ChunkedInputStream(sessbuf);
+        final InputStream in = new ChunkedInputStream(sessbuf);
 
-        byte[] tmp = new byte[3];
+        final byte[] tmp = new byte[3];
 
         int bytesRead = 0;
         int timeouts = 0;
@@ -483,13 +499,14 @@ public class TestChunkCoding {
                 if (i > 0) {
                     bytesRead += i;
                 }
-            } catch (InterruptedIOException ex) {
+            } catch (final InterruptedIOException ex) {
                 timeouts++;
             }
         }
         Assert.assertEquals(20, bytesRead);
         Assert.assertEquals(5, timeouts);
-    }
+        in.close();
+}
 
 }
 
diff --git a/httpcore/src/test/java/org/apache/http/impl/io/TestContentLengthInputStream.java b/httpcore/src/test/java/org/apache/http/impl/io/TestContentLengthInputStream.java
index bf5e79b..d905b3a 100644
--- a/httpcore/src/test/java/org/apache/http/impl/io/TestContentLengthInputStream.java
+++ b/httpcore/src/test/java/org/apache/http/impl/io/TestContentLengthInputStream.java
@@ -44,36 +44,39 @@ public class TestContentLengthInputStream {
 
     @Test
     public void testConstructors() throws Exception {
-        new ContentLengthInputStream(new SessionInputBufferMock(new byte[] {}), 10);
+        final ContentLengthInputStream in = new ContentLengthInputStream(
+                new SessionInputBufferMock(new byte[] {}), 0);
+        in.close();
         try {
             new ContentLengthInputStream(null, 10);
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
             // expected
         }
         try {
             new ContentLengthInputStream(new SessionInputBufferMock(new byte[] {}), -10);
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
             // expected
         }
     }
 
     @Test
     public void testBasics() throws IOException {
-        String correct = "1234567890123456";
-        InputStream in = new ContentLengthInputStream(new SessionInputBufferMock(
+        final String correct = "1234567890123456";
+        final InputStream in = new ContentLengthInputStream(new SessionInputBufferMock(
             EncodingUtils.getBytes(correct, CONTENT_CHARSET)), 10L);
-        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        final ByteArrayOutputStream out = new ByteArrayOutputStream();
 
-        byte[] buffer = new byte[50];
+        final byte[] buffer = new byte[50];
         int len = in.read(buffer, 0, 2);
         out.write(buffer, 0, len);
         len = in.read(buffer);
         out.write(buffer, 0, len);
 
-        String result = EncodingUtils.getString(out.toByteArray(), CONTENT_CHARSET);
+        final String result = EncodingUtils.getString(out.toByteArray(), CONTENT_CHARSET);
         Assert.assertEquals(result, "1234567890");
+        in.close();
     }
 
     @Test
@@ -86,6 +89,7 @@ public class TestContentLengthInputStream {
         in.read();
         Assert.assertEquals(9, in.skip(10));
         Assert.assertTrue(in.read() == -1);
+        in.close();
 
         in = new ContentLengthInputStream(new SessionInputBufferMock(new byte[20]), 2L);
         in.read();
@@ -93,46 +97,49 @@ public class TestContentLengthInputStream {
         Assert.assertTrue(in.skip(10) <= 0);
         Assert.assertTrue(in.skip(-1) == 0);
         Assert.assertTrue(in.read() == -1);
+        in.close();
 
         in = new ContentLengthInputStream(new SessionInputBufferMock(new byte[20]), 10L);
         Assert.assertEquals(5,in.skip(5));
         Assert.assertEquals(5, in.read(new byte[20]));
+        in.close();
     }
 
     @Test
     public void testAvailable() throws IOException {
-        InputStream in = new ContentLengthInputStream(
-                new SessionInputBufferMock(new byte[] {1, 2, 3}), 10L);
+        final InputStream in = new ContentLengthInputStream(
+                new SessionInputBufferMock(new byte[] {1, 2, 3}), 3L);
         Assert.assertEquals(0, in.available());
         in.read();
         Assert.assertEquals(2, in.available());
+        in.close();
     }
 
     @Test
     public void testClose() throws IOException {
-        String correct = "1234567890123456-";
-        SessionInputBuffer inbuffer = new SessionInputBufferMock(EncodingUtils.getBytes(
+        final String correct = "1234567890123456-";
+        final SessionInputBuffer inbuffer = new SessionInputBufferMock(EncodingUtils.getBytes(
                 correct, CONTENT_CHARSET));
-        InputStream in = new ContentLengthInputStream(inbuffer, 16L);
+        final InputStream in = new ContentLengthInputStream(inbuffer, 16L);
         in.close();
         in.close();
         try {
             in.read();
             Assert.fail("IOException should have been thrown");
-        } catch (IOException ex) {
+        } catch (final IOException ex) {
             // expected
         }
-        byte[] tmp = new byte[10];
+        final byte[] tmp = new byte[10];
         try {
             in.read(tmp);
             Assert.fail("IOException should have been thrown");
-        } catch (IOException ex) {
+        } catch (final IOException ex) {
             // expected
         }
         try {
             in.read(tmp, 0, tmp.length);
             Assert.fail("IOException should have been thrown");
-        } catch (IOException ex) {
+        } catch (final IOException ex) {
             // expected
         }
         Assert.assertEquals('-', inbuffer.read());
@@ -140,22 +147,27 @@ public class TestContentLengthInputStream {
 
     @Test
     public void testTruncatedContent() throws IOException {
-        String correct = "1234567890123456";
-        SessionInputBuffer inbuffer = new SessionInputBufferMock(EncodingUtils.getBytes(
+        final String correct = "1234567890123456";
+        final SessionInputBuffer inbuffer = new SessionInputBufferMock(EncodingUtils.getBytes(
                 correct, CONTENT_CHARSET));
-        InputStream in = new ContentLengthInputStream(inbuffer, 32L);
-        byte[] tmp = new byte[32];
-        int byteRead = in.read(tmp);
+        final InputStream in = new ContentLengthInputStream(inbuffer, 32L);
+        final byte[] tmp = new byte[32];
+        final int byteRead = in.read(tmp);
         Assert.assertEquals(16, byteRead);
         try {
             in.read(tmp);
             Assert.fail("ConnectionClosedException should have been closed");
-        } catch (ConnectionClosedException ex) {
+        } catch (final ConnectionClosedException ex) {
         }
         try {
             in.read();
             Assert.fail("ConnectionClosedException should have been closed");
-        } catch (ConnectionClosedException ex) {
+        } catch (final ConnectionClosedException ex) {
+        }
+        try {
+            in.close();
+            Assert.fail("ConnectionClosedException should have been closed");
+        } catch (final ConnectionClosedException ex) {
         }
     }
 
diff --git a/httpcore/src/test/java/org/apache/http/impl/io/TestContentLengthOutputStream.java b/httpcore/src/test/java/org/apache/http/impl/io/TestContentLengthOutputStream.java
index 0ef1010..9339fe0 100644
--- a/httpcore/src/test/java/org/apache/http/impl/io/TestContentLengthOutputStream.java
+++ b/httpcore/src/test/java/org/apache/http/impl/io/TestContentLengthOutputStream.java
@@ -39,28 +39,30 @@ public class TestContentLengthOutputStream {
 
     @Test
     public void testConstructors() throws Exception {
-        new ContentLengthOutputStream(new SessionOutputBufferMock(), 10L);
+        final ContentLengthOutputStream in = new ContentLengthOutputStream(
+                new SessionOutputBufferMock(), 10L);
+        in.close();
         try {
             new ContentLengthOutputStream(null, 10L);
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
             // expected
         }
         try {
             new ContentLengthOutputStream(new SessionOutputBufferMock(), -10);
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
             // expected
         }
     }
 
     @Test
     public void testBasics() throws Exception {
-        ByteArrayOutputStream buffer = new ByteArrayOutputStream();
-        SessionOutputBufferMock datatransmitter = new SessionOutputBufferMock(buffer);
-        OutputStream out = new ContentLengthOutputStream(datatransmitter, 15L);
+        final ByteArrayOutputStream buffer = new ByteArrayOutputStream();
+        final SessionOutputBufferMock datatransmitter = new SessionOutputBufferMock(buffer);
+        final OutputStream out = new ContentLengthOutputStream(datatransmitter, 15L);
 
-        byte[] tmp = new byte[10];
+        final byte[] tmp = new byte[10];
         out.write(tmp, 0, 10);
         out.write(1);
         out.write(tmp, 0, 10);
@@ -70,28 +72,28 @@ public class TestContentLengthOutputStream {
         out.write(2);
         out.flush();
         out.close();
-        byte[] data = datatransmitter.getData();
+        final byte[] data = datatransmitter.getData();
         Assert.assertEquals(15, data.length);
     }
 
     @Test
     public void testClose() throws Exception {
-        ByteArrayOutputStream buffer = new ByteArrayOutputStream();
-        SessionOutputBufferMock datatransmitter = new SessionOutputBufferMock(buffer);
-        OutputStream out = new ContentLengthOutputStream(datatransmitter, 15L);
+        final ByteArrayOutputStream buffer = new ByteArrayOutputStream();
+        final SessionOutputBufferMock datatransmitter = new SessionOutputBufferMock(buffer);
+        final OutputStream out = new ContentLengthOutputStream(datatransmitter, 15L);
         out.close();
         out.close();
-        byte[] tmp = new byte[10];
+        final byte[] tmp = new byte[10];
         try {
             out.write(tmp);
             Assert.fail("IOException should have been thrown");
-        } catch (IOException ex) {
+        } catch (final IOException ex) {
             // expected
         }
         try {
             out.write(1);
             Assert.fail("IOException should have been thrown");
-        } catch (IOException ex) {
+        } catch (final IOException ex) {
             // expected
         }
     }
diff --git a/httpcore/src/test/java/org/apache/http/impl/io/TestIdentityInputStream.java b/httpcore/src/test/java/org/apache/http/impl/io/TestIdentityInputStream.java
index 01426d1..59a46b5 100644
--- a/httpcore/src/test/java/org/apache/http/impl/io/TestIdentityInputStream.java
+++ b/httpcore/src/test/java/org/apache/http/impl/io/TestIdentityInputStream.java
@@ -40,22 +40,23 @@ public class TestIdentityInputStream {
 
     @Test
     public void testConstructor() throws Exception {
-        SessionInputBuffer receiver = new SessionInputBufferMock(new byte[] {});
-        new IdentityInputStream(receiver);
+        final SessionInputBuffer receiver = new SessionInputBufferMock(new byte[] {});
+        final IdentityInputStream in = new IdentityInputStream(receiver);
+        in.close();
         try {
             new IdentityInputStream(null);
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
             //expected
         }
     }
 
     @Test
     public void testBasicRead() throws Exception {
-        byte[] input = new byte[] {'a', 'b', 'c'};
-        SessionInputBufferMock receiver = new SessionInputBufferMock(input);
-        IdentityInputStream instream = new IdentityInputStream(receiver);
-        byte[] tmp = new byte[2];
+        final byte[] input = new byte[] {'a', 'b', 'c'};
+        final SessionInputBufferMock receiver = new SessionInputBufferMock(input);
+        final IdentityInputStream instream = new IdentityInputStream(receiver);
+        final byte[] tmp = new byte[2];
         Assert.assertEquals(2, instream.read(tmp, 0, tmp.length));
         Assert.assertEquals('a', tmp[0]);
         Assert.assertEquals('b', tmp[1]);
@@ -64,19 +65,20 @@ public class TestIdentityInputStream {
         Assert.assertEquals(-1, instream.read());
         Assert.assertEquals(-1, instream.read(tmp, 0, tmp.length));
         Assert.assertEquals(-1, instream.read());
+        instream.close();
     }
 
     @Test
     public void testClosedCondition() throws Exception {
-        byte[] input = new byte[] {'a', 'b', 'c'};
-        SessionInputBufferMock receiver = new SessionInputBufferMock(input);
-        IdentityInputStream instream = new IdentityInputStream(receiver);
+        final byte[] input = new byte[] {'a', 'b', 'c'};
+        final SessionInputBufferMock receiver = new SessionInputBufferMock(input);
+        final IdentityInputStream instream = new IdentityInputStream(receiver);
 
         instream.close();
         instream.close();
 
         Assert.assertEquals(0, instream.available());
-        byte[] tmp = new byte[2];
+        final byte[] tmp = new byte[2];
         Assert.assertEquals(-1, instream.read(tmp, 0, tmp.length));
         Assert.assertEquals(-1, instream.read());
         Assert.assertEquals(-1, instream.read(tmp, 0, tmp.length));
@@ -85,11 +87,12 @@ public class TestIdentityInputStream {
 
     @Test
     public void testAvailable() throws Exception {
-        byte[] input = new byte[] {'a', 'b', 'c'};
-        SessionInputBufferMock receiver = new SessionInputBufferMock(input);
-        IdentityInputStream instream = new IdentityInputStream(receiver);
+        final byte[] input = new byte[] {'a', 'b', 'c'};
+        final SessionInputBufferMock receiver = new SessionInputBufferMock(input);
+        final IdentityInputStream instream = new IdentityInputStream(receiver);
         instream.read();
         Assert.assertEquals(2, instream.available());
+        instream.close();
     }
 
 }
diff --git a/httpcore/src/test/java/org/apache/http/impl/io/TestIdentityOutputStream.java b/httpcore/src/test/java/org/apache/http/impl/io/TestIdentityOutputStream.java
index 104aa9f..5b818c2 100644
--- a/httpcore/src/test/java/org/apache/http/impl/io/TestIdentityOutputStream.java
+++ b/httpcore/src/test/java/org/apache/http/impl/io/TestIdentityOutputStream.java
@@ -39,101 +39,102 @@ public class TestIdentityOutputStream {
 
     @Test
     public void testConstructors() throws Exception {
-        new IdentityOutputStream(new SessionOutputBufferMock());
+        new IdentityOutputStream(new SessionOutputBufferMock()).close();
         try {
             new IdentityOutputStream(null);
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
             // expected
         }
     }
 
     @Test
     public void testBasics() throws Exception {
-        ByteArrayOutputStream buffer = new ByteArrayOutputStream();
-        SessionOutputBufferMock datatransmitter = new SessionOutputBufferMock(buffer);
-        OutputStream out = new IdentityOutputStream(datatransmitter);
+        final ByteArrayOutputStream buffer = new ByteArrayOutputStream();
+        final SessionOutputBufferMock datatransmitter = new SessionOutputBufferMock(buffer);
+        final OutputStream out = new IdentityOutputStream(datatransmitter);
 
-        byte[] tmp = new byte[10];
+        final byte[] tmp = new byte[10];
         out.write(tmp, 0, 10);
         out.write(tmp);
         out.write(1);
         out.flush();
         out.close();
-        byte[] data = datatransmitter.getData();
+        final byte[] data = datatransmitter.getData();
         Assert.assertEquals(21, data.length);
     }
 
     @Test
     public void testClose() throws Exception {
-        ByteArrayOutputStream buffer = new ByteArrayOutputStream();
-        SessionOutputBufferMock datatransmitter = new SessionOutputBufferMock(buffer);
-        OutputStream out = new IdentityOutputStream(datatransmitter);
+        final ByteArrayOutputStream buffer = new ByteArrayOutputStream();
+        final SessionOutputBufferMock datatransmitter = new SessionOutputBufferMock(buffer);
+        final OutputStream out = new IdentityOutputStream(datatransmitter);
         out.close();
         out.close();
-        byte[] tmp = new byte[10];
+        final byte[] tmp = new byte[10];
         try {
             out.write(tmp);
             Assert.fail("IOException should have been thrown");
-        } catch (IOException ex) {
+        } catch (final IOException ex) {
             // expected
         }
         try {
             out.write(1);
             Assert.fail("IOException should have been thrown");
-        } catch (IOException ex) {
+        } catch (final IOException ex) {
             // expected
         }
     }
 
     @Test
     public void testConstructor() throws Exception {
-        SessionOutputBufferMock transmitter = new SessionOutputBufferMock();
-        new IdentityOutputStream(transmitter);
+        final SessionOutputBufferMock transmitter = new SessionOutputBufferMock();
+        new IdentityOutputStream(transmitter).close();
         try {
             new IdentityOutputStream(null);
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
             //expected
         }
     }
 
     @Test
     public void testBasicWrite() throws Exception {
-        SessionOutputBufferMock transmitter = new SessionOutputBufferMock();
-        IdentityOutputStream outstream = new IdentityOutputStream(transmitter);
+        final SessionOutputBufferMock transmitter = new SessionOutputBufferMock();
+        final IdentityOutputStream outstream = new IdentityOutputStream(transmitter);
         outstream.write(new byte[] {'a', 'b'}, 0, 2);
         outstream.write('c');
         outstream.flush();
 
-        byte[] input = transmitter.getData();
+        final byte[] input = transmitter.getData();
 
         Assert.assertNotNull(input);
-        byte[] expected = new byte[] {'a', 'b', 'c'};
+        final byte[] expected = new byte[] {'a', 'b', 'c'};
         Assert.assertEquals(expected.length, input.length);
         for (int i = 0; i < expected.length; i++) {
             Assert.assertEquals(expected[i], input[i]);
         }
+        outstream.close();
     }
 
     @Test
     public void testClosedCondition() throws Exception {
-        SessionOutputBufferMock transmitter = new SessionOutputBufferMock();
-        IdentityOutputStream outstream = new IdentityOutputStream(transmitter);
+        final SessionOutputBufferMock transmitter = new SessionOutputBufferMock();
+        final IdentityOutputStream outstream = new IdentityOutputStream(transmitter);
         outstream.close();
         outstream.close();
 
         try {
-            byte[] tmp = new byte[2];
+            final byte[] tmp = new byte[2];
             outstream.write(tmp, 0, tmp.length);
             Assert.fail("IOException should have been thrown");
-        } catch (IOException e) {
+        } catch (final IOException e) {
             //expected
         }
         try {
             outstream.write('a');
             Assert.fail("IOException should have been thrown");
-        } catch (IOException e) {
+        } catch (final IOException e) {
             //expected
         }
     }
diff --git a/httpcore/src/test/java/org/apache/http/impl/io/TestMessageParser.java b/httpcore/src/test/java/org/apache/http/impl/io/TestMessageParser.java
index ecb5852..3852973 100644
--- a/httpcore/src/test/java/org/apache/http/impl/io/TestMessageParser.java
+++ b/httpcore/src/test/java/org/apache/http/impl/io/TestMessageParser.java
@@ -29,6 +29,7 @@ package org.apache.http.impl.io;
 
 import java.io.IOException;
 
+import org.apache.http.Consts;
 import org.apache.http.Header;
 import org.apache.http.HeaderElement;
 import org.apache.http.NameValuePair;
@@ -50,20 +51,20 @@ public class TestMessageParser {
             // the first argument must not be null
             AbstractMessageParser.parseHeaders(null, -1, -1, null);
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
             // expected
         }
         try {
             new BufferedHeader(null);
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
             // expected
         }
     }
 
     @Test
     public void testBasicHeaderParsing() throws Exception {
-        String s =
+        final String s =
             "header1: stuff\r\n" +
             "header2  : stuff \r\n" +
             "header3: stuff\r\n" +
@@ -71,8 +72,8 @@ public class TestMessageParser {
             "\t and even more stuff\r\n" +
             "     \r\n" +
             "\r\n";
-        SessionInputBuffer receiver = new SessionInputBufferMock(s, "US-ASCII");
-        Header[] headers = AbstractMessageParser.parseHeaders
+        final SessionInputBuffer receiver = new SessionInputBufferMock(s, Consts.ASCII);
+        final Header[] headers = AbstractMessageParser.parseHeaders
             (receiver, -1, -1, null);
         Assert.assertNotNull(headers);
         Assert.assertEquals(3, headers.length);
@@ -83,7 +84,7 @@ public class TestMessageParser {
         Assert.assertEquals("header3", headers[2].getName());
         Assert.assertEquals("stuff and more stuff and even more stuff", headers[2].getValue());
 
-        Header h = headers[0];
+        final Header h = headers[0];
 
         Assert.assertTrue(h instanceof BufferedHeader);
         Assert.assertNotNull(((BufferedHeader)h).getBuffer());
@@ -93,21 +94,21 @@ public class TestMessageParser {
 
     @Test
     public void testBufferedHeader() throws Exception {
-        String s =
+        final String s =
             "header1  : stuff; param1 = value1; param2 = \"value 2\" \r\n" +
             "\r\n";
-        SessionInputBuffer receiver = new SessionInputBufferMock(s, "US-ASCII");
-        Header[] headers = AbstractMessageParser.parseHeaders
+        final SessionInputBuffer receiver = new SessionInputBufferMock(s, Consts.ASCII);
+        final Header[] headers = AbstractMessageParser.parseHeaders
             (receiver, -1, -1, null);
         Assert.assertNotNull(headers);
         Assert.assertEquals(1, headers.length);
         Assert.assertEquals("header1  : stuff; param1 = value1; param2 = \"value 2\" ", headers[0].toString());
-        HeaderElement[] elements = headers[0].getElements();
+        final HeaderElement[] elements = headers[0].getElements();
         Assert.assertNotNull(elements);
         Assert.assertEquals(1, elements.length);
         Assert.assertEquals("stuff", elements[0].getName());
         Assert.assertEquals(null, elements[0].getValue());
-        NameValuePair[] params = elements[0].getParameters();
+        final NameValuePair[] params = elements[0].getParameters();
         Assert.assertNotNull(params);
         Assert.assertEquals(2, params.length);
         Assert.assertEquals("param1", params[0].getName());
@@ -121,32 +122,32 @@ public class TestMessageParser {
         String s = "    stuff\r\n" +
             "header1: stuff\r\n" +
             "\r\n";
-        SessionInputBuffer receiver = new SessionInputBufferMock(s, "US-ASCII");
+        SessionInputBuffer receiver = new SessionInputBufferMock(s, Consts.ASCII);
         try {
             AbstractMessageParser.parseHeaders(receiver, -1, -1, null);
             Assert.fail("ProtocolException should have been thrown");
-        } catch (ProtocolException ex) {
+        } catch (final ProtocolException ex) {
             // expected
         }
         s = "  :  stuff\r\n" +
             "header1: stuff\r\n" +
             "\r\n";
-        receiver = new SessionInputBufferMock(s, "US-ASCII");
+        receiver = new SessionInputBufferMock(s, Consts.ASCII);
         try {
             AbstractMessageParser.parseHeaders(receiver, -1, -1, null);
             Assert.fail("ProtocolException should have been thrown");
-        } catch (ProtocolException ex) {
+        } catch (final ProtocolException ex) {
             // expected
         }
     }
 
     @Test
     public void testParsingMalformedFirstHeader() throws Exception {
-        String s =
+        final String s =
             "    header1: stuff\r\n" +
             "header2  : stuff \r\n";
-        SessionInputBuffer receiver = new SessionInputBufferMock(s, "US-ASCII");
-        Header[] headers = AbstractMessageParser.parseHeaders
+        final SessionInputBuffer receiver = new SessionInputBufferMock(s, Consts.ASCII);
+        final Header[] headers = AbstractMessageParser.parseHeaders
             (receiver, -1, -1, null);
         Assert.assertNotNull(headers);
         Assert.assertEquals(2, headers.length);
@@ -158,9 +159,9 @@ public class TestMessageParser {
 
     @Test
     public void testEmptyDataStream() throws Exception {
-        String s = "";
-        SessionInputBuffer receiver = new SessionInputBufferMock(s, "US-ASCII");
-        Header[] headers = AbstractMessageParser.parseHeaders
+        final String s = "";
+        final SessionInputBuffer receiver = new SessionInputBufferMock(s, Consts.ASCII);
+        final Header[] headers = AbstractMessageParser.parseHeaders
             (receiver, -1, -1, null);
         Assert.assertNotNull(headers);
         Assert.assertEquals(0, headers.length);
@@ -168,32 +169,32 @@ public class TestMessageParser {
 
     @Test
     public void testMaxHeaderCount() throws Exception {
-        String s =
+        final String s =
             "header1: stuff\r\n" +
             "header2: stuff \r\n" +
             "header3: stuff\r\n" +
             "\r\n";
-        SessionInputBuffer receiver = new SessionInputBufferMock(s, "US-ASCII");
+        final SessionInputBuffer receiver = new SessionInputBufferMock(s, Consts.ASCII);
         try {
             AbstractMessageParser.parseHeaders(receiver, 2, -1, null);
             Assert.fail("IOException should have been thrown");
-        } catch (IOException ex) {
+        } catch (final IOException ex) {
             // expected
         }
     }
 
     @Test
     public void testMaxHeaderCountForFoldedHeader() throws Exception {
-        String s =
+        final String s =
             "header1: stuff\r\n" +
             " stuff \r\n" +
             " stuff\r\n" +
             "\r\n";
-        SessionInputBuffer receiver = new SessionInputBufferMock(s, "US-ASCII");
+        final SessionInputBuffer receiver = new SessionInputBufferMock(s, Consts.ASCII);
         try {
             AbstractMessageParser.parseHeaders(receiver, 2, 15, null);
             Assert.fail("IOException should have been thrown");
-        } catch (IOException ex) {
+        } catch (final IOException ex) {
             // expected
         }
     }
diff --git a/httpcore/src/test/java/org/apache/http/impl/io/TestRequestParser.java b/httpcore/src/test/java/org/apache/http/impl/io/TestRequestParser.java
index c36fac4..651fc38 100644
--- a/httpcore/src/test/java/org/apache/http/impl/io/TestRequestParser.java
+++ b/httpcore/src/test/java/org/apache/http/impl/io/TestRequestParser.java
@@ -1,8 +1,4 @@
 /*
- * $HeadURL$
- * $Revision$
- * $Date$
- *
  * ====================================================================
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements.  See the NOTICE file
@@ -28,21 +24,18 @@
  * <http://www.apache.org/>.
  *
  */
-
 package org.apache.http.impl.io;
 
 import java.io.InterruptedIOException;
 
 import org.apache.http.ConnectionClosedException;
+import org.apache.http.Consts;
 import org.apache.http.Header;
 import org.apache.http.HttpRequest;
 import org.apache.http.HttpVersion;
 import org.apache.http.RequestLine;
-import org.apache.http.impl.DefaultHttpRequestFactory;
 import org.apache.http.impl.SessionInputBufferMock;
 import org.apache.http.io.SessionInputBuffer;
-import org.apache.http.message.BasicLineParser;
-import org.apache.http.params.BasicHttpParams;
 import org.junit.Assert;
 import org.junit.Test;
 
@@ -51,102 +44,57 @@ import org.junit.Test;
  */
 public class TestRequestParser {
 
-    @Test
+    @Test(expected=IllegalArgumentException.class)
     public void testInvalidConstructorInput() throws Exception {
-        try {
-            new DefaultHttpRequestParser(
-                    null,
-                    BasicLineParser.DEFAULT,
-                    new DefaultHttpRequestFactory(),
-                    new BasicHttpParams());
-            Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
-            // expected
-        }
-        try {
-            SessionInputBuffer inbuffer = new SessionInputBufferMock(new byte[] {});
-            new DefaultHttpRequestParser(
-                    inbuffer,
-                    BasicLineParser.DEFAULT,
-                    null,
-                    new BasicHttpParams());
-            Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
-            // expected
-        }
-        try {
-            SessionInputBuffer inbuffer = new SessionInputBufferMock(new byte[] {});
-            new DefaultHttpRequestParser(
-                    inbuffer,
-                    BasicLineParser.DEFAULT,
-                    new DefaultHttpRequestFactory(),
-                    null);
-            Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
-            // expected
-        }
+        new DefaultHttpRequestParser(null);
     }
 
     @Test
     public void testBasicMessageParsing() throws Exception {
-        String s =
+        final String s =
             "GET / HTTP/1.1\r\n" +
             "Host: localhost\r\n" +
             "User-Agent: whatever\r\n" +
             "Cookie: c1=stuff\r\n" +
             "\r\n";
-        SessionInputBuffer inbuffer = new SessionInputBufferMock(s, "US-ASCII");
+        final SessionInputBuffer inbuffer = new SessionInputBufferMock(s, Consts.ASCII);
 
-        DefaultHttpRequestParser parser = new DefaultHttpRequestParser(
-                inbuffer,
-                BasicLineParser.DEFAULT,
-                new DefaultHttpRequestFactory(),
-                new BasicHttpParams());
+        final DefaultHttpRequestParser parser = new DefaultHttpRequestParser(inbuffer);
+        final HttpRequest httprequest = parser.parse();
 
-        HttpRequest httprequest = parser.parse();
-
-        RequestLine reqline = httprequest.getRequestLine();
+        final RequestLine reqline = httprequest.getRequestLine();
         Assert.assertNotNull(reqline);
         Assert.assertEquals("GET", reqline.getMethod());
         Assert.assertEquals("/", reqline.getUri());
         Assert.assertEquals(HttpVersion.HTTP_1_1, reqline.getProtocolVersion());
-        Header[] headers = httprequest.getAllHeaders();
+        final Header[] headers = httprequest.getAllHeaders();
         Assert.assertEquals(3, headers.length);
     }
 
     @Test
     public void testConnectionClosedException() throws Exception {
-        SessionInputBuffer inbuffer = new SessionInputBufferMock(new byte[] {});
-
-        DefaultHttpRequestParser parser = new DefaultHttpRequestParser(
-                inbuffer,
-                BasicLineParser.DEFAULT,
-                new DefaultHttpRequestFactory(),
-                new BasicHttpParams());
+        final SessionInputBuffer inbuffer = new SessionInputBufferMock(new byte[] {});
 
+        final DefaultHttpRequestParser parser = new DefaultHttpRequestParser(inbuffer);
         try {
             parser.parse();
             Assert.fail("ConnectionClosedException should have been thrown");
-        } catch (ConnectionClosedException expected) {
+        } catch (final ConnectionClosedException expected) {
         }
     }
 
     @Test
     public void testMessageParsingTimeout() throws Exception {
-        String s =
+        final String s =
             "GET \000/ HTTP/1.1\r\000\n" +
             "Host: loca\000lhost\r\n" +
             "User-Agent: whatever\r\n" +
             "Coo\000kie: c1=stuff\r\n" +
             "\000\r\n";
-        SessionInputBuffer inbuffer = new SessionInputBufferMock(
+        final SessionInputBuffer inbuffer = new SessionInputBufferMock(
                 new TimeoutByteArrayInputStream(s.getBytes("US-ASCII")), 16);
 
-        DefaultHttpRequestParser parser = new DefaultHttpRequestParser(
-                inbuffer,
-                BasicLineParser.DEFAULT,
-                new DefaultHttpRequestFactory(),
-                new BasicHttpParams());
+        final DefaultHttpRequestParser parser = new DefaultHttpRequestParser(inbuffer);
 
         int timeoutCount = 0;
 
@@ -155,7 +103,7 @@ public class TestRequestParser {
             try {
                 httprequest = parser.parse();
                 break;
-            } catch (InterruptedIOException ex) {
+            } catch (final InterruptedIOException ex) {
                 timeoutCount++;
             }
 
@@ -164,12 +112,13 @@ public class TestRequestParser {
         Assert.assertEquals(5, timeoutCount);
 
         @SuppressWarnings("null") // httprequest cannot be null here
+        final
         RequestLine reqline = httprequest.getRequestLine();
         Assert.assertNotNull(reqline);
         Assert.assertEquals("GET", reqline.getMethod());
         Assert.assertEquals("/", reqline.getUri());
         Assert.assertEquals(HttpVersion.HTTP_1_1, reqline.getProtocolVersion());
-        Header[] headers = httprequest.getAllHeaders();
+        final Header[] headers = httprequest.getAllHeaders();
         Assert.assertEquals(3, headers.length);
     }
 
diff --git a/httpcore/src/test/java/org/apache/http/impl/io/TestResponseParser.java b/httpcore/src/test/java/org/apache/http/impl/io/TestResponseParser.java
index 011d624..6a3c158 100644
--- a/httpcore/src/test/java/org/apache/http/impl/io/TestResponseParser.java
+++ b/httpcore/src/test/java/org/apache/http/impl/io/TestResponseParser.java
@@ -29,120 +29,73 @@ package org.apache.http.impl.io;
 
 import java.io.InterruptedIOException;
 
+import org.apache.http.Consts;
 import org.apache.http.Header;
 import org.apache.http.HttpResponse;
 import org.apache.http.HttpVersion;
 import org.apache.http.NoHttpResponseException;
 import org.apache.http.StatusLine;
-import org.apache.http.impl.DefaultHttpResponseFactory;
 import org.apache.http.impl.SessionInputBufferMock;
 import org.apache.http.io.SessionInputBuffer;
-import org.apache.http.message.BasicLineParser;
-import org.apache.http.params.BasicHttpParams;
 import org.junit.Assert;
 import org.junit.Test;
 
 /**
- * Unit tests for {@link HttpResponseParser}.
+ * Unit tests for {@link DefaultHttpResponseParser}.
  */
 public class TestResponseParser {
 
-    @Test
+    @Test(expected=IllegalArgumentException.class)
     public void testInvalidConstructorInput() throws Exception {
-        try {
-            new DefaultHttpResponseParser(
-                    null,
-                    BasicLineParser.DEFAULT,
-                    new DefaultHttpResponseFactory(),
-                    new BasicHttpParams());
-            Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
-            // expected
-        }
-        try {
-            SessionInputBuffer inbuffer = new SessionInputBufferMock(new byte[] {});
-            new DefaultHttpResponseParser(
-                    inbuffer,
-                    BasicLineParser.DEFAULT,
-                    null,
-                    new BasicHttpParams());
-            Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
-            // expected
-        }
-        try {
-            SessionInputBuffer inbuffer = new SessionInputBufferMock(new byte[] {});
-            new DefaultHttpResponseParser(
-                    inbuffer,
-                    BasicLineParser.DEFAULT,
-                    new DefaultHttpResponseFactory(),
-                    null);
-            Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
-            // expected
-        }
+        new DefaultHttpResponseParser(null);
     }
 
     @Test
     public void testBasicMessageParsing() throws Exception {
-        String s =
+        final String s =
             "HTTP/1.1 200 OK\r\n" +
             "Server: whatever\r\n" +
             "Date: some date\r\n" +
             "Set-Cookie: c1=stuff\r\n" +
             "\r\n";
-        SessionInputBuffer inbuffer = new SessionInputBufferMock(s, "US-ASCII");
-
-        DefaultHttpResponseParser parser = new DefaultHttpResponseParser(
-                inbuffer,
-                BasicLineParser.DEFAULT,
-                new DefaultHttpResponseFactory(),
-                new BasicHttpParams());
+        final SessionInputBuffer inbuffer = new SessionInputBufferMock(s, Consts.ASCII);
 
-        HttpResponse httpresponse = parser.parse();
+        final DefaultHttpResponseParser parser = new DefaultHttpResponseParser(inbuffer);
+        final HttpResponse httpresponse = parser.parse();
 
-        StatusLine statusline = httpresponse.getStatusLine();
+        final StatusLine statusline = httpresponse.getStatusLine();
         Assert.assertNotNull(statusline);
         Assert.assertEquals(200, statusline.getStatusCode());
         Assert.assertEquals("OK", statusline.getReasonPhrase());
         Assert.assertEquals(HttpVersion.HTTP_1_1, statusline.getProtocolVersion());
-        Header[] headers = httpresponse.getAllHeaders();
+        final Header[] headers = httpresponse.getAllHeaders();
         Assert.assertEquals(3, headers.length);
     }
 
     @Test
     public void testConnectionClosedException() throws Exception {
-        SessionInputBuffer inbuffer = new SessionInputBufferMock(new byte[] {});
-
-        DefaultHttpResponseParser parser = new DefaultHttpResponseParser(
-                inbuffer,
-                BasicLineParser.DEFAULT,
-                new DefaultHttpResponseFactory(),
-                new BasicHttpParams());
+        final SessionInputBuffer inbuffer = new SessionInputBufferMock(new byte[] {});
 
+        final DefaultHttpResponseParser parser = new DefaultHttpResponseParser(inbuffer);
         try {
             parser.parse();
             Assert.fail("NoHttpResponseException should have been thrown");
-        } catch (NoHttpResponseException expected) {
+        } catch (final NoHttpResponseException expected) {
         }
     }
 
     @Test
     public void testMessageParsingTimeout() throws Exception {
-        String s =
+        final String s =
             "HTTP\000/1.1 200\000 OK\r\n" +
             "Server: wha\000tever\r\n" +
             "Date: some date\r\n" +
             "Set-Coo\000kie: c1=stuff\r\n" +
             "\000\r\n";
-        SessionInputBuffer inbuffer = new SessionInputBufferMock(
+        final SessionInputBuffer inbuffer = new SessionInputBufferMock(
                 new TimeoutByteArrayInputStream(s.getBytes("US-ASCII")), 16);
 
-        DefaultHttpResponseParser parser = new DefaultHttpResponseParser(
-                inbuffer,
-                BasicLineParser.DEFAULT,
-                new DefaultHttpResponseFactory(),
-                new BasicHttpParams());
+        final DefaultHttpResponseParser parser = new DefaultHttpResponseParser(inbuffer);
 
         int timeoutCount = 0;
 
@@ -151,7 +104,7 @@ public class TestResponseParser {
             try {
                 httpresponse = parser.parse();
                 break;
-            } catch (InterruptedIOException ex) {
+            } catch (final InterruptedIOException ex) {
                 timeoutCount++;
             }
 
@@ -160,12 +113,13 @@ public class TestResponseParser {
         Assert.assertEquals(5, timeoutCount);
 
         @SuppressWarnings("null") // httpresponse cannot be null here
+        final
         StatusLine statusline = httpresponse.getStatusLine();
         Assert.assertNotNull(statusline);
         Assert.assertEquals(200, statusline.getStatusCode());
         Assert.assertEquals("OK", statusline.getReasonPhrase());
         Assert.assertEquals(HttpVersion.HTTP_1_1, statusline.getProtocolVersion());
-        Header[] headers = httpresponse.getAllHeaders();
+        final Header[] headers = httpresponse.getAllHeaders();
         Assert.assertEquals(3, headers.length);
     }
 
diff --git a/httpcore/src/test/java/org/apache/http/impl/io/TestSessionBuffers.java b/httpcore/src/test/java/org/apache/http/impl/io/TestSessionInOutBuffers.java
similarity index 55%
rename from httpcore/src/test/java/org/apache/http/impl/io/TestSessionBuffers.java
rename to httpcore/src/test/java/org/apache/http/impl/io/TestSessionInOutBuffers.java
index 3c15ebf..68dba46 100644
--- a/httpcore/src/test/java/org/apache/http/impl/io/TestSessionBuffers.java
+++ b/httpcore/src/test/java/org/apache/http/impl/io/TestSessionInOutBuffers.java
@@ -27,74 +27,28 @@
 
 package org.apache.http.impl.io;
 
-import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
-import java.io.InputStream;
 import java.nio.charset.CharacterCodingException;
+import java.nio.charset.CharsetDecoder;
+import java.nio.charset.CharsetEncoder;
 import java.nio.charset.CodingErrorAction;
 
 import org.apache.http.Consts;
+import org.apache.http.config.MessageConstraints;
 import org.apache.http.impl.SessionInputBufferMock;
 import org.apache.http.impl.SessionOutputBufferMock;
 import org.apache.http.io.HttpTransportMetrics;
-import org.apache.http.params.BasicHttpParams;
-import org.apache.http.params.CoreConnectionPNames;
-import org.apache.http.params.HttpParams;
-import org.apache.http.params.HttpProtocolParams;
 import org.apache.http.util.CharArrayBuffer;
 import org.junit.Assert;
 import org.junit.Test;
+import org.mockito.Mockito;
 
-public class TestSessionBuffers {
-
-    @Test
-    public void testInit() throws Exception {
-        ByteArrayOutputStream out = new ByteArrayOutputStream();
-        new SessionOutputBufferMock(out);
-        try {
-            new SessionOutputBufferMock(null, new BasicHttpParams());
-            Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
-            //expected
-        }
-        try {
-            new SessionOutputBufferMock(out, null);
-            Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
-            //expected
-        }
-        ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
-        new SessionInputBufferMock(in, 10);
-        try {
-            new SessionInputBufferMock(in, -10);
-            Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
-            //expected
-        }
-        try {
-            new SessionOutputBufferMock(out, -10);
-            Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
-            //expected
-        }
-        try {
-            new SessionInputBufferMock((InputStream)null, 1024);
-            Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
-            //expected
-        }
-        try {
-            new SessionInputBufferMock(in, 10, null);
-            Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
-            //expected
-        }
-    }
+public class TestSessionInOutBuffers {
 
     @Test
     public void testBasicBufferProperties() throws Exception {
-        SessionInputBufferMock inbuffer = new SessionInputBufferMock(new byte[] { 1, 2 , 3});
+        final SessionInputBufferMock inbuffer = new SessionInputBufferMock(new byte[] { 1, 2 , 3});
         Assert.assertEquals(SessionInputBufferMock.BUFFER_SIZE, inbuffer.capacity());
         Assert.assertEquals(SessionInputBufferMock.BUFFER_SIZE, inbuffer.available());
         Assert.assertEquals(0, inbuffer.length());
@@ -102,7 +56,7 @@ public class TestSessionBuffers {
         Assert.assertEquals(SessionInputBufferMock.BUFFER_SIZE - 2, inbuffer.available());
         Assert.assertEquals(2, inbuffer.length());
 
-        SessionOutputBufferMock outbuffer = new SessionOutputBufferMock();
+        final SessionOutputBufferMock outbuffer = new SessionOutputBufferMock();
         Assert.assertEquals(SessionOutputBufferMock.BUFFER_SIZE, outbuffer.capacity());
         Assert.assertEquals(SessionOutputBufferMock.BUFFER_SIZE, outbuffer.available());
         Assert.assertEquals(0, outbuffer.length());
@@ -114,11 +68,11 @@ public class TestSessionBuffers {
     @Test
     public void testBasicReadWriteLine() throws Exception {
 
-        String[] teststrs = new String[5];
+        final String[] teststrs = new String[5];
         teststrs[0] = "Hello";
         teststrs[1] = "This string should be much longer than the size of the output buffer " +
                 "which is only 16 bytes for this test";
-        StringBuilder buffer = new StringBuilder();
+        final StringBuilder buffer = new StringBuilder();
         for (int i = 0; i < 15; i++) {
             buffer.append("123456789 ");
         }
@@ -127,11 +81,11 @@ public class TestSessionBuffers {
         teststrs[3] = "";
         teststrs[4] = "And goodbye";
 
-        CharArrayBuffer chbuffer = new CharArrayBuffer(16);
-        SessionOutputBufferMock outbuffer = new SessionOutputBufferMock();
-        for (int i = 0; i < teststrs.length; i++) {
+        final CharArrayBuffer chbuffer = new CharArrayBuffer(16);
+        final SessionOutputBufferMock outbuffer = new SessionOutputBufferMock();
+        for (final String teststr : teststrs) {
             chbuffer.clear();
-            chbuffer.append(teststrs[i]);
+            chbuffer.append(teststr);
             outbuffer.writeLine(chbuffer);
         }
         //these write operations should have no effect
@@ -140,30 +94,30 @@ public class TestSessionBuffers {
         outbuffer.flush();
 
         HttpTransportMetrics tmetrics = outbuffer.getMetrics();
-        long bytesWritten = tmetrics.getBytesTransferred();
+        final long bytesWritten = tmetrics.getBytesTransferred();
         long expected = 0;
-        for (int i = 0; i < teststrs.length; i++) {
-            expected += (teststrs[i].length() + 2/*CRLF*/);
+        for (final String teststr : teststrs) {
+            expected += (teststr.length() + 2/*CRLF*/);
         }
         Assert.assertEquals(expected, bytesWritten);
 
-        SessionInputBufferMock inbuffer = new SessionInputBufferMock(
+        final SessionInputBufferMock inbuffer = new SessionInputBufferMock(
                 outbuffer.getData());
 
-        for (int i = 0; i < teststrs.length; i++) {
-            Assert.assertEquals(teststrs[i], inbuffer.readLine());
+        for (final String teststr : teststrs) {
+            Assert.assertEquals(teststr, inbuffer.readLine());
         }
 
         Assert.assertNull(inbuffer.readLine());
         Assert.assertNull(inbuffer.readLine());
         tmetrics = inbuffer.getMetrics();
-        long bytesRead = tmetrics.getBytesTransferred();
+        final long bytesRead = tmetrics.getBytesTransferred();
         Assert.assertEquals(expected, bytesRead);
     }
 
     @Test
     public void testComplexReadWriteLine() throws Exception {
-        SessionOutputBufferMock outbuffer = new SessionOutputBufferMock();
+        final SessionOutputBufferMock outbuffer = new SessionOutputBufferMock();
         outbuffer.write(new byte[] {'a', '\n'});
         outbuffer.write(new byte[] {'\r', '\n'});
         outbuffer.write(new byte[] {'\r', '\r', '\n'});
@@ -177,11 +131,11 @@ public class TestSessionBuffers {
         long bytesWritten = outbuffer.getMetrics().getBytesTransferred();
         Assert.assertEquals(8, bytesWritten);
 
-        StringBuilder buffer = new StringBuilder();
+        final StringBuilder buffer = new StringBuilder();
         for (int i = 0; i < 14; i++) {
             buffer.append("a");
         }
-        String s1 = buffer.toString();
+        final String s1 = buffer.toString();
         buffer.append("\r\n");
         outbuffer.write(buffer.toString().getBytes("US-ASCII"));
         outbuffer.flush();
@@ -192,7 +146,7 @@ public class TestSessionBuffers {
         for (int i = 0; i < 15; i++) {
             buffer.append("a");
         }
-        String s2 = buffer.toString();
+        final String s2 = buffer.toString();
         buffer.append("\r\n");
         outbuffer.write(buffer.toString().getBytes("US-ASCII"));
         outbuffer.flush();
@@ -203,7 +157,7 @@ public class TestSessionBuffers {
         for (int i = 0; i < 16; i++) {
             buffer.append("a");
         }
-        String s3 = buffer.toString();
+        final String s3 = buffer.toString();
         buffer.append("\r\n");
         outbuffer.write(buffer.toString().getBytes("US-ASCII"));
         outbuffer.flush();
@@ -215,7 +169,7 @@ public class TestSessionBuffers {
         bytesWritten = outbuffer.getMetrics().getBytesTransferred();
         Assert.assertEquals(8 + 14 + 2 + 15 + 2 + 16 + 2 + 1, bytesWritten);
 
-        SessionInputBufferMock inbuffer = new SessionInputBufferMock(
+        final SessionInputBufferMock inbuffer = new SessionInputBufferMock(
                 outbuffer.getData());
 
         Assert.assertEquals("a", inbuffer.readLine());
@@ -228,18 +182,18 @@ public class TestSessionBuffers {
         Assert.assertEquals("a", inbuffer.readLine());
         Assert.assertNull(inbuffer.readLine());
         Assert.assertNull(inbuffer.readLine());
-        long bytesRead = inbuffer.getMetrics().getBytesTransferred();
+        final long bytesRead = inbuffer.getMetrics().getBytesTransferred();
         Assert.assertEquals(bytesWritten, bytesRead);
     }
 
     @Test
     public void testBasicReadWriteLineLargeBuffer() throws Exception {
 
-        String[] teststrs = new String[5];
+        final String[] teststrs = new String[5];
         teststrs[0] = "Hello";
         teststrs[1] = "This string should be much longer than the size of the output buffer " +
                 "which is only 16 bytes for this test";
-        StringBuilder buffer = new StringBuilder();
+        final StringBuilder buffer = new StringBuilder();
         for (int i = 0; i < 15; i++) {
             buffer.append("123456789 ");
         }
@@ -248,11 +202,11 @@ public class TestSessionBuffers {
         teststrs[3] = "";
         teststrs[4] = "And goodbye";
 
-        CharArrayBuffer chbuffer = new CharArrayBuffer(16);
-        SessionOutputBufferMock outbuffer = new SessionOutputBufferMock();
-        for (int i = 0; i < teststrs.length; i++) {
+        final CharArrayBuffer chbuffer = new CharArrayBuffer(16);
+        final SessionOutputBufferMock outbuffer = new SessionOutputBufferMock();
+        for (final String teststr : teststrs) {
             chbuffer.clear();
-            chbuffer.append(teststrs[i]);
+            chbuffer.append(teststr);
             outbuffer.writeLine(chbuffer);
         }
         //these write operations should have no effect
@@ -260,33 +214,33 @@ public class TestSessionBuffers {
         outbuffer.writeLine((CharArrayBuffer)null);
         outbuffer.flush();
 
-        long bytesWritten = outbuffer.getMetrics().getBytesTransferred();
+        final long bytesWritten = outbuffer.getMetrics().getBytesTransferred();
         long expected = 0;
-        for (int i = 0; i < teststrs.length; i++) {
-            expected += (teststrs[i].length() + 2/*CRLF*/);
+        for (final String teststr : teststrs) {
+            expected += (teststr.length() + 2/*CRLF*/);
         }
         Assert.assertEquals(expected, bytesWritten);
 
-        SessionInputBufferMock inbuffer = new SessionInputBufferMock(
+        final SessionInputBufferMock inbuffer = new SessionInputBufferMock(
                 outbuffer.getData(), 1024);
 
-        for (int i = 0; i < teststrs.length; i++) {
-            Assert.assertEquals(teststrs[i], inbuffer.readLine());
+        for (final String teststr : teststrs) {
+            Assert.assertEquals(teststr, inbuffer.readLine());
         }
         Assert.assertNull(inbuffer.readLine());
         Assert.assertNull(inbuffer.readLine());
-        long bytesRead = inbuffer.getMetrics().getBytesTransferred();
+        final long bytesRead = inbuffer.getMetrics().getBytesTransferred();
         Assert.assertEquals(expected, bytesRead);
     }
 
     @Test
     public void testReadWriteBytes() throws Exception {
         // make the buffer larger than that of outbuffer
-        byte[] out = new byte[40];
+        final byte[] out = new byte[40];
         for (int i = 0; i < out.length; i++) {
             out[i] = (byte)('0' + i);
         }
-        SessionOutputBufferMock outbuffer = new SessionOutputBufferMock();
+        final SessionOutputBufferMock outbuffer = new SessionOutputBufferMock();
         int off = 0;
         int remaining = out.length;
         while (remaining > 0) {
@@ -299,16 +253,16 @@ public class TestSessionBuffers {
             remaining -= chunk;
         }
         outbuffer.flush();
-        long bytesWritten = outbuffer.getMetrics().getBytesTransferred();
+        final long bytesWritten = outbuffer.getMetrics().getBytesTransferred();
         Assert.assertEquals(out.length, bytesWritten);
 
-        byte[] tmp = outbuffer.getData();
+        final byte[] tmp = outbuffer.getData();
         Assert.assertEquals(out.length, tmp.length);
         for (int i = 0; i < out.length; i++) {
             Assert.assertEquals(out[i], tmp[i]);
         }
 
-        SessionInputBufferMock inbuffer = new SessionInputBufferMock(tmp);
+        final SessionInputBufferMock inbuffer = new SessionInputBufferMock(tmp);
 
         // these read operations will have no effect
         Assert.assertEquals(0, inbuffer.read(null, 0, 10));
@@ -316,7 +270,7 @@ public class TestSessionBuffers {
         long bytesRead = inbuffer.getMetrics().getBytesTransferred();
         Assert.assertEquals(0, bytesRead);
 
-        byte[] in = new byte[40];
+        final byte[] in = new byte[40];
         off = 0;
         remaining = in.length;
         while (remaining > 0) {
@@ -324,7 +278,7 @@ public class TestSessionBuffers {
             if (chunk > remaining) {
                 chunk = remaining;
             }
-            int l = inbuffer.read(in, off, chunk);
+            final int l = inbuffer.read(in, off, chunk);
             if (l == -1) {
                 break;
             }
@@ -343,26 +297,26 @@ public class TestSessionBuffers {
     @Test
     public void testReadWriteByte() throws Exception {
         // make the buffer larger than that of outbuffer
-        byte[] out = new byte[40];
+        final byte[] out = new byte[40];
         for (int i = 0; i < out.length; i++) {
             out[i] = (byte)(120 + i);
         }
-        SessionOutputBufferMock outbuffer = new SessionOutputBufferMock();
-        for (int i = 0; i < out.length; i++) {
-            outbuffer.write(out[i]);
+        final SessionOutputBufferMock outbuffer = new SessionOutputBufferMock();
+        for (final byte element : out) {
+            outbuffer.write(element);
         }
         outbuffer.flush();
-        long bytesWritten = outbuffer.getMetrics().getBytesTransferred();
+        final long bytesWritten = outbuffer.getMetrics().getBytesTransferred();
         Assert.assertEquals(out.length, bytesWritten);
 
-        byte[] tmp = outbuffer.getData();
+        final byte[] tmp = outbuffer.getData();
         Assert.assertEquals(out.length, tmp.length);
         for (int i = 0; i < out.length; i++) {
             Assert.assertEquals(out[i], tmp[i]);
         }
 
-        SessionInputBufferMock inbuffer = new SessionInputBufferMock(tmp);
-        byte[] in = new byte[40];
+        final SessionInputBufferMock inbuffer = new SessionInputBufferMock(tmp);
+        final byte[] in = new byte[40];
         for (int i = 0; i < in.length; i++) {
             in[i] = (byte)inbuffer.read();
         }
@@ -371,29 +325,55 @@ public class TestSessionBuffers {
         }
         Assert.assertEquals(-1, inbuffer.read());
         Assert.assertEquals(-1, inbuffer.read());
-        long bytesRead = inbuffer.getMetrics().getBytesTransferred();
+        final long bytesRead = inbuffer.getMetrics().getBytesTransferred();
         Assert.assertEquals(out.length, bytesRead);
     }
 
     @Test
+    public void testWriteSmallFragmentBuffering() throws Exception {
+        final ByteArrayOutputStream outstream = Mockito.spy(new ByteArrayOutputStream());
+        final SessionOutputBufferMock outbuffer = new SessionOutputBufferMock(outstream, 16, 16, null);
+        outbuffer.write(1);
+        outbuffer.write(2);
+        outbuffer.write(new byte[] {1, 2});
+        outbuffer.write(new byte[] {3, 4});
+        outbuffer.flush();
+        Mockito.verify(outstream, Mockito.times(1)).write(
+                Mockito.<byte []>any(), Mockito.anyInt(), Mockito.anyInt());
+        Mockito.verify(outstream, Mockito.never()).write(Mockito.anyInt());
+    }
+
+    @Test
+    public void testWriteSmallFragmentNoBuffering() throws Exception {
+        final ByteArrayOutputStream outstream = Mockito.spy(new ByteArrayOutputStream());
+        final SessionOutputBufferMock outbuffer = new SessionOutputBufferMock(outstream, 16, 0, null);
+        outbuffer.write(1);
+        outbuffer.write(2);
+        outbuffer.write(new byte[] {1, 2});
+        outbuffer.write(new byte[] {3, 4});
+        Mockito.verify(outstream, Mockito.times(2)).write(
+                Mockito.<byte []>any(), Mockito.anyInt(), Mockito.anyInt());
+        Mockito.verify(outstream, Mockito.times(2)).write(Mockito.anyInt());
+    }
+
+    @Test
     public void testLineLimit() throws Exception {
-        HttpParams params = new BasicHttpParams();
-        String s = "a very looooooooooooooooooooooooooooooooooooooong line\r\n     ";
-        byte[] tmp = s.getBytes("US-ASCII");
+        final String s = "a very looooooooooooooooooooooooooooooooooooooong line\r\n     ";
+        final byte[] tmp = s.getBytes("US-ASCII");
         // no limit
-        params.setIntParameter(CoreConnectionPNames.MAX_LINE_LENGTH, 0);
-        SessionInputBufferMock inbuffer1 = new SessionInputBufferMock(tmp, 5, params);
+        final SessionInputBufferMock inbuffer1 = new SessionInputBufferMock(tmp, 5,
+                MessageConstraints.DEFAULT);
         Assert.assertNotNull(inbuffer1.readLine());
         long bytesRead = inbuffer1.getMetrics().getBytesTransferred();
         Assert.assertEquals(60, bytesRead);
 
         // 15 char limit
-        params.setIntParameter(CoreConnectionPNames.MAX_LINE_LENGTH, 15);
-        SessionInputBufferMock inbuffer2 = new SessionInputBufferMock(tmp, 5, params);
+        final SessionInputBufferMock inbuffer2 = new SessionInputBufferMock(tmp, 5,
+                MessageConstraints.lineLen(15));
         try {
             inbuffer2.readLine();
             Assert.fail("IOException should have been thrown");
-        } catch (IOException ex) {
+        } catch (final IOException ex) {
             // expected
             bytesRead = inbuffer2.getMetrics().getBytesTransferred();
             Assert.assertEquals(20, bytesRead);
@@ -402,10 +382,9 @@ public class TestSessionBuffers {
 
     @Test
     public void testReadLineFringeCase1() throws Exception {
-        HttpParams params = new BasicHttpParams();
-        String s = "abc\r\n";
-        byte[] tmp = s.getBytes("US-ASCII");
-        SessionInputBufferMock inbuffer1 = new SessionInputBufferMock(tmp, 128, params);
+        final String s = "abc\r\n";
+        final byte[] tmp = s.getBytes("US-ASCII");
+        final SessionInputBufferMock inbuffer1 = new SessionInputBufferMock(tmp, 128);
         Assert.assertEquals('a', inbuffer1.read());
         Assert.assertEquals('b', inbuffer1.read());
         Assert.assertEquals('c', inbuffer1.read());
@@ -422,11 +401,11 @@ public class TestSessionBuffers {
         0x432, 0x435, 0x442
     };
 
-    private static String constructString(int [] unicodeChars) {
-        StringBuilder buffer = new StringBuilder();
+    private static String constructString(final int [] unicodeChars) {
+        final StringBuilder buffer = new StringBuilder();
         if (unicodeChars != null) {
-            for (int i = 0; i < unicodeChars.length; i++) {
-                buffer.append((char)unicodeChars[i]);
+            for (final int unicodeChar : unicodeChars) {
+                buffer.append((char)unicodeChar);
             }
         }
         return buffer.toString();
@@ -434,16 +413,13 @@ public class TestSessionBuffers {
 
     @Test
     public void testMultibyteCodedReadWriteLine() throws Exception {
-        String s1 = constructString(SWISS_GERMAN_HELLO);
-        String s2 = constructString(RUSSIAN_HELLO);
-        String s3 = "Like hello and stuff";
-
-        HttpParams params = new BasicHttpParams();
-        HttpProtocolParams.setHttpElementCharset(params, "UTF-8");
+        final String s1 = constructString(SWISS_GERMAN_HELLO);
+        final String s2 = constructString(RUSSIAN_HELLO);
+        final String s3 = "Like hello and stuff";
 
-        SessionOutputBufferMock outbuffer = new SessionOutputBufferMock(params);
+        final SessionOutputBufferMock outbuffer = new SessionOutputBufferMock(Consts.UTF_8);
 
-        CharArrayBuffer chbuffer = new CharArrayBuffer(16);
+        final CharArrayBuffer chbuffer = new CharArrayBuffer(16);
         for (int i = 0; i < 10; i++) {
             chbuffer.clear();
             chbuffer.append(s1);
@@ -456,14 +432,14 @@ public class TestSessionBuffers {
             outbuffer.writeLine(chbuffer);
         }
         outbuffer.flush();
-        long bytesWritten = outbuffer.getMetrics().getBytesTransferred();
-        long expected = ((s1.getBytes("UTF-8").length + 2)+
+        final long bytesWritten = outbuffer.getMetrics().getBytesTransferred();
+        final long expected = ((s1.getBytes("UTF-8").length + 2)+
                 (s2.getBytes("UTF-8").length + 2) +
                 (s3.getBytes("UTF-8").length + 2)) * 10;
         Assert.assertEquals(expected, bytesWritten);
 
-        SessionInputBufferMock inbuffer = new SessionInputBufferMock(
-                outbuffer.getData(), params);
+        final SessionInputBufferMock inbuffer = new SessionInputBufferMock(
+                outbuffer.getData(), Consts.UTF_8);
 
         for (int i = 0; i < 10; i++) {
             Assert.assertEquals(s1, inbuffer.readLine());
@@ -472,47 +448,41 @@ public class TestSessionBuffers {
         }
         Assert.assertNull(inbuffer.readLine());
         Assert.assertNull(inbuffer.readLine());
-        long bytesRead = inbuffer.getMetrics().getBytesTransferred();
+        final long bytesRead = inbuffer.getMetrics().getBytesTransferred();
         Assert.assertEquals(expected, bytesRead);
     }
 
     @Test
     public void testMultibyteCodedReadWriteLongLine() throws Exception {
-        String s1 = constructString(SWISS_GERMAN_HELLO);
-        String s2 = constructString(RUSSIAN_HELLO);
-        String s3 = "Like hello and stuff";
-        StringBuilder buf = new StringBuilder();
+        final String s1 = constructString(SWISS_GERMAN_HELLO);
+        final String s2 = constructString(RUSSIAN_HELLO);
+        final String s3 = "Like hello and stuff";
+        final StringBuilder buf = new StringBuilder();
         for (int i = 0; i < 1024; i++) {
             buf.append(s1).append(s2).append(s3);
         }
-        String s = buf.toString();
+        final String s = buf.toString();
 
-        HttpParams params = new BasicHttpParams();
-        HttpProtocolParams.setHttpElementCharset(params, "UTF-8");
+        final SessionOutputBufferMock outbuffer = new SessionOutputBufferMock(Consts.UTF_8);
 
-        SessionOutputBufferMock outbuffer = new SessionOutputBufferMock(params);
-
-        CharArrayBuffer chbuffer = new CharArrayBuffer(16);
+        final CharArrayBuffer chbuffer = new CharArrayBuffer(16);
         chbuffer.append(s);
         outbuffer.writeLine(chbuffer);
         outbuffer.flush();
 
-        SessionInputBufferMock inbuffer = new SessionInputBufferMock(
-                outbuffer.getData(), params);
+        final SessionInputBufferMock inbuffer = new SessionInputBufferMock(
+                outbuffer.getData(), Consts.UTF_8);
 
         Assert.assertEquals(s, inbuffer.readLine());
     }
 
     @Test
     public void testNonAsciiReadWriteLine() throws Exception {
-        String s1 = constructString(SWISS_GERMAN_HELLO);
-
-        HttpParams params = new BasicHttpParams();
-        HttpProtocolParams.setHttpElementCharset(params, Consts.ISO_8859_1.name());
+        final String s1 = constructString(SWISS_GERMAN_HELLO);
 
-        SessionOutputBufferMock outbuffer = new SessionOutputBufferMock(params);
+        final SessionOutputBufferMock outbuffer = new SessionOutputBufferMock(Consts.ISO_8859_1);
 
-        CharArrayBuffer chbuffer = new CharArrayBuffer(16);
+        final CharArrayBuffer chbuffer = new CharArrayBuffer(16);
         for (int i = 0; i < 5; i++) {
             chbuffer.clear();
             chbuffer.append(s1);
@@ -524,19 +494,17 @@ public class TestSessionBuffers {
         chbuffer.clear();
         outbuffer.writeLine(chbuffer);
         outbuffer.flush();
-        long bytesWritten = outbuffer.getMetrics().getBytesTransferred();
-        long expected = ((s1.toString().getBytes(Consts.ISO_8859_1.name()).length + 2)) * 10 + 2;
+        final long bytesWritten = outbuffer.getMetrics().getBytesTransferred();
+        final long expected = ((s1.toString().getBytes(Consts.ISO_8859_1.name()).length + 2)) * 10 + 2;
         Assert.assertEquals(expected, bytesWritten);
 
-        SessionInputBufferMock inbuffer = new SessionInputBufferMock(
-                outbuffer.getData(),
-                params);
-        HttpProtocolParams.setHttpElementCharset(params, Consts.ISO_8859_1.name());
+        final SessionInputBufferMock inbuffer = new SessionInputBufferMock(
+                outbuffer.getData(), Consts.ISO_8859_1);
 
-        CharArrayBuffer buf = new CharArrayBuffer(64);
+        final CharArrayBuffer buf = new CharArrayBuffer(64);
         for (int i = 0; i < 10; i++) {
             buf.clear();
-            int len = inbuffer.readLine(buf);
+            final int len = inbuffer.readLine(buf);
             Assert.assertEquals(len, SWISS_GERMAN_HELLO.length);
             Assert.assertEquals(s1, buf.toString());
         }
@@ -544,89 +512,87 @@ public class TestSessionBuffers {
         Assert.assertEquals("", inbuffer.readLine());
         Assert.assertNull(inbuffer.readLine());
         Assert.assertNull(inbuffer.readLine());
-        long bytesRead = inbuffer.getMetrics().getBytesTransferred();
+        final long bytesRead = inbuffer.getMetrics().getBytesTransferred();
         Assert.assertEquals(expected, bytesRead);
     }
 
-    @Test
-    public void testUnmappableInputAction() throws Exception {
-        BasicHttpParams params = new BasicHttpParams();
-        String s = "In valid ISO-8859-1 character string because  of Ŵ and ŵ";
-        HttpProtocolParams.setHttpElementCharset(params, Consts.ISO_8859_1.name());
-
-        // Action with report
-        HttpProtocolParams.setUnmappableInputAction(params, CodingErrorAction.REPORT);
-        SessionOutputBufferMock outbuf = new SessionOutputBufferMock(params);
-        try {
-            outbuf.writeLine(s);
-            Assert.fail("Expected CharacterCodingException");
-        } catch (CharacterCodingException expected) {
-        }
-
-        // Action with ignore
-        HttpProtocolParams.setUnmappableInputAction(params, CodingErrorAction.IGNORE);
-        outbuf = new SessionOutputBufferMock(params);
-        try {
-            outbuf.writeLine(s);
-        } catch (CharacterCodingException e) {
-            Assert.fail("Unexpected CharacterCodingException");
-        }
-
-        // Action with replace
-        HttpProtocolParams.setUnmappableInputAction(params, CodingErrorAction.REPLACE);
-        outbuf = new SessionOutputBufferMock(params);
-        try {
-            outbuf.writeLine(s);
-        } catch (IOException e) {
-            Assert.fail("Unexpected CharacterCodingException");
-        }
+    @Test(expected=CharacterCodingException.class)
+    public void testUnmappableInputActionReport() throws Exception {
+        final String s = "This text contains a circumflex \u0302 !!!";
+        final CharsetEncoder encoder = Consts.ISO_8859_1.newEncoder();
+        encoder.onMalformedInput(CodingErrorAction.IGNORE);
+        encoder.onUnmappableCharacter(CodingErrorAction.REPORT);
+        final SessionOutputBufferMock outbuf = new SessionOutputBufferMock(encoder);
+        outbuf.writeLine(s);
     }
 
     @Test
-    public void testMalformedInputAction() throws Exception {
-        byte[] tmp = constructString(SWISS_GERMAN_HELLO).getBytes("UTF-16");
-        CharArrayBuffer buf = new CharArrayBuffer(1);
+    public void testUnmappableInputActionReplace() throws Exception {
+        final String s = "This text contains a circumflex \u0302 !!!";
+        final CharsetEncoder encoder = Consts.ISO_8859_1.newEncoder();
+        encoder.onMalformedInput(CodingErrorAction.IGNORE);
+        encoder.onUnmappableCharacter(CodingErrorAction.REPLACE);
+        final SessionOutputBufferMock outbuf = new SessionOutputBufferMock(encoder);
+        outbuf.writeLine(s);
+        outbuf.flush();
+        final String result = new String(outbuf.getData(), "ISO-8859-1");
+        Assert.assertEquals("This text contains a circumflex ? !!!\r\n", result);
+    }
 
-        BasicHttpParams params = new BasicHttpParams();
-        HttpProtocolParams.setHttpElementCharset(params, "UTF-8");
+    @Test
+    public void testUnmappableInputActionIgnore() throws Exception {
+        final String s = "This text contains a circumflex \u0302 !!!";
+        final CharsetEncoder encoder = Consts.ISO_8859_1.newEncoder();
+        encoder.onMalformedInput(CodingErrorAction.IGNORE);
+        encoder.onUnmappableCharacter(CodingErrorAction.IGNORE);
+        final SessionOutputBufferMock outbuf = new SessionOutputBufferMock(encoder);
+        outbuf.writeLine(s);
+        outbuf.flush();
+        final String result = new String(outbuf.getData(), "ISO-8859-1");
+        Assert.assertEquals("This text contains a circumflex  !!!\r\n", result);
+    }
 
-        // Action with report
-        HttpProtocolParams.setMalformedInputAction(params, CodingErrorAction.REPORT);
-        SessionInputBufferMock inbuffer = new SessionInputBufferMock(tmp, params);
-        try {
-            inbuffer.readLine(buf);
-            Assert.fail("Expected CharacterCodingException");
-        } catch (CharacterCodingException e) {
-        }
+    @Test(expected=CharacterCodingException.class)
+    public void testMalformedInputActionReport() throws Exception {
+        final byte[] tmp = constructString(SWISS_GERMAN_HELLO).getBytes(Consts.ISO_8859_1.name());
+        final CharsetDecoder decoder = Consts.UTF_8.newDecoder();
+        decoder.onMalformedInput(CodingErrorAction.REPORT);
+        decoder.onUnmappableCharacter(CodingErrorAction.IGNORE);
+        final SessionInputBufferMock inbuffer = new SessionInputBufferMock(tmp, decoder);
+        inbuffer.readLine();
+    }
 
-        // Action with replace
-        HttpProtocolParams.setMalformedInputAction(params, CodingErrorAction.REPLACE);
-        inbuffer = new SessionInputBufferMock(tmp, params);
-        try {
-            inbuffer.readLine(buf);
-        } catch (CharacterCodingException e) {
-            Assert.fail("Unexpected CharacterCodingException");
-        }
+    @Test
+    public void testMalformedInputActionReplace() throws Exception {
+        final byte[] tmp = constructString(SWISS_GERMAN_HELLO).getBytes(Consts.ISO_8859_1.name());
+        final CharsetDecoder decoder = Consts.UTF_8.newDecoder();
+        decoder.onMalformedInput(CodingErrorAction.REPLACE);
+        decoder.onUnmappableCharacter(CodingErrorAction.IGNORE);
+        final SessionInputBufferMock inbuffer = new SessionInputBufferMock(tmp, decoder);
+        final String s = inbuffer.readLine();
+        Assert.assertEquals("Gr\ufffdezi_z\ufffdm\ufffd", s);
+    }
 
-        // Action with ignore
-        HttpProtocolParams.setMalformedInputAction(params, CodingErrorAction.IGNORE);
-        inbuffer = new SessionInputBufferMock(tmp, params);
-        try {
-            inbuffer.readLine();
-        } catch (IOException e) {
-            Assert.fail("Unexpected CharacterCodingException");
-        }
+    @Test
+    public void testMalformedInputActionIgnore() throws Exception {
+        final byte[] tmp = constructString(SWISS_GERMAN_HELLO).getBytes(Consts.ISO_8859_1.name());
+        final CharsetDecoder decoder = Consts.UTF_8.newDecoder();
+        decoder.onMalformedInput(CodingErrorAction.IGNORE);
+        decoder.onUnmappableCharacter(CodingErrorAction.IGNORE);
+        final SessionInputBufferMock inbuffer = new SessionInputBufferMock(tmp, decoder);
+        final String s = inbuffer.readLine();
+        Assert.assertEquals("Grezi_zm", s);
     }
 
     @Test
     public void testInvalidCharArrayBuffer() throws Exception {
-        SessionInputBufferMock inbuffer = new SessionInputBufferMock(new byte[] {});
+        final SessionInputBufferMock inbuffer = new SessionInputBufferMock(new byte[] {});
         try {
             inbuffer.readLine(null);
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
             //expected
-            long bytesRead = inbuffer.getMetrics().getBytesTransferred();
+            final long bytesRead = inbuffer.getMetrics().getBytesTransferred();
             Assert.assertEquals(0, bytesRead);
         }
     }
diff --git a/httpcore/src/test/java/org/apache/http/impl/io/TestSocketOutputBuffer.java b/httpcore/src/test/java/org/apache/http/impl/io/TestSocketOutputBuffer.java
deleted file mode 100644
index 2223b0f..0000000
--- a/httpcore/src/test/java/org/apache/http/impl/io/TestSocketOutputBuffer.java
+++ /dev/null
@@ -1,197 +0,0 @@
-/*
- * ====================================================================
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- *
- */
-
-package org.apache.http.impl.io;
-
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import java.io.OutputStream;
-import java.net.Socket;
-
-import org.apache.http.params.CoreConnectionPNames;
-import org.apache.http.params.CoreProtocolPNames;
-import org.apache.http.params.HttpParams;
-import org.apache.http.util.CharArrayBuffer;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-public class TestSocketOutputBuffer {
-
-    private SocketOutputBuffer sob;
-
-    @Mock private Socket socket;
-    @Mock private OutputStream os;
-    @Mock private HttpParams params;
-    private byte[] b;
-    private CharArrayBuffer cb;
-
-    @Before
-    public void setUp() throws Exception {
-        MockitoAnnotations.initMocks(this);
-
-        when(socket.getOutputStream()).thenReturn(os);
-    }
-
-    private void create(int buffSize, int arraySize, int minChunkLimit) throws Exception {
-        b = new byte[arraySize];
-        cb = new CharArrayBuffer(arraySize);
-
-        when(params.getIntParameter(CoreConnectionPNames.MIN_CHUNK_LIMIT, 512)).thenReturn(minChunkLimit);
-
-        sob = new SocketOutputBuffer(socket, buffSize, params);
-    }
-
-    @Test
-    public void testWriteByteArrayOffLenDirectToStream1() throws Exception {
-        create(2048, 2048, 1024);
-
-        sob.write(b, 0, b.length);
-        verify(os, times(1)).write(any(byte[].class), eq(0), eq(b.length));
-    }
-
-    @Test
-    public void testWriteByteArrayOffLenDirectToStream2() throws Exception {
-        create(1024, 2048, 2048);
-
-        sob.write(b, 0, b.length);
-        verify(os, times(1)).write(any(byte[].class), eq(0), eq(b.length));
-    }
-
-    @Test
-    public void testWriteByteArrayOffLenToBuffer() throws Exception {
-        create(2048, 2048, 2048);
-
-        sob.write(b, 0, b.length);
-        verify(os, times(0)).write(any(byte[].class), eq(0), eq(b.length));
-    }
-
-    @Test
-    public void testWriteByteArrayDirectToStream1() throws Exception {
-        create(2048, 2048, 1024);
-
-        sob.write(b);
-        verify(os, times(1)).write(any(byte[].class), eq(0), eq(b.length));
-    }
-
-    @Test
-    public void testWriteByteArrayDirectToStream2() throws Exception {
-        create(1024, 2048, 2048);
-
-        sob.write(b);
-        verify(os, times(1)).write(any(byte[].class), eq(0), eq(b.length));
-    }
-
-    @Test
-    public void testWriteByteArrayToBuffer() throws Exception {
-        create(2048, 2048, 2048);
-
-        sob.write(b);
-        verify(os, times(0)).write(any(byte[].class), eq(0), eq(b.length));
-    }
-
-    @Test
-    public void testWriteLineString() throws Exception {
-        create(2048, 2048, 2048);
-
-        sob.writeLine("test");
-    }
-
-    @Test
-    public void testWriteLineStringEncode() throws Exception {
-        when(params.getParameter(CoreProtocolPNames.HTTP_ELEMENT_CHARSET)).thenReturn("UTF-8");
-        create(2048, 2048, 2048);
-
-        sob.writeLine("test");
-    }
-
-    @Test
-    public void testWriteLineEmptyString() throws Exception {
-        create(2048, 2048, 2048);
-
-        sob.writeLine("");
-    }
-
-    @Test
-    public void testWriteLineEmptyStringEncode() throws Exception {
-        when(params.getParameter(CoreProtocolPNames.HTTP_ELEMENT_CHARSET)).thenReturn("UTF-8");
-        create(2048, 2048, 2048);
-
-        sob.writeLine("");
-    }
-
-    @Test
-    public void testWriteLineNullString() throws Exception {
-        create(2048, 2048, 2048);
-
-        sob.writeLine((String)null);
-    }
-
-    @Test
-    public void testWriteLineNullStringEncode() throws Exception {
-        when(params.getParameter(CoreProtocolPNames.HTTP_ELEMENT_CHARSET)).thenReturn("UTF-8");
-        create(2048, 2048, 2048);
-
-        sob.writeLine((String)null);
-    }
-
-    @Test
-    public void testWriteLineCharArrayBuffer() throws Exception {
-        create(2048, 2048, 2048);
-
-        sob.writeLine(cb);
-    }
-
-    @Test
-    public void testWriteLineCharArrayBufferEncode() throws Exception {
-        when(params.getParameter(CoreProtocolPNames.HTTP_ELEMENT_CHARSET)).thenReturn("UTF-8");
-        create(2048, 2048, 2048);
-
-        sob.writeLine(cb);
-    }
-
-    @Test
-    public void testWriteLineEmptyCharArrayBuffer() throws Exception {
-        create(2048, 0, 2048);
-
-        sob.writeLine(cb);
-    }
-
-    @Test
-    public void testWriteLineEmptyCharArrayBufferEncode() throws Exception {
-        when(params.getParameter(CoreProtocolPNames.HTTP_ELEMENT_CHARSET)).thenReturn("UTF-8");
-        create(2048, 0, 2048);
-
-        sob.writeLine(cb);
-    }
-
-}
diff --git a/httpcore/src/test/java/org/apache/http/impl/io/TimeoutByteArrayInputStream.java b/httpcore/src/test/java/org/apache/http/impl/io/TimeoutByteArrayInputStream.java
index eaf6b14..dabc617 100644
--- a/httpcore/src/test/java/org/apache/http/impl/io/TimeoutByteArrayInputStream.java
+++ b/httpcore/src/test/java/org/apache/http/impl/io/TimeoutByteArrayInputStream.java
@@ -42,14 +42,14 @@ class TimeoutByteArrayInputStream extends InputStream {
     private int pos;
     protected int count;
 
-    public TimeoutByteArrayInputStream(byte[] buf, int off, int len) {
+    public TimeoutByteArrayInputStream(final byte[] buf, final int off, final int len) {
         super();
         this.buf = buf;
         this.pos = off;
         this.count = Math.min(off + len, buf.length);
     }
 
-    public TimeoutByteArrayInputStream(byte[] buf) {
+    public TimeoutByteArrayInputStream(final byte[] buf) {
         this(buf, 0, buf.length);
     }
 
@@ -58,7 +58,7 @@ class TimeoutByteArrayInputStream extends InputStream {
         if (this.pos < this.count) {
             return -1;
         }
-        int v = this.buf[this.pos++] & 0xff;
+        final int v = this.buf[this.pos++] & 0xff;
         if (v != 0) {
             return v;
         } else {
@@ -67,7 +67,7 @@ class TimeoutByteArrayInputStream extends InputStream {
     }
 
     @Override
-    public int read(byte b[], int off, int len) throws IOException {
+    public int read(final byte b[], final int off, final int len) throws IOException {
         if (b == null) {
             throw new NullPointerException();
         } else if ((off < 0) || (off > b.length) || (len < 0) ||
@@ -77,18 +77,19 @@ class TimeoutByteArrayInputStream extends InputStream {
         if (this.pos >= this.count) {
             return -1;
         }
+        int chunk = len;
         if (this.pos + len > this.count) {
-            len = this.count - this.pos;
+            chunk = this.count - this.pos;
         }
-        if (len <= 0) {
+        if (chunk <= 0) {
             return 0;
         }
         if ((this.buf[this.pos] & 0xff) == 0) {
             this.pos++;
             throw new InterruptedIOException("Timeout");
         }
-        for (int i = 0; i < len; i++) {
-            int v = this.buf[this.pos] & 0xff;
+        for (int i = 0; i < chunk; i++) {
+            final int v = this.buf[this.pos] & 0xff;
             if (v == 0) {
                 return i;
             } else {
@@ -96,19 +97,20 @@ class TimeoutByteArrayInputStream extends InputStream {
                 this.pos++;
             }
         }
-        return len;
+        return chunk;
     }
 
     @Override
-    public long skip(long n) {
+    public long skip(final long n) {
+        long chunk = n;
         if (this.pos + n > this.count) {
-            n = this.count - this.pos;
+            chunk = this.count - this.pos;
         }
-        if (n < 0) {
+        if (chunk < 0) {
             return 0;
         }
-        this.pos += n;
-        return n;
+        this.pos += chunk;
+        return chunk;
     }
 
     @Override
diff --git a/httpcore/src/test/java/org/apache/http/impl/pool/TestBasicConnPool.java b/httpcore/src/test/java/org/apache/http/impl/pool/TestBasicConnPool.java
index 74349e5..f2233e5 100644
--- a/httpcore/src/test/java/org/apache/http/impl/pool/TestBasicConnPool.java
+++ b/httpcore/src/test/java/org/apache/http/impl/pool/TestBasicConnPool.java
@@ -27,6 +27,7 @@
 package org.apache.http.impl.pool;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
 
 import java.net.ServerSocket;
 
@@ -36,9 +37,8 @@ import javax.net.ssl.SSLSocketFactory;
 
 import org.apache.http.HttpClientConnection;
 import org.apache.http.HttpHost;
-import org.apache.http.params.BasicHttpParams;
-import org.apache.http.params.CoreConnectionPNames;
-import org.apache.http.params.HttpParams;
+import org.apache.http.config.ConnectionConfig;
+import org.apache.http.config.SocketConfig;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
@@ -48,13 +48,11 @@ public class TestBasicConnPool {
     private BasicConnFactory connFactory;
     private BasicConnPool pool;
     private HttpHost host;
-    private HttpParams params;
     private HttpClientConnection conn;
 
     private ServerSocket server;
     private int serverPort;
 
-    private SSLServerSocket sslServer;
     private int sslServerPort;
 
     @Before
@@ -64,13 +62,11 @@ public class TestBasicConnPool {
         serverPort = server.getLocalPort();
 
         // setup an "https" server
-        sslServer = (SSLServerSocket) SSLServerSocketFactory.getDefault().createServerSocket(0);
+        final SSLServerSocket sslServer = (SSLServerSocket) SSLServerSocketFactory.getDefault().createServerSocket(0);
         sslServerPort = sslServer.getLocalPort();
 
-        params = new BasicHttpParams();
-        params.setIntParameter(CoreConnectionPNames.SO_TIMEOUT, 100);
-        params.setIntParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 100);
-        connFactory = new BasicConnFactory(params);
+        final SocketConfig sconfig = SocketConfig.custom().setSoTimeout(100).build();
+        connFactory = new BasicConnFactory(sconfig, ConnectionConfig.DEFAULT);
         pool = new BasicConnPool(connFactory);
     }
 
@@ -79,16 +75,10 @@ public class TestBasicConnPool {
         server.close();
         if(conn != null) {
             conn.close();
-            conn.shutdown();
         }
     }
 
     @Test(expected=IllegalArgumentException.class)
-    public void testNullConstructor1() throws Exception {
-        new BasicConnPool((HttpParams) null);
-    }
-
-    @Test(expected=IllegalArgumentException.class)
     public void testNullConstructor2() throws Exception {
         new BasicConnPool((BasicConnFactory) null);
     }
@@ -98,17 +88,21 @@ public class TestBasicConnPool {
         host = new HttpHost("localhost", serverPort, "http");
         conn = connFactory.create(host);
 
-        assertEquals(true, conn.isOpen());
+        assertTrue(conn.isOpen());
         assertEquals(100, conn.getSocketTimeout());
     }
 
     @Test
     public void testHttpsCreateConnection() throws Exception {
-        connFactory = new BasicConnFactory((SSLSocketFactory)SSLSocketFactory.getDefault(), params);
+        final SocketConfig sconfig = SocketConfig.custom().setSoTimeout(100).build();
+        connFactory = new BasicConnFactory(
+                null,
+                (SSLSocketFactory)SSLSocketFactory.getDefault(),
+                0, sconfig, ConnectionConfig.DEFAULT);
         host = new HttpHost("localhost", sslServerPort, "https");
         conn = connFactory.create(host);
 
-        assertEquals(true, conn.isOpen());
+        assertTrue(conn.isOpen());
         assertEquals(100, conn.getSocketTimeout());
     }
 
@@ -117,7 +111,7 @@ public class TestBasicConnPool {
         host = new HttpHost("localhost", serverPort, "http");
         conn = connFactory.create(host);
 
-        BasicPoolEntry entry = pool.createEntry(host, conn);
+        final BasicPoolEntry entry = pool.createEntry(host, conn);
 
         assertEquals(conn, entry.getConnection());
         assertEquals("localhost", entry.getRoute().getHostName());
diff --git a/httpcore/src/test/java/org/apache/http/integration/TestSyncHttp.java b/httpcore/src/test/java/org/apache/http/integration/TestSyncHttp.java
index 14fdb43..e3938a5 100644
--- a/httpcore/src/test/java/org/apache/http/integration/TestSyncHttp.java
+++ b/httpcore/src/test/java/org/apache/http/integration/TestSyncHttp.java
@@ -33,7 +33,6 @@ import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.io.OutputStream;
 import java.io.UnsupportedEncodingException;
-import java.net.Socket;
 import java.nio.charset.Charset;
 import java.util.ArrayList;
 import java.util.List;
@@ -54,10 +53,9 @@ import org.apache.http.entity.AbstractHttpEntity;
 import org.apache.http.entity.ByteArrayEntity;
 import org.apache.http.entity.ContentType;
 import org.apache.http.entity.StringEntity;
-import org.apache.http.impl.DefaultHttpClientConnection;
+import org.apache.http.impl.DefaultBHttpClientConnection;
 import org.apache.http.message.BasicHttpEntityEnclosingRequest;
 import org.apache.http.message.BasicHttpRequest;
-import org.apache.http.params.CoreProtocolPNames;
 import org.apache.http.protocol.HTTP;
 import org.apache.http.protocol.HttpContext;
 import org.apache.http.protocol.HttpExpectationVerifier;
@@ -84,11 +82,13 @@ public class TestSyncHttp {
     @Before
     public void initServer() throws Exception {
         this.server = new HttpServer();
+        this.server.setTimeout(5000);
     }
 
     @Before
     public void initClient() throws Exception {
         this.client = new HttpClient();
+        this.client.setTimeout(5000);
     }
 
     @After
@@ -104,15 +104,15 @@ public class TestSyncHttp {
     @Test
     public void testSimpleBasicHttpRequests() throws Exception {
 
-        int reqNo = 20;
+        final int reqNo = 20;
 
-        Random rnd = new Random();
+        final Random rnd = new Random();
 
         // Prepare some random data
         final List<byte[]> testData = new ArrayList<byte[]>(reqNo);
         for (int i = 0; i < reqNo; i++) {
-            int size = rnd.nextInt(5000);
-            byte[] data = new byte[size];
+            final int size = rnd.nextInt(5000);
+            final byte[] data = new byte[size];
             rnd.nextBytes(data);
             testData.add(data);
         }
@@ -129,9 +129,9 @@ public class TestSyncHttp {
                 if (s.startsWith("/?")) {
                     s = s.substring(2);
                 }
-                int index = Integer.parseInt(s);
-                byte[] data = testData.get(index);
-                ByteArrayEntity entity = new ByteArrayEntity(data);
+                final int index = Integer.parseInt(s);
+                final byte[] data = testData.get(index);
+                final ByteArrayEntity entity = new ByteArrayEntity(data);
                 response.setEntity(entity);
             }
 
@@ -139,20 +139,19 @@ public class TestSyncHttp {
 
         this.server.start();
 
-        DefaultHttpClientConnection conn = new DefaultHttpClientConnection();
-        HttpHost host = new HttpHost("localhost", this.server.getPort());
+        final DefaultBHttpClientConnection conn = client.createConnection();
+        final HttpHost host = new HttpHost("localhost", this.server.getPort());
 
         try {
             for (int r = 0; r < reqNo; r++) {
                 if (!conn.isOpen()) {
-                    Socket socket = new Socket(host.getHostName(), host.getPort());
-                    conn.bind(socket, this.client.getParams());
+                    client.connect(host, conn);
                 }
 
-                BasicHttpRequest get = new BasicHttpRequest("GET", "/?" + r);
-                HttpResponse response = this.client.execute(get, host, conn);
-                byte[] received = EntityUtils.toByteArray(response.getEntity());
-                byte[] expected = testData.get(r);
+                final BasicHttpRequest get = new BasicHttpRequest("GET", "/?" + r);
+                final HttpResponse response = this.client.execute(get, host, conn);
+                final byte[] received = EntityUtils.toByteArray(response.getEntity());
+                final byte[] expected = testData.get(r);
 
                 Assert.assertEquals(expected.length, received.length);
                 for (int i = 0; i < expected.length; i++) {
@@ -164,7 +163,7 @@ public class TestSyncHttp {
             }
 
             //Verify the connection metrics
-            HttpConnectionMetrics cm = conn.getMetrics();
+            final HttpConnectionMetrics cm = conn.getMetrics();
             Assert.assertEquals(reqNo, cm.getRequestCount());
             Assert.assertEquals(reqNo, cm.getResponseCount());
 
@@ -181,15 +180,15 @@ public class TestSyncHttp {
     @Test
     public void testSimpleHttpPostsWithContentLength() throws Exception {
 
-        int reqNo = 20;
+        final int reqNo = 20;
 
-        Random rnd = new Random();
+        final Random rnd = new Random();
 
         // Prepare some random data
-        List<byte[]> testData = new ArrayList<byte[]>(reqNo);
+        final List<byte[]> testData = new ArrayList<byte[]>(reqNo);
         for (int i = 0; i < reqNo; i++) {
-            int size = rnd.nextInt(5000);
-            byte[] data = new byte[size];
+            final int size = rnd.nextInt(5000);
+            final byte[] data = new byte[size];
             rnd.nextBytes(data);
             testData.add(data);
         }
@@ -203,14 +202,14 @@ public class TestSyncHttp {
                     final HttpContext context) throws HttpException, IOException {
 
                 if (request instanceof HttpEntityEnclosingRequest) {
-                    HttpEntity incoming = ((HttpEntityEnclosingRequest) request).getEntity();
-                    byte[] data = EntityUtils.toByteArray(incoming);
+                    final HttpEntity incoming = ((HttpEntityEnclosingRequest) request).getEntity();
+                    final byte[] data = EntityUtils.toByteArray(incoming);
 
-                    ByteArrayEntity outgoing = new ByteArrayEntity(data);
+                    final ByteArrayEntity outgoing = new ByteArrayEntity(data);
                     outgoing.setChunked(false);
                     response.setEntity(outgoing);
                 } else {
-                    StringEntity outgoing = new StringEntity("No content");
+                    final StringEntity outgoing = new StringEntity("No content");
                     response.setEntity(outgoing);
                 }
             }
@@ -219,24 +218,23 @@ public class TestSyncHttp {
 
         this.server.start();
 
-        DefaultHttpClientConnection conn = new DefaultHttpClientConnection();
-        HttpHost host = new HttpHost("localhost", this.server.getPort());
+        final DefaultBHttpClientConnection conn = client.createConnection();
+        final HttpHost host = new HttpHost("localhost", this.server.getPort());
 
         try {
             for (int r = 0; r < reqNo; r++) {
                 if (!conn.isOpen()) {
-                    Socket socket = new Socket(host.getHostName(), host.getPort());
-                    conn.bind(socket, this.client.getParams());
+                    client.connect(host, conn);
                 }
 
-                BasicHttpEntityEnclosingRequest post = new BasicHttpEntityEnclosingRequest("POST", "/");
-                byte[] data = testData.get(r);
-                ByteArrayEntity outgoing = new ByteArrayEntity(data);
+                final BasicHttpEntityEnclosingRequest post = new BasicHttpEntityEnclosingRequest("POST", "/");
+                final byte[] data = testData.get(r);
+                final ByteArrayEntity outgoing = new ByteArrayEntity(data);
                 post.setEntity(outgoing);
 
-                HttpResponse response = this.client.execute(post, host, conn);
-                byte[] received = EntityUtils.toByteArray(response.getEntity());
-                byte[] expected = testData.get(r);
+                final HttpResponse response = this.client.execute(post, host, conn);
+                final byte[] received = EntityUtils.toByteArray(response.getEntity());
+                final byte[] expected = testData.get(r);
 
                 Assert.assertEquals(expected.length, received.length);
                 for (int i = 0; i < expected.length; i++) {
@@ -247,7 +245,7 @@ public class TestSyncHttp {
                 }
             }
             //Verify the connection metrics
-            HttpConnectionMetrics cm = conn.getMetrics();
+            final HttpConnectionMetrics cm = conn.getMetrics();
             Assert.assertEquals(reqNo, cm.getRequestCount());
             Assert.assertEquals(reqNo, cm.getResponseCount());
 
@@ -264,15 +262,15 @@ public class TestSyncHttp {
     @Test
     public void testSimpleHttpPostsChunked() throws Exception {
 
-        int reqNo = 20;
+        final int reqNo = 20;
 
-        Random rnd = new Random();
+        final Random rnd = new Random();
 
         // Prepare some random data
-        List<byte[]> testData = new ArrayList<byte[]>(reqNo);
+        final List<byte[]> testData = new ArrayList<byte[]>(reqNo);
         for (int i = 0; i < reqNo; i++) {
-            int size = rnd.nextInt(20000);
-            byte[] data = new byte[size];
+            final int size = rnd.nextInt(20000);
+            final byte[] data = new byte[size];
             rnd.nextBytes(data);
             testData.add(data);
         }
@@ -286,14 +284,14 @@ public class TestSyncHttp {
                     final HttpContext context) throws HttpException, IOException {
 
                 if (request instanceof HttpEntityEnclosingRequest) {
-                    HttpEntity incoming = ((HttpEntityEnclosingRequest) request).getEntity();
-                    byte[] data = EntityUtils.toByteArray(incoming);
+                    final HttpEntity incoming = ((HttpEntityEnclosingRequest) request).getEntity();
+                    final byte[] data = EntityUtils.toByteArray(incoming);
 
-                    ByteArrayEntity outgoing = new ByteArrayEntity(data);
+                    final ByteArrayEntity outgoing = new ByteArrayEntity(data);
                     outgoing.setChunked(true);
                     response.setEntity(outgoing);
                 } else {
-                    StringEntity outgoing = new StringEntity("No content");
+                    final StringEntity outgoing = new StringEntity("No content");
                     response.setEntity(outgoing);
                 }
             }
@@ -302,25 +300,24 @@ public class TestSyncHttp {
 
         this.server.start();
 
-        DefaultHttpClientConnection conn = new DefaultHttpClientConnection();
-        HttpHost host = new HttpHost("localhost", this.server.getPort());
+        final DefaultBHttpClientConnection conn = client.createConnection();
+        final HttpHost host = new HttpHost("localhost", this.server.getPort());
 
         try {
             for (int r = 0; r < reqNo; r++) {
                 if (!conn.isOpen()) {
-                    Socket socket = new Socket(host.getHostName(), host.getPort());
-                    conn.bind(socket, this.client.getParams());
+                    client.connect(host, conn);
                 }
 
-                BasicHttpEntityEnclosingRequest post = new BasicHttpEntityEnclosingRequest("POST", "/");
-                byte[] data = testData.get(r);
-                ByteArrayEntity outgoing = new ByteArrayEntity(data);
+                final BasicHttpEntityEnclosingRequest post = new BasicHttpEntityEnclosingRequest("POST", "/");
+                final byte[] data = testData.get(r);
+                final ByteArrayEntity outgoing = new ByteArrayEntity(data);
                 outgoing.setChunked(true);
                 post.setEntity(outgoing);
 
-                HttpResponse response = this.client.execute(post, host, conn);
-                byte[] received = EntityUtils.toByteArray(response.getEntity());
-                byte[] expected = testData.get(r);
+                final HttpResponse response = this.client.execute(post, host, conn);
+                final byte[] received = EntityUtils.toByteArray(response.getEntity());
+                final byte[] expected = testData.get(r);
 
                 Assert.assertEquals(expected.length, received.length);
                 for (int i = 0; i < expected.length; i++) {
@@ -331,7 +328,7 @@ public class TestSyncHttp {
                 }
             }
             //Verify the connection metrics
-            HttpConnectionMetrics cm = conn.getMetrics();
+            final HttpConnectionMetrics cm = conn.getMetrics();
             Assert.assertEquals(reqNo, cm.getRequestCount());
             Assert.assertEquals(reqNo, cm.getResponseCount());
         } finally {
@@ -346,15 +343,15 @@ public class TestSyncHttp {
     @Test
     public void testSimpleHttpPostsHTTP10() throws Exception {
 
-        int reqNo = 20;
+        final int reqNo = 20;
 
-        Random rnd = new Random();
+        final Random rnd = new Random();
 
         // Prepare some random data
-        List<byte[]> testData = new ArrayList<byte[]>(reqNo);
+        final List<byte[]> testData = new ArrayList<byte[]>(reqNo);
         for (int i = 0; i < reqNo; i++) {
-            int size = rnd.nextInt(5000);
-            byte[] data = new byte[size];
+            final int size = rnd.nextInt(5000);
+            final byte[] data = new byte[size];
             rnd.nextBytes(data);
             testData.add(data);
         }
@@ -368,14 +365,14 @@ public class TestSyncHttp {
                     final HttpContext context) throws HttpException, IOException {
 
                 if (request instanceof HttpEntityEnclosingRequest) {
-                    HttpEntity incoming = ((HttpEntityEnclosingRequest) request).getEntity();
-                    byte[] data = EntityUtils.toByteArray(incoming);
+                    final HttpEntity incoming = ((HttpEntityEnclosingRequest) request).getEntity();
+                    final byte[] data = EntityUtils.toByteArray(incoming);
 
-                    ByteArrayEntity outgoing = new ByteArrayEntity(data);
+                    final ByteArrayEntity outgoing = new ByteArrayEntity(data);
                     outgoing.setChunked(false);
                     response.setEntity(outgoing);
                 } else {
-                    StringEntity outgoing = new StringEntity("No content");
+                    final StringEntity outgoing = new StringEntity("No content");
                     response.setEntity(outgoing);
                 }
             }
@@ -384,29 +381,26 @@ public class TestSyncHttp {
 
         this.server.start();
 
-        // Set protocol level to HTTP/1.0
-        this.client.getParams().setParameter(
-                CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_0);
-
-        DefaultHttpClientConnection conn = new DefaultHttpClientConnection();
-        HttpHost host = new HttpHost("localhost", this.server.getPort());
+        final DefaultBHttpClientConnection conn = client.createConnection();
+        final HttpHost host = new HttpHost("localhost", this.server.getPort());
 
         try {
             for (int r = 0; r < reqNo; r++) {
                 if (!conn.isOpen()) {
-                    Socket socket = new Socket(host.getHostName(), host.getPort());
-                    conn.bind(socket, this.client.getParams());
+                    client.connect(host, conn);
                 }
 
-                BasicHttpEntityEnclosingRequest post = new BasicHttpEntityEnclosingRequest("POST", "/");
-                byte[] data = testData.get(r);
-                ByteArrayEntity outgoing = new ByteArrayEntity(data);
+                // Set protocol level to HTTP/1.0
+                final BasicHttpEntityEnclosingRequest post = new BasicHttpEntityEnclosingRequest(
+                        "POST", "/", HttpVersion.HTTP_1_0);
+                final byte[] data = testData.get(r);
+                final ByteArrayEntity outgoing = new ByteArrayEntity(data);
                 post.setEntity(outgoing);
 
-                HttpResponse response = this.client.execute(post, host, conn);
+                final HttpResponse response = this.client.execute(post, host, conn);
                 Assert.assertEquals(HttpVersion.HTTP_1_1, response.getStatusLine().getProtocolVersion());
-                byte[] received = EntityUtils.toByteArray(response.getEntity());
-                byte[] expected = testData.get(r);
+                final byte[] received = EntityUtils.toByteArray(response.getEntity());
+                final byte[] expected = testData.get(r);
 
                 Assert.assertEquals(expected.length, received.length);
                 for (int i = 0; i < expected.length; i++) {
@@ -418,7 +412,7 @@ public class TestSyncHttp {
             }
 
             //Verify the connection metrics
-            HttpConnectionMetrics cm = conn.getMetrics();
+            final HttpConnectionMetrics cm = conn.getMetrics();
             Assert.assertEquals(reqNo, cm.getRequestCount());
             Assert.assertEquals(reqNo, cm.getResponseCount());
         } finally {
@@ -434,15 +428,15 @@ public class TestSyncHttp {
     @Test
     public void testHttpPostsWithExpectContinue() throws Exception {
 
-        int reqNo = 20;
+        final int reqNo = 20;
 
-        Random rnd = new Random();
+        final Random rnd = new Random();
 
         // Prepare some random data
-        List<byte[]> testData = new ArrayList<byte[]>(reqNo);
+        final List<byte[]> testData = new ArrayList<byte[]>(reqNo);
         for (int i = 0; i < reqNo; i++) {
-            int size = rnd.nextInt(5000);
-            byte[] data = new byte[size];
+            final int size = rnd.nextInt(5000);
+            final byte[] data = new byte[size];
             rnd.nextBytes(data);
             testData.add(data);
         }
@@ -456,14 +450,14 @@ public class TestSyncHttp {
                     final HttpContext context) throws HttpException, IOException {
 
                 if (request instanceof HttpEntityEnclosingRequest) {
-                    HttpEntity incoming = ((HttpEntityEnclosingRequest) request).getEntity();
-                    byte[] data = EntityUtils.toByteArray(incoming);
+                    final HttpEntity incoming = ((HttpEntityEnclosingRequest) request).getEntity();
+                    final byte[] data = EntityUtils.toByteArray(incoming);
 
-                    ByteArrayEntity outgoing = new ByteArrayEntity(data);
+                    final ByteArrayEntity outgoing = new ByteArrayEntity(data);
                     outgoing.setChunked(true);
                     response.setEntity(outgoing);
                 } else {
-                    StringEntity outgoing = new StringEntity("No content");
+                    final StringEntity outgoing = new StringEntity("No content");
                     response.setEntity(outgoing);
                 }
             }
@@ -473,27 +467,24 @@ public class TestSyncHttp {
         this.server.start();
 
         // Activate 'expect: continue' handshake
-        this.client.getParams().setBooleanParameter(CoreProtocolPNames.USE_EXPECT_CONTINUE, true);
-
-        DefaultHttpClientConnection conn = new DefaultHttpClientConnection();
-        HttpHost host = new HttpHost("localhost", this.server.getPort());
+        final DefaultBHttpClientConnection conn = client.createConnection();
+        final HttpHost host = new HttpHost("localhost", this.server.getPort());
 
         try {
             for (int r = 0; r < reqNo; r++) {
                 if (!conn.isOpen()) {
-                    Socket socket = new Socket(host.getHostName(), host.getPort());
-                    conn.bind(socket, this.client.getParams());
+                    client.connect(host, conn);
                 }
 
-                BasicHttpEntityEnclosingRequest post = new BasicHttpEntityEnclosingRequest("POST", "/");
-                byte[] data = testData.get(r);
-                ByteArrayEntity outgoing = new ByteArrayEntity(data);
+                final BasicHttpEntityEnclosingRequest post = new BasicHttpEntityEnclosingRequest("POST", "/");
+                final byte[] data = testData.get(r);
+                final ByteArrayEntity outgoing = new ByteArrayEntity(data);
                 outgoing.setChunked(true);
                 post.setEntity(outgoing);
 
-                HttpResponse response = this.client.execute(post, host, conn);
-                byte[] received = EntityUtils.toByteArray(response.getEntity());
-                byte[] expected = testData.get(r);
+                final HttpResponse response = this.client.execute(post, host, conn);
+                final byte[] received = EntityUtils.toByteArray(response.getEntity());
+                final byte[] expected = testData.get(r);
 
                 Assert.assertEquals(expected.length, received.length);
                 for (int i = 0; i < expected.length; i++) {
@@ -505,7 +496,7 @@ public class TestSyncHttp {
             }
 
             //Verify the connection metrics
-            HttpConnectionMetrics cm = conn.getMetrics();
+            final HttpConnectionMetrics cm = conn.getMetrics();
             Assert.assertEquals(reqNo, cm.getRequestCount());
             Assert.assertEquals(reqNo, cm.getResponseCount());
         } finally {
@@ -522,7 +513,7 @@ public class TestSyncHttp {
     @Test
     public void testHttpPostsWithExpectationVerification() throws Exception {
 
-        int reqNo = 3;
+        final int reqNo = 3;
 
         // Initialize the server-side request handler
         this.server.registerHandler("*", new HttpRequestHandler() {
@@ -532,7 +523,7 @@ public class TestSyncHttp {
                     final HttpResponse response,
                     final HttpContext context) throws HttpException, IOException {
 
-                StringEntity outgoing = new StringEntity("No content");
+                final StringEntity outgoing = new StringEntity("No content");
                 response.setEntity(outgoing);
             }
 
@@ -544,18 +535,18 @@ public class TestSyncHttp {
                     final HttpRequest request,
                     final HttpResponse response,
                     final HttpContext context) throws HttpException {
-                Header someheader = request.getFirstHeader("Secret");
+                final Header someheader = request.getFirstHeader("Secret");
                 if (someheader != null) {
                     int secretNumber;
                     try {
                         secretNumber = Integer.parseInt(someheader.getValue());
-                    } catch (NumberFormatException ex) {
+                    } catch (final NumberFormatException ex) {
                         response.setStatusCode(HttpStatus.SC_BAD_REQUEST);
                         return;
                     }
                     if (secretNumber < 2) {
                         response.setStatusCode(HttpStatus.SC_EXPECTATION_FAILED);
-                        ByteArrayEntity outgoing = new ByteArrayEntity(
+                        final ByteArrayEntity outgoing = new ByteArrayEntity(
                                 EncodingUtils.getAsciiBytes("Wrong secret number"));
                         response.setEntity(outgoing);
                     }
@@ -566,28 +557,24 @@ public class TestSyncHttp {
 
         this.server.start();
 
-        // Activate 'expect: continue' handshake
-        this.client.getParams().setBooleanParameter(CoreProtocolPNames.USE_EXPECT_CONTINUE, true);
-
-        DefaultHttpClientConnection conn = new DefaultHttpClientConnection();
-        HttpHost host = new HttpHost("localhost", this.server.getPort());
+        final DefaultBHttpClientConnection conn = client.createConnection();
+        final HttpHost host = new HttpHost("localhost", this.server.getPort());
 
         try {
             for (int r = 0; r < reqNo; r++) {
                 if (!conn.isOpen()) {
-                    Socket socket = new Socket(host.getHostName(), host.getPort());
-                    conn.bind(socket, this.client.getParams());
+                    client.connect(host, conn);
                 }
 
-                BasicHttpEntityEnclosingRequest post = new BasicHttpEntityEnclosingRequest("POST", "/");
+                final BasicHttpEntityEnclosingRequest post = new BasicHttpEntityEnclosingRequest("POST", "/");
                 post.addHeader("Secret", Integer.toString(r));
-                ByteArrayEntity outgoing = new ByteArrayEntity(
-                        EncodingUtils.getAsciiBytes("No content"));
+                final ByteArrayEntity outgoing = new ByteArrayEntity(
+                        EncodingUtils.getAsciiBytes("No content " + r));
                 post.setEntity(outgoing);
 
-                HttpResponse response = this.client.execute(post, host, conn);
+                final HttpResponse response = this.client.execute(post, host, conn);
 
-                HttpEntity entity = response.getEntity();
+                final HttpEntity entity = response.getEntity();
                 Assert.assertNotNull(entity);
                 EntityUtils.consume(entity);
 
@@ -602,7 +589,7 @@ public class TestSyncHttp {
                 }
             }
             //Verify the connection metrics
-            HttpConnectionMetrics cm = conn.getMetrics();
+            final HttpConnectionMetrics cm = conn.getMetrics();
             Assert.assertEquals(reqNo, cm.getRequestCount());
             Assert.assertEquals(reqNo, cm.getResponseCount());
         } finally {
@@ -614,26 +601,18 @@ public class TestSyncHttp {
     static class RepeatingEntity extends AbstractHttpEntity {
 
         private final byte[] raw;
-        private int n;
+        private final int n;
 
-        public RepeatingEntity(final String content, Charset charset, int n) {
+        public RepeatingEntity(final String content, final Charset charset, final int n) {
             super();
-            if (content == null) {
-                throw new IllegalArgumentException("Content may not be null");
-            }
-            if (n <= 0) {
-                throw new IllegalArgumentException("N may not be negative or zero");
-            }
-            if (charset == null) {
-                charset = Charset.forName("US-ASCII"); // US-ASCII is built-in
-            }
+            final Charset cs = charset != null ? charset : Charset.forName("US-ASCII");
             byte[] b;
             // Java 6 only:
             // b = content.getBytes(charset);
             // Java 5 OK:
             try {
-                b = content.getBytes(charset.name());
-            } catch (UnsupportedEncodingException ex) {
+                b = content.getBytes(cs.name());
+            } catch (final UnsupportedEncodingException ex) {
                 b = content.getBytes();
             }
             this.raw = b;
@@ -670,7 +649,7 @@ public class TestSyncHttp {
     @Test
     public void testHttpContent() throws Exception {
 
-        String[] patterns = {
+        final String[] patterns = {
 
             "0123456789ABCDEF",
             "yadayada-blahblah-this-and-that-yadayada-blahblah-this-and-that-" +
@@ -709,20 +688,20 @@ public class TestSyncHttp {
                                 throw new HttpException("Invalid request: " +
                                         "number of repetitions cannot be negative or zero");
                             }
-                        } catch (NumberFormatException ex) {
+                        } catch (final NumberFormatException ex) {
                             throw new HttpException("Invalid request: " +
                                     "number of repetitions is invalid");
                         }
                     }
 
-                    HttpEntity incoming = ((HttpEntityEnclosingRequest) request).getEntity();
-                    String line = EntityUtils.toString(incoming);
-                    ContentType contentType = ContentType.getOrDefault(incoming);
+                    final HttpEntity incoming = ((HttpEntityEnclosingRequest) request).getEntity();
+                    final String line = EntityUtils.toString(incoming);
+                    final ContentType contentType = ContentType.getOrDefault(incoming);
                     Charset charset = contentType.getCharset();
                     if (charset == null) {
                         charset = HTTP.DEF_CONTENT_CHARSET;
                     }
-                    RepeatingEntity outgoing = new RepeatingEntity(line, charset, n);
+                    final RepeatingEntity outgoing = new RepeatingEntity(line, charset, n);
                     outgoing.setChunked(n % 2 == 0);
                     response.setEntity(outgoing);
                 } else {
@@ -733,35 +712,33 @@ public class TestSyncHttp {
         });
 
         this.server.start();
-        DefaultHttpClientConnection conn = new DefaultHttpClientConnection();
-        HttpHost host = new HttpHost("localhost", this.server.getPort());
+        final DefaultBHttpClientConnection conn = client.createConnection();
+        final HttpHost host = new HttpHost("localhost", this.server.getPort());
 
         try {
-            for (int i = 0; i < patterns.length; i++) {
-                String pattern = patterns[i];
+            for (final String pattern : patterns) {
                 for (int n = 1000; n < 1020; n++) {
                     if (!conn.isOpen()) {
-                        Socket socket = new Socket(host.getHostName(), host.getPort());
-                        conn.bind(socket, this.client.getParams());
+                        client.connect(host, conn);
                     }
 
-                    BasicHttpEntityEnclosingRequest post = new BasicHttpEntityEnclosingRequest(
+                    final BasicHttpEntityEnclosingRequest post = new BasicHttpEntityEnclosingRequest(
                             "POST", "/?n=" + n);
-                    StringEntity outgoing = new StringEntity(pattern);
+                    final StringEntity outgoing = new StringEntity(pattern);
                     outgoing.setChunked(n % 2 == 0);
                     post.setEntity(outgoing);
 
-                    HttpResponse response = this.client.execute(post, host, conn);
-                    HttpEntity incoming = response.getEntity();
+                    final HttpResponse response = this.client.execute(post, host, conn);
+                    final HttpEntity incoming = response.getEntity();
                     Assert.assertNotNull(incoming);
-                    InputStream instream = incoming.getContent();
-                    ContentType contentType = ContentType.getOrDefault(incoming);
+                    final InputStream instream = incoming.getContent();
+                    final ContentType contentType = ContentType.getOrDefault(incoming);
                     Charset charset = contentType.getCharset();
                     if (charset == null) {
                         charset = HTTP.DEF_CONTENT_CHARSET;
                     }
                     Assert.assertNotNull(instream);
-                    BufferedReader reader = new BufferedReader(new InputStreamReader(instream, charset));
+                    final BufferedReader reader = new BufferedReader(new InputStreamReader(instream, charset));
 
                     String line;
                     int count = 0;
@@ -791,12 +768,12 @@ public class TestSyncHttp {
                     final HttpContext context) throws HttpException, IOException {
 
                 if (request instanceof HttpEntityEnclosingRequest) {
-                    HttpEntity incoming = ((HttpEntityEnclosingRequest) request).getEntity();
-                    byte[] data = EntityUtils.toByteArray(incoming);
-                    ByteArrayEntity outgoing = new ByteArrayEntity(data);
+                    final HttpEntity incoming = ((HttpEntityEnclosingRequest) request).getEntity();
+                    final byte[] data = EntityUtils.toByteArray(incoming);
+                    final ByteArrayEntity outgoing = new ByteArrayEntity(data);
                     response.setEntity(outgoing);
                 } else {
-                    StringEntity outgoing = new StringEntity("No content");
+                    final StringEntity outgoing = new StringEntity("No content");
                     response.setEntity(outgoing);
                 }
             }
@@ -805,21 +782,20 @@ public class TestSyncHttp {
 
         this.server.start();
 
-        DefaultHttpClientConnection conn = new DefaultHttpClientConnection();
-        HttpHost host = new HttpHost("localhost", this.server.getPort());
+        final DefaultBHttpClientConnection conn = client.createConnection();
+        final HttpHost host = new HttpHost("localhost", this.server.getPort());
 
         try {
             if (!conn.isOpen()) {
-                Socket socket = new Socket(host.getHostName(), host.getPort());
-                conn.bind(socket, this.client.getParams());
+                client.connect(host, conn);
             }
 
-            BasicHttpEntityEnclosingRequest post = new BasicHttpEntityEnclosingRequest("POST", "/");
+            final BasicHttpEntityEnclosingRequest post = new BasicHttpEntityEnclosingRequest("POST", "/");
             post.setEntity(null);
 
-            HttpResponse response = this.client.execute(post, host, conn);
+            final HttpResponse response = this.client.execute(post, host, conn);
             Assert.assertEquals(HttpStatus.SC_OK, response.getStatusLine().getStatusCode());
-            byte[] received = EntityUtils.toByteArray(response.getEntity());
+            final byte[] received = EntityUtils.toByteArray(response.getEntity());
             Assert.assertEquals(0, received.length);
         } finally {
             conn.close();
@@ -837,12 +813,12 @@ public class TestSyncHttp {
                     final HttpContext context) throws HttpException, IOException {
 
                 if (request instanceof HttpEntityEnclosingRequest) {
-                    HttpEntity incoming = ((HttpEntityEnclosingRequest) request).getEntity();
-                    byte[] data = EntityUtils.toByteArray(incoming);
-                    ByteArrayEntity outgoing = new ByteArrayEntity(data);
+                    final HttpEntity incoming = ((HttpEntityEnclosingRequest) request).getEntity();
+                    final byte[] data = EntityUtils.toByteArray(incoming);
+                    final ByteArrayEntity outgoing = new ByteArrayEntity(data);
                     response.setEntity(outgoing);
                 } else {
-                    StringEntity outgoing = new StringEntity("No content");
+                    final StringEntity outgoing = new StringEntity("No content");
                     response.setEntity(outgoing);
                 }
             }
@@ -851,16 +827,15 @@ public class TestSyncHttp {
 
         this.server.start();
 
-        DefaultHttpClientConnection conn = new DefaultHttpClientConnection();
-        HttpHost host = new HttpHost("localhost", this.server.getPort());
+        final DefaultBHttpClientConnection conn = client.createConnection();
+        final HttpHost host = new HttpHost("localhost", this.server.getPort());
 
         try {
             if (!conn.isOpen()) {
-                Socket socket = new Socket(host.getHostName(), host.getPort());
-                conn.bind(socket, this.client.getParams());
+                client.connect(host, conn);
             }
 
-            BasicHttpEntityEnclosingRequest post = new BasicHttpEntityEnclosingRequest("POST", "/");
+            final BasicHttpEntityEnclosingRequest post = new BasicHttpEntityEnclosingRequest("POST", "/");
             post.setEntity(null);
 
             this.client = new HttpClient(new ImmutableHttpProcessor(
@@ -868,11 +843,11 @@ public class TestSyncHttp {
                             new RequestTargetHost(),
                             new RequestConnControl(),
                             new RequestUserAgent(),
-                            new RequestExpectContinue() }));
-            
-            HttpResponse response = this.client.execute(post, host, conn);
+                            new RequestExpectContinue(true) }));
+
+            final HttpResponse response = this.client.execute(post, host, conn);
             Assert.assertEquals(HttpStatus.SC_OK, response.getStatusLine().getStatusCode());
-            byte[] received = EntityUtils.toByteArray(response.getEntity());
+            final byte[] received = EntityUtils.toByteArray(response.getEntity());
             Assert.assertEquals(0, received.length);
         } finally {
             conn.close();
@@ -890,12 +865,12 @@ public class TestSyncHttp {
                     final HttpContext context) throws HttpException, IOException {
 
                 if (request instanceof HttpEntityEnclosingRequest) {
-                    HttpEntity incoming = ((HttpEntityEnclosingRequest) request).getEntity();
-                    byte[] data = EntityUtils.toByteArray(incoming);
-                    ByteArrayEntity outgoing = new ByteArrayEntity(data);
+                    final HttpEntity incoming = ((HttpEntityEnclosingRequest) request).getEntity();
+                    final byte[] data = EntityUtils.toByteArray(incoming);
+                    final ByteArrayEntity outgoing = new ByteArrayEntity(data);
                     response.setEntity(outgoing);
                 } else {
-                    StringEntity outgoing = new StringEntity("No content");
+                    final StringEntity outgoing = new StringEntity("No content");
                     response.setEntity(outgoing);
                 }
             }
@@ -904,24 +879,23 @@ public class TestSyncHttp {
 
         this.server.start();
 
-        DefaultHttpClientConnection conn = new DefaultHttpClientConnection();
-        HttpHost host = new HttpHost("localhost", this.server.getPort());
+        final DefaultBHttpClientConnection conn = client.createConnection();
+        final HttpHost host = new HttpHost("localhost", this.server.getPort());
 
         try {
             if (!conn.isOpen()) {
-                Socket socket = new Socket(host.getHostName(), host.getPort());
-                conn.bind(socket, this.client.getParams());
+                client.connect(host, conn);
             }
 
-            BasicHttpEntityEnclosingRequest post = new BasicHttpEntityEnclosingRequest("POST", "/");
+            final BasicHttpEntityEnclosingRequest post = new BasicHttpEntityEnclosingRequest("POST", "/");
             post.setEntity(null);
 
             this.client = new HttpClient(new ImmutableHttpProcessor(
                     new HttpRequestInterceptor[] {
                             new HttpRequestInterceptor() {
-                                
+
                                 public void process(
-                                        final HttpRequest request, 
+                                        final HttpRequest request,
                                         final HttpContext context) throws HttpException, IOException {
                                     request.addHeader(HTTP.TRANSFER_ENCODING, "identity");
                                 }
@@ -930,9 +904,9 @@ public class TestSyncHttp {
                             new RequestTargetHost(),
                             new RequestConnControl(),
                             new RequestUserAgent(),
-                            new RequestExpectContinue() }));
-            
-            HttpResponse response = this.client.execute(post, host, conn);
+                            new RequestExpectContinue(true) }));
+
+            final HttpResponse response = this.client.execute(post, host, conn);
             Assert.assertEquals(HttpStatus.SC_BAD_REQUEST, response.getStatusLine().getStatusCode());
         } finally {
             conn.close();
@@ -943,7 +917,7 @@ public class TestSyncHttp {
     @Test
     public void testNoContentResponse() throws Exception {
 
-        int reqNo = 20;
+        final int reqNo = 20;
 
         // Initialize the server-side request handler
         this.server.registerHandler("*", new HttpRequestHandler() {
@@ -959,18 +933,17 @@ public class TestSyncHttp {
 
         this.server.start();
 
-        DefaultHttpClientConnection conn = new DefaultHttpClientConnection();
-        HttpHost host = new HttpHost("localhost", this.server.getPort());
+        final DefaultBHttpClientConnection conn = client.createConnection();
+        final HttpHost host = new HttpHost("localhost", this.server.getPort());
 
         try {
             for (int r = 0; r < reqNo; r++) {
                 if (!conn.isOpen()) {
-                    Socket socket = new Socket(host.getHostName(), host.getPort());
-                    conn.bind(socket, this.client.getParams());
+                    client.connect(host, conn);
                 }
 
-                BasicHttpRequest get = new BasicHttpRequest("GET", "/?" + r);
-                HttpResponse response = this.client.execute(get, host, conn);
+                final BasicHttpRequest get = new BasicHttpRequest("GET", "/?" + r);
+                final HttpResponse response = this.client.execute(get, host, conn);
                 Assert.assertNull(response.getEntity());
                 if (!this.client.keepAlive(response)) {
                     conn.close();
@@ -979,7 +952,7 @@ public class TestSyncHttp {
             }
 
             //Verify the connection metrics
-            HttpConnectionMetrics cm = conn.getMetrics();
+            final HttpConnectionMetrics cm = conn.getMetrics();
             Assert.assertEquals(reqNo, cm.getRequestCount());
             Assert.assertEquals(reqNo, cm.getResponseCount());
 
diff --git a/httpcore/src/test/java/org/apache/http/message/TestAbstractMessage.java b/httpcore/src/test/java/org/apache/http/message/TestAbstractMessage.java
index cd41b6c..15371d5 100644
--- a/httpcore/src/test/java/org/apache/http/message/TestAbstractMessage.java
+++ b/httpcore/src/test/java/org/apache/http/message/TestAbstractMessage.java
@@ -24,49 +24,52 @@
  * <http://www.apache.org/>.
  *
  */
-
 package org.apache.http.message;
 
 import org.apache.http.Header;
 import org.apache.http.HttpMessage;
+import org.apache.http.HttpVersion;
 import org.apache.http.ProtocolVersion;
-import org.apache.http.params.BasicHttpParams;
-import org.apache.http.params.HttpParams;
-import org.apache.http.params.HttpProtocolParams;
 import org.junit.Assert;
 import org.junit.Test;
 
 /**
- * Unit tests for {@link Header}.
+ * Unit tests for {@link AbstractHttpMessage}.
  *
  */
 public class TestAbstractMessage {
 
     static class TestHttpMessage extends AbstractHttpMessage {
 
-        public TestHttpMessage() {
+        private final ProtocolVersion ver;
+
+        public TestHttpMessage(final ProtocolVersion ver) {
             super();
+            this.ver = ver != null ? ver : HttpVersion.HTTP_1_1;
+        }
+
+        public TestHttpMessage() {
+            this(HttpVersion.HTTP_1_1);
         }
 
         public ProtocolVersion getProtocolVersion() {
-            return HttpProtocolParams.getVersion(this.getParams());
+            return ver;
         }
 
     }
 
     @Test
     public void testBasicProperties() {
-        HttpMessage message = new TestHttpMessage();
-        Assert.assertNotNull(message.getParams());
+        final HttpMessage message = new TestHttpMessage();
         Assert.assertNotNull(message.headerIterator());
-        Header[] headers = message.getAllHeaders();
+        final Header[] headers = message.getAllHeaders();
         Assert.assertNotNull(headers);
         Assert.assertEquals(0, headers.length);
     }
 
     @Test
     public void testBasicHeaderOps() {
-        HttpMessage message = new TestHttpMessage();
+        final HttpMessage message = new TestHttpMessage();
         Assert.assertFalse(message.containsHeader("whatever"));
 
         message.addHeader("name", "1");
@@ -124,33 +127,18 @@ public class TestAbstractMessage {
     }
 
     @Test
-    public void testParameters() {
-        HttpMessage message = new TestHttpMessage();
-        Assert.assertNotNull(message.getParams());
-        HttpParams params = new BasicHttpParams();
-        message.setParams(params);
-        Assert.assertTrue(params == message.getParams());
-    }
-
-    @Test
     public void testInvalidInput() {
-        HttpMessage message = new TestHttpMessage();
-        try {
-            message.setParams(null);
-            Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
-            // expected
-        }
+        final HttpMessage message = new TestHttpMessage();
         try {
             message.addHeader(null, null);
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
             // expected
         }
         try {
             message.setHeader(null, null);
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
             // expected
         }
     }
diff --git a/httpcore/src/test/java/org/apache/http/message/TestBasicHeaderElementIterator.java b/httpcore/src/test/java/org/apache/http/message/TestBasicHeaderElementIterator.java
index c47f140..88a6e15 100644
--- a/httpcore/src/test/java/org/apache/http/message/TestBasicHeaderElementIterator.java
+++ b/httpcore/src/test/java/org/apache/http/message/TestBasicHeaderElementIterator.java
@@ -24,7 +24,6 @@
  * <http://www.apache.org/>.
  *
  */
-
 package org.apache.http.message;
 
 import java.util.NoSuchElementException;
@@ -43,12 +42,12 @@ public class TestBasicHeaderElementIterator {
 
     @Test
     public void testMultiHeader() {
-        Header[] headers = new Header[]{
+        final Header[] headers = new Header[]{
                 new BasicHeader("Name", "value0"),
                 new BasicHeader("Name", "value1")
         };
 
-        HeaderElementIterator hei =
+        final HeaderElementIterator hei =
                 new BasicHeaderElementIterator(
                         new BasicHeaderIterator(headers, "Name"));
 
@@ -66,7 +65,7 @@ public class TestBasicHeaderElementIterator {
         try {
             hei.next();
             Assert.fail("NoSuchElementException should have been thrown");
-        } catch (NoSuchElementException ex) {
+        } catch (final NoSuchElementException ex) {
             // expected
         }
 
@@ -74,19 +73,19 @@ public class TestBasicHeaderElementIterator {
         try {
             hei.next();
             Assert.fail("NoSuchElementException should have been thrown");
-        } catch (NoSuchElementException ex) {
+        } catch (final NoSuchElementException ex) {
             // expected
         }
     }
 
     @Test
     public void testMultiHeaderSameLine() {
-        Header[] headers = new Header[]{
+        final Header[] headers = new Header[]{
                 new BasicHeader("name", "value0,value1"),
                 new BasicHeader("nAme", "cookie1=1,cookie2=2")
         };
 
-        HeaderElementIterator hei =
+        final HeaderElementIterator hei =
                 new BasicHeaderElementIterator(new BasicHeaderIterator(headers, "Name"));
 
         HeaderElement elem = hei.nextElement();
@@ -110,13 +109,13 @@ public class TestBasicHeaderElementIterator {
 
     @Test
     public void testFringeCases() {
-        Header[] headers = new Header[]{
+        final Header[] headers = new Header[]{
                 new BasicHeader("Name", null),
                 new BasicHeader("Name", "    "),
                 new BasicHeader("Name", ",,,")
         };
 
-        HeaderElementIterator hei =
+        final HeaderElementIterator hei =
                 new BasicHeaderElementIterator(
                         new BasicHeaderIterator(headers, "Name"));
 
@@ -124,7 +123,7 @@ public class TestBasicHeaderElementIterator {
         try {
             hei.next();
             Assert.fail("NoSuchElementException should have been thrown");
-        } catch (NoSuchElementException ex) {
+        } catch (final NoSuchElementException ex) {
             // expected
         }
 
@@ -132,7 +131,7 @@ public class TestBasicHeaderElementIterator {
         try {
             hei.next();
             Assert.fail("NoSuchElementException should have been thrown");
-        } catch (NoSuchElementException ex) {
+        } catch (final NoSuchElementException ex) {
             // expected
         }
     }
diff --git a/httpcore/src/test/java/org/apache/http/message/TestBasicHeaderIterator.java b/httpcore/src/test/java/org/apache/http/message/TestBasicHeaderIterator.java
index ab5eb4f..6a0666c 100644
--- a/httpcore/src/test/java/org/apache/http/message/TestBasicHeaderIterator.java
+++ b/httpcore/src/test/java/org/apache/http/message/TestBasicHeaderIterator.java
@@ -24,7 +24,6 @@
  * <http://www.apache.org/>.
  *
  */
-
 package org.apache.http.message;
 
 import java.util.NoSuchElementException;
@@ -43,7 +42,7 @@ public class TestBasicHeaderIterator {
 
     @Test
     public void testAllSame() {
-        Header[] headers = new Header[]{
+        final Header[] headers = new Header[]{
             new BasicHeader("Name", "value0"),
             new BasicHeader("nAme", "value1, value1.1"),
             new BasicHeader("naMe", "value2=whatever"),
@@ -78,7 +77,7 @@ public class TestBasicHeaderIterator {
 
     @Test
     public void testFirstLastOneNone() {
-        Header[] headers = new Header[]{
+        final Header[] headers = new Header[]{
             new BasicHeader("match"   , "value0"),
             new BasicHeader("mismatch", "value1, value1.1"),
             new BasicHeader("single"  , "value2=whatever"),
@@ -119,7 +118,7 @@ public class TestBasicHeaderIterator {
 
     @Test
     public void testInterspersed() {
-        Header[] headers = new Header[]{
+        final Header[] headers = new Header[]{
             new BasicHeader("yellow", "00"),
             new BasicHeader("maroon", "01"),
             new BasicHeader("orange", "02"),
@@ -222,7 +221,7 @@ public class TestBasicHeaderIterator {
         try {
             hit = new BasicHeaderIterator(null, "whatever");
             Assert.fail("null headers not detected");
-        } catch (IllegalArgumentException iax) {
+        } catch (final IllegalArgumentException iax) {
             // expected
         }
 
@@ -234,7 +233,7 @@ public class TestBasicHeaderIterator {
         try {
             hit.nextHeader();
             Assert.fail("next beyond end not detected");
-        } catch (NoSuchElementException nsx) {
+        } catch (final NoSuchElementException nsx) {
             // expected
         }
     }
@@ -244,7 +243,7 @@ public class TestBasicHeaderIterator {
     public void testRemaining() {
         // to satisfy Clover and take coverage to 100%
 
-        Header[] headers = new Header[]{
+        final Header[] headers = new Header[]{
             new BasicHeader("Name", "value0"),
             new BasicHeader("nAme", "value1, value1.1"),
             new BasicHeader("naMe", "value2=whatever"),
@@ -268,7 +267,7 @@ public class TestBasicHeaderIterator {
         try {
             hit.remove();
             Assert.fail("remove not detected");
-        } catch (UnsupportedOperationException uox) {
+        } catch (final UnsupportedOperationException uox) {
             // expected
         }
 
diff --git a/httpcore/src/test/java/org/apache/http/message/TestBasicHeaderValueFormatter.java b/httpcore/src/test/java/org/apache/http/message/TestBasicHeaderValueFormatter.java
index 2b07426..de7c8d6 100644
--- a/httpcore/src/test/java/org/apache/http/message/TestBasicHeaderValueFormatter.java
+++ b/httpcore/src/test/java/org/apache/http/message/TestBasicHeaderValueFormatter.java
@@ -23,10 +23,7 @@
  * information on the Apache Software Foundation, please see
  * <http://www.apache.org/>.
  *
- * [Additional notices, if required by prior licensing conditions]
- *
  */
-
 package org.apache.http.message;
 
 import org.apache.http.HeaderElement;
@@ -43,13 +40,13 @@ public class TestBasicHeaderValueFormatter {
 
     @Test
     public void testNVPFormatting() throws Exception {
-        NameValuePair param1 = new BasicNameValuePair("param", "regular_stuff");
-        NameValuePair param2 = new BasicNameValuePair("param", "this\\that");
-        NameValuePair param3 = new BasicNameValuePair("param", "this,that");
-        NameValuePair param4 = new BasicNameValuePair("param", "quote marks (\") must be escaped");
-        NameValuePair param5 = new BasicNameValuePair("param", "back slash (\\) must be escaped too");
-        NameValuePair param6 = new BasicNameValuePair("param", "values with\tblanks must always be quoted");
-        NameValuePair param7 = new BasicNameValuePair("param", null);
+        final NameValuePair param1 = new BasicNameValuePair("param", "regular_stuff");
+        final NameValuePair param2 = new BasicNameValuePair("param", "this\\that");
+        final NameValuePair param3 = new BasicNameValuePair("param", "this,that");
+        final NameValuePair param4 = new BasicNameValuePair("param", "quote marks (\") must be escaped");
+        final NameValuePair param5 = new BasicNameValuePair("param", "back slash (\\) must be escaped too");
+        final NameValuePair param6 = new BasicNameValuePair("param", "values with\tblanks must always be quoted");
+        final NameValuePair param7 = new BasicNameValuePair("param", null);
 
 
         Assert.assertEquals("param=regular_stuff",
@@ -100,10 +97,10 @@ public class TestBasicHeaderValueFormatter {
 
     @Test
     public void testParamsFormatting() throws Exception {
-        NameValuePair param1 = new BasicNameValuePair("param", "regular_stuff");
-        NameValuePair param2 = new BasicNameValuePair("param", "this\\that");
-        NameValuePair param3 = new BasicNameValuePair("param", "this,that");
-        NameValuePair[] params = new NameValuePair[] {param1, param2, param3};
+        final NameValuePair param1 = new BasicNameValuePair("param", "regular_stuff");
+        final NameValuePair param2 = new BasicNameValuePair("param", "this\\that");
+        final NameValuePair param3 = new BasicNameValuePair("param", "this,that");
+        final NameValuePair[] params = new NameValuePair[] {param1, param2, param3};
         Assert.assertEquals("param=regular_stuff; param=\"this\\\\that\"; param=\"this,that\"",
                      BasicHeaderValueFormatter.formatParameters(params, false, null));
         Assert.assertEquals("param=\"regular_stuff\"; param=\"this\\\\that\"; param=\"this,that\"",
@@ -114,12 +111,12 @@ public class TestBasicHeaderValueFormatter {
 
     @Test
     public void testHEFormatting() throws Exception {
-        NameValuePair param1 = new BasicNameValuePair("param", "regular_stuff");
-        NameValuePair param2 = new BasicNameValuePair("param", "this\\that");
-        NameValuePair param3 = new BasicNameValuePair("param", "this,that");
-        NameValuePair param4 = new BasicNameValuePair("param", null);
-        NameValuePair[] params = new NameValuePair[] {param1, param2, param3, param4};
-        HeaderElement element = new BasicHeaderElement("name", "value", params);
+        final NameValuePair param1 = new BasicNameValuePair("param", "regular_stuff");
+        final NameValuePair param2 = new BasicNameValuePair("param", "this\\that");
+        final NameValuePair param3 = new BasicNameValuePair("param", "this,that");
+        final NameValuePair param4 = new BasicNameValuePair("param", null);
+        final NameValuePair[] params = new NameValuePair[] {param1, param2, param3, param4};
+        final HeaderElement element = new BasicHeaderElement("name", "value", params);
 
         Assert.assertEquals("name=value; param=regular_stuff; param=\"this\\\\that\"; param=\"this,that\"; param",
                      BasicHeaderValueFormatter.formatHeaderElement(element, false, null));
@@ -127,16 +124,16 @@ public class TestBasicHeaderValueFormatter {
 
     @Test
     public void testElementsFormatting() throws Exception {
-        NameValuePair param1 = new BasicNameValuePair("param", "regular_stuff");
-        NameValuePair param2 = new BasicNameValuePair("param", "this\\that");
-        NameValuePair param3 = new BasicNameValuePair("param", "this,that");
-        NameValuePair param4 = new BasicNameValuePair("param", null);
-        HeaderElement element1 = new BasicHeaderElement("name1", "value1", new NameValuePair[] {param1});
-        HeaderElement element2 = new BasicHeaderElement("name2", "value2", new NameValuePair[] {param2});
-        HeaderElement element3 = new BasicHeaderElement("name3", "value3", new NameValuePair[] {param3});
-        HeaderElement element4 = new BasicHeaderElement("name4", "value4", new NameValuePair[] {param4});
-        HeaderElement element5 = new BasicHeaderElement("name5", null);
-        HeaderElement[] elements = new HeaderElement[] {element1, element2, element3, element4, element5};
+        final NameValuePair param1 = new BasicNameValuePair("param", "regular_stuff");
+        final NameValuePair param2 = new BasicNameValuePair("param", "this\\that");
+        final NameValuePair param3 = new BasicNameValuePair("param", "this,that");
+        final NameValuePair param4 = new BasicNameValuePair("param", null);
+        final HeaderElement element1 = new BasicHeaderElement("name1", "value1", new NameValuePair[] {param1});
+        final HeaderElement element2 = new BasicHeaderElement("name2", "value2", new NameValuePair[] {param2});
+        final HeaderElement element3 = new BasicHeaderElement("name3", "value3", new NameValuePair[] {param3});
+        final HeaderElement element4 = new BasicHeaderElement("name4", "value4", new NameValuePair[] {param4});
+        final HeaderElement element5 = new BasicHeaderElement("name5", null);
+        final HeaderElement[] elements = new HeaderElement[] {element1, element2, element3, element4, element5};
 
         Assert.assertEquals
             ("name1=value1; param=regular_stuff, name2=value2; " +
@@ -151,18 +148,18 @@ public class TestBasicHeaderValueFormatter {
         try {
             BasicHeaderValueFormatter.formatHeaderElement
                 ((HeaderElement) null, false,
-                 BasicHeaderValueFormatter.DEFAULT);
+                 BasicHeaderValueFormatter.INSTANCE);
             Assert.fail("IllegalArgumentException should habe been thrown");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
             // expected
         }
 
         try {
             BasicHeaderValueFormatter.formatElements
                 ((HeaderElement[]) null, false,
-                 BasicHeaderValueFormatter.DEFAULT);
+                 BasicHeaderValueFormatter.INSTANCE);
             Assert.fail("IllegalArgumentException should habe been thrown");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
             // expected
         }
     }
@@ -175,16 +172,16 @@ public class TestBasicHeaderValueFormatter {
             BasicHeaderValueFormatter.formatNameValuePair
                 ((NameValuePair) null, true, null);
             Assert.fail("IllegalArgumentException should habe been thrown");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
             // expected
         }
 
         try {
             BasicHeaderValueFormatter.formatParameters
                 ((NameValuePair[]) null, true,
-                 BasicHeaderValueFormatter.DEFAULT);
+                 BasicHeaderValueFormatter.INSTANCE);
             Assert.fail("IllegalArgumentException should habe been thrown");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
             // expected
         }
     }
diff --git a/httpcore/src/test/java/org/apache/http/message/TestBasicHeaderValueParser.java b/httpcore/src/test/java/org/apache/http/message/TestBasicHeaderValueParser.java
index 75f2322..6575d94 100644
--- a/httpcore/src/test/java/org/apache/http/message/TestBasicHeaderValueParser.java
+++ b/httpcore/src/test/java/org/apache/http/message/TestBasicHeaderValueParser.java
@@ -23,10 +23,7 @@
  * information on the Apache Software Foundation, please see
  * <http://www.apache.org/>.
  *
- * [Additional notices, if required by prior licensing conditions]
- *
  */
-
 package org.apache.http.message;
 
 import org.apache.http.HeaderElement;
@@ -38,15 +35,15 @@ import org.junit.Test;
 /**
  * Tests for header value parsing.
  *
- * @version $Id: TestBasicHeaderValueParser.java 1100965 2011-05-09 11:26:57Z olegk $
+ * @version $Id: TestBasicHeaderValueParser.java 1433815 2013-01-16 03:27:44Z ggregory $
  */
 public class TestBasicHeaderValueParser {
 
     @Test
     public void testParseHeaderElements() throws Exception {
-        String headerValue = "name1 = value1; name2; name3=\"value3\" , name4=value4; " +
+        final String headerValue = "name1 = value1; name2; name3=\"value3\" , name4=value4; " +
             "name5=value5, name6= ; name7 = value7; name8 = \" value8\"";
-        HeaderElement[] elements = BasicHeaderValueParser.parseElements(headerValue, null);
+        final HeaderElement[] elements = BasicHeaderValueParser.parseElements(headerValue, null);
         // there are 3 elements
         Assert.assertEquals(3,elements.length);
         // 1st element
@@ -78,9 +75,9 @@ public class TestBasicHeaderValueParser {
 
     @Test
     public void testParseHEEscaped() {
-        String s =
+        final String s =
           "test1 =  \"\\\"stuff\\\"\", test2= \"\\\\\", test3 = \"stuff, stuff\"";
-        HeaderElement[] elements = BasicHeaderValueParser.parseElements(s, null);
+        final HeaderElement[] elements = BasicHeaderValueParser.parseElements(s, null);
         Assert.assertEquals(3, elements.length);
         Assert.assertEquals("test1", elements[0].getName());
         Assert.assertEquals("\\\"stuff\\\"", elements[0].getValue());
@@ -92,29 +89,29 @@ public class TestBasicHeaderValueParser {
 
     @Test
     public void testHEFringeCase1() throws Exception {
-        String headerValue = "name1 = value1,";
-        HeaderElement[] elements = BasicHeaderValueParser.parseElements(headerValue, null);
+        final String headerValue = "name1 = value1,";
+        final HeaderElement[] elements = BasicHeaderValueParser.parseElements(headerValue, null);
         Assert.assertEquals("Number of elements", 1, elements.length);
     }
 
     @Test
     public void testHEFringeCase2() throws Exception {
-        String headerValue = "name1 = value1, ";
-        HeaderElement[] elements = BasicHeaderValueParser.parseElements(headerValue, null);
+        final String headerValue = "name1 = value1, ";
+        final HeaderElement[] elements = BasicHeaderValueParser.parseElements(headerValue, null);
         Assert.assertEquals("Number of elements", 1, elements.length);
     }
 
     @Test
     public void testHEFringeCase3() throws Exception {
-        String headerValue = ",, ,, ,";
-        HeaderElement[] elements = BasicHeaderValueParser.parseElements(headerValue, null);
+        final String headerValue = ",, ,, ,";
+        final HeaderElement[] elements = BasicHeaderValueParser.parseElements(headerValue, null);
         Assert.assertEquals("Number of elements", 0, elements.length);
     }
 
     @Test
     public void testNVParseUsingCursor() {
 
-        HeaderValueParser parser = BasicHeaderValueParser.DEFAULT;
+        final HeaderValueParser parser = BasicHeaderValueParser.INSTANCE;
 
         String s = "test";
         CharArrayBuffer buffer = new CharArrayBuffer(16);
@@ -274,7 +271,7 @@ public class TestBasicHeaderValueParser {
 
     @Test
     public void testNVParseAllWithCursor() {
-        HeaderValueParser parser = BasicHeaderValueParser.DEFAULT;
+        final HeaderValueParser parser = BasicHeaderValueParser.INSTANCE;
 
         String s =
             "test; test1 =  stuff   ; test2 =  \"stuff; stuff\"; test3=\"stuff";
@@ -342,9 +339,9 @@ public class TestBasicHeaderValueParser {
 
     @Test
     public void testNVParseEscaped() {
-        String s =
+        final String s =
           "test1 =  \"\\\"stuff\\\"\"; test2= \"\\\\\"; test3 = \"stuff; stuff\"";
-        NameValuePair[] params =
+        final NameValuePair[] params =
             BasicHeaderValueParser.parseParameters(s, null);
         Assert.assertEquals(3, params.length);
         Assert.assertEquals("test1", params[0].getName());
diff --git a/httpcore/src/test/java/org/apache/http/message/TestBasicHttpResponse.java b/httpcore/src/test/java/org/apache/http/message/TestBasicHttpResponse.java
new file mode 100644
index 0000000..d94db0f
--- /dev/null
+++ b/httpcore/src/test/java/org/apache/http/message/TestBasicHttpResponse.java
@@ -0,0 +1,101 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+
+package org.apache.http.message;
+
+import org.apache.http.HttpVersion;
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * Unit tests for {@link BasicHttpResponse}.
+ */
+public class TestBasicHttpResponse {
+
+    @Test
+    public void testBasics() {
+        final BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
+        Assert.assertEquals(HttpVersion.HTTP_1_1, response.getProtocolVersion());
+        Assert.assertEquals(HttpVersion.HTTP_1_1, response.getStatusLine().getProtocolVersion());
+        Assert.assertEquals(200, response.getStatusLine().getStatusCode());
+        Assert.assertEquals("OK", response.getStatusLine().getReasonPhrase());
+    }
+
+    @Test
+    public void testStatusLineMutation() {
+        final BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
+        Assert.assertEquals(HttpVersion.HTTP_1_1, response.getStatusLine().getProtocolVersion());
+        Assert.assertEquals(200, response.getStatusLine().getStatusCode());
+        Assert.assertEquals("OK", response.getStatusLine().getReasonPhrase());
+        response.setReasonPhrase("Kind of OK");
+        Assert.assertEquals(HttpVersion.HTTP_1_1, response.getStatusLine().getProtocolVersion());
+        Assert.assertEquals(200, response.getStatusLine().getStatusCode());
+        Assert.assertEquals("Kind of OK", response.getStatusLine().getReasonPhrase());
+        response.setStatusCode(299);
+        Assert.assertEquals(HttpVersion.HTTP_1_1, response.getStatusLine().getProtocolVersion());
+        Assert.assertEquals(299, response.getStatusLine().getStatusCode());
+        Assert.assertEquals("Kind of OK", response.getStatusLine().getReasonPhrase());
+        response.setStatusLine(HttpVersion.HTTP_1_0, 298);
+        Assert.assertEquals(HttpVersion.HTTP_1_0, response.getStatusLine().getProtocolVersion());
+        Assert.assertEquals(298, response.getStatusLine().getStatusCode());
+        Assert.assertEquals(null, response.getStatusLine().getReasonPhrase());
+        response.setStatusLine(HttpVersion.HTTP_1_1, 200, "OK");
+        Assert.assertEquals(HttpVersion.HTTP_1_1, response.getStatusLine().getProtocolVersion());
+        Assert.assertEquals(200, response.getStatusLine().getStatusCode());
+        Assert.assertEquals("OK", response.getStatusLine().getReasonPhrase());
+        response.setStatusLine(new BasicStatusLine(HttpVersion.HTTP_1_0, 500, "Boom"));
+        Assert.assertEquals(HttpVersion.HTTP_1_0, response.getStatusLine().getProtocolVersion());
+        Assert.assertEquals(500, response.getStatusLine().getStatusCode());
+        Assert.assertEquals("Boom", response.getStatusLine().getReasonPhrase());
+    }
+
+    @Test
+    public void testInvalidStatusCode() {
+        try {
+            new BasicHttpResponse(HttpVersion.HTTP_1_1, -200, "OK");
+            Assert.fail("IllegalArgumentException expected");
+        } catch (final IllegalArgumentException expected) {
+        }
+        final BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
+        try {
+            response.setStatusCode(-1);
+            Assert.fail("IllegalArgumentException expected");
+        } catch (final IllegalArgumentException expected) {
+        }
+        try {
+            response.setStatusLine(HttpVersion.HTTP_1_1, -1);
+            Assert.fail("IllegalArgumentException expected");
+        } catch (final IllegalArgumentException expected) {
+        }
+        try {
+            response.setStatusLine(HttpVersion.HTTP_1_1, -1, "not ok");
+            Assert.fail("IllegalArgumentException expected");
+        } catch (final IllegalArgumentException expected) {
+        }
+    }
+
+}
diff --git a/httpcore/src/test/java/org/apache/http/message/TestBasicLineFormatter.java b/httpcore/src/test/java/org/apache/http/message/TestBasicLineFormatter.java
index c6ee960..942225d 100644
--- a/httpcore/src/test/java/org/apache/http/message/TestBasicLineFormatter.java
+++ b/httpcore/src/test/java/org/apache/http/message/TestBasicLineFormatter.java
@@ -43,7 +43,7 @@ public class TestBasicLineFormatter {
 
     @Test
     public void testHttpVersionFormatting() throws Exception {
-        String s = BasicLineFormatter.formatProtocolVersion
+        final String s = BasicLineFormatter.formatProtocolVersion
             (HttpVersion.HTTP_1_1, null);
         Assert.assertEquals("HTTP/1.1", s);
     }
@@ -52,16 +52,16 @@ public class TestBasicLineFormatter {
     public void testHttpVersionFormattingInvalidInput() throws Exception {
         try {
             BasicLineFormatter.formatProtocolVersion
-                (null, BasicLineFormatter.DEFAULT);
+                (null, BasicLineFormatter.INSTANCE);
             Assert.fail("IllegalArgumentException should habe been thrown");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
             // expected
         }
         try {
-            BasicLineFormatter.DEFAULT.appendProtocolVersion
+            BasicLineFormatter.INSTANCE.appendProtocolVersion
                 (new CharArrayBuffer(10), (HttpVersion) null);
             Assert.fail("IllegalArgumentException should habe been thrown");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
             // expected
         }
     }
@@ -69,8 +69,8 @@ public class TestBasicLineFormatter {
 
     @Test
     public void testRLFormatting() throws Exception {
-        RequestLine requestline = new BasicRequestLine("GET", "/stuff", HttpVersion.HTTP_1_1);
-        String s = BasicLineFormatter.formatRequestLine(requestline, null);
+        final RequestLine requestline = new BasicRequestLine("GET", "/stuff", HttpVersion.HTTP_1_1);
+        final String s = BasicLineFormatter.formatRequestLine(requestline, null);
         Assert.assertEquals("GET /stuff HTTP/1.1", s);
     }
 
@@ -78,16 +78,16 @@ public class TestBasicLineFormatter {
     public void testRLFormattingInvalidInput() throws Exception {
         try {
             BasicLineFormatter.formatRequestLine
-                (null, BasicLineFormatter.DEFAULT);
+                (null, BasicLineFormatter.INSTANCE);
             Assert.fail("IllegalArgumentException should habe been thrown");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
             // expected
         }
         try {
-            BasicLineFormatter.DEFAULT.formatRequestLine
+            BasicLineFormatter.INSTANCE.formatRequestLine
                 (new CharArrayBuffer(10), (RequestLine) null);
             Assert.fail("IllegalArgumentException should habe been thrown");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
             // expected
         }
     }
@@ -110,16 +110,16 @@ public class TestBasicLineFormatter {
     public void testSLFormattingInvalidInput() throws Exception {
         try {
             BasicLineFormatter.formatStatusLine
-                (null, BasicLineFormatter.DEFAULT);
+                (null, BasicLineFormatter.INSTANCE);
             Assert.fail("IllegalArgumentException should habe been thrown");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
             // expected
         }
         try {
-            BasicLineFormatter.DEFAULT.formatStatusLine
+            BasicLineFormatter.INSTANCE.formatStatusLine
                 (new CharArrayBuffer(10), (StatusLine) null);
             Assert.fail("IllegalArgumentException should habe been thrown");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
             // expected
         }
     }
@@ -127,10 +127,10 @@ public class TestBasicLineFormatter {
 
     @Test
     public void testHeaderFormatting() throws Exception {
-        Header header1 = new BasicHeader("name", "value");
+        final Header header1 = new BasicHeader("name", "value");
         String s = BasicLineFormatter.formatHeader(header1, null);
         Assert.assertEquals("name: value", s);
-        Header header2 = new BasicHeader("name", null);
+        final Header header2 = new BasicHeader("name", null);
         s = BasicLineFormatter.formatHeader(header2, null);
         Assert.assertEquals("name: ", s);
     }
@@ -139,16 +139,16 @@ public class TestBasicLineFormatter {
     public void testHeaderFormattingInvalidInput() throws Exception {
         try {
             BasicLineFormatter.formatHeader
-                (null, BasicLineFormatter.DEFAULT);
+                (null, BasicLineFormatter.INSTANCE);
             Assert.fail("IllegalArgumentException should habe been thrown");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
             // expected
         }
         try {
-            BasicLineFormatter.DEFAULT.formatHeader
+            BasicLineFormatter.INSTANCE.formatHeader
                 (new CharArrayBuffer(10), (Header) null);
             Assert.fail("IllegalArgumentException should habe been thrown");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
             // expected
         }
     }
diff --git a/httpcore/src/test/java/org/apache/http/message/TestBasicLineParser.java b/httpcore/src/test/java/org/apache/http/message/TestBasicLineParser.java
index 91cb820..2d9377e 100644
--- a/httpcore/src/test/java/org/apache/http/message/TestBasicLineParser.java
+++ b/httpcore/src/test/java/org/apache/http/message/TestBasicLineParser.java
@@ -72,35 +72,35 @@ public class TestBasicLineParser {
         try {
             BasicLineParser.parseRequestLine("    ", null);
             Assert.fail();
-        } catch (ParseException e) {
+        } catch (final ParseException e) {
             // expected
         }
 
         try {
             BasicLineParser.parseRequestLine("  GET", null);
             Assert.fail();
-        } catch (ParseException e) {
+        } catch (final ParseException e) {
             // expected
         }
 
         try {
             BasicLineParser.parseRequestLine("GET /stuff", null);
             Assert.fail();
-        } catch (ParseException e) {
+        } catch (final ParseException e) {
             // expected
         }
 
         try {
             BasicLineParser.parseRequestLine("GET/stuff HTTP/1.1", null);
             Assert.fail();
-        } catch (ParseException e) {
+        } catch (final ParseException e) {
             // expected
         }
 
         try {
             BasicLineParser.parseRequestLine("GET /stuff HTTP/1.1 Oooooooooooppsie", null);
             Assert.fail();
-        } catch (ParseException e) {
+        } catch (final ParseException e) {
             // expected
         }
     }
@@ -169,35 +169,35 @@ public class TestBasicLineParser {
         try {
             BasicLineParser.parseStatusLine("xxx 200 OK", null);
             Assert.fail();
-        } catch (ParseException e) {
+        } catch (final ParseException e) {
             // expected
         }
 
         try {
             BasicLineParser.parseStatusLine("HTTP/1.1 xxx OK", null);
             Assert.fail();
-        } catch (ParseException e) {
+        } catch (final ParseException e) {
             // expected
         }
 
         try {
             BasicLineParser.parseStatusLine("HTTP/1.1    ", null);
             Assert.fail();
-        } catch (ParseException e) {
+        } catch (final ParseException e) {
             // expected
         }
 
         try {
             BasicLineParser.parseStatusLine("HTTP/1.1", null);
             Assert.fail();
-        } catch (ParseException e) {
+        } catch (final ParseException e) {
             // expected
         }
 
         try {
             BasicLineParser.parseStatusLine("HTTP/1.1 -200 OK", null);
             Assert.fail();
-        } catch (ParseException e) {
+        } catch (final ParseException e) {
             // expected
         }
     }
@@ -230,7 +230,7 @@ public class TestBasicLineParser {
         buffer.append(s);
         ParserCursor cursor = new ParserCursor(0, s.length());
 
-        LineParser parser = BasicLineParser.DEFAULT;
+        final LineParser parser = BasicLineParser.INSTANCE;
 
         HttpVersion version = (HttpVersion) parser.parseProtocolVersion(buffer, cursor);
         Assert.assertEquals("HTTP protocol name", "HTTP", version.getProtocol());
@@ -260,70 +260,70 @@ public class TestBasicLineParser {
         try {
             BasicLineParser.parseProtocolVersion((String)null, null);
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException e) {
+        } catch (final IllegalArgumentException e) {
             //expected
         }
         try {
             BasicLineParser.parseProtocolVersion
                 ("    ", null);
             Assert.fail("ParseException should have been thrown");
-        } catch (ParseException e) {
+        } catch (final ParseException e) {
             //expected
         }
         try {
             BasicLineParser.parseProtocolVersion
                 ("HTT", null);
             Assert.fail("ParseException should have been thrown");
-        } catch (ParseException e) {
+        } catch (final ParseException e) {
             //expected
         }
         try {
             BasicLineParser.parseProtocolVersion
                 ("crap", null);
             Assert.fail("ParseException should have been thrown");
-        } catch (ParseException e) {
+        } catch (final ParseException e) {
             //expected
         }
         try {
             BasicLineParser.parseProtocolVersion
                 ("HTTP/crap", null);
             Assert.fail("ParseException should have been thrown");
-        } catch (ParseException e) {
+        } catch (final ParseException e) {
             //expected
         }
         try {
             BasicLineParser.parseProtocolVersion
                 ("HTTP/1", null);
             Assert.fail("ParseException should have been thrown");
-        } catch (ParseException e) {
+        } catch (final ParseException e) {
             //expected
         }
         try {
             BasicLineParser.parseProtocolVersion
                 ("HTTP/1234   ", null);
             Assert.fail("ParseException should have been thrown");
-        } catch (ParseException e) {
+        } catch (final ParseException e) {
             //expected
         }
         try {
             BasicLineParser.parseProtocolVersion
                 ("HTTP/1.", null);
             Assert.fail("ParseException should have been thrown");
-        } catch (ParseException e) {
+        } catch (final ParseException e) {
             //expected
         }
         try {
             BasicLineParser.parseProtocolVersion
                 ("HTTP/whatever.whatever whatever", null);
             Assert.fail("ParseException should have been thrown");
-        } catch (ParseException e) {
+        } catch (final ParseException e) {
             //expected
         }
         try {
             BasicLineParser.parseProtocolVersion
                 ("HTTP/1.whatever whatever", null);
             Assert.fail("ParseException should have been thrown");
-        } catch (ParseException e) {
+        } catch (final ParseException e) {
             //expected
         }
     }
diff --git a/httpcore/src/test/java/org/apache/http/message/TestBasicMessages.java b/httpcore/src/test/java/org/apache/http/message/TestBasicMessages.java
index e551307..84240ea 100644
--- a/httpcore/src/test/java/org/apache/http/message/TestBasicMessages.java
+++ b/httpcore/src/test/java/org/apache/http/message/TestBasicMessages.java
@@ -27,19 +27,17 @@
 
 package org.apache.http.message;
 
-import org.apache.http.Header;
 import org.apache.http.HttpEntity;
 import org.apache.http.HttpRequest;
 import org.apache.http.HttpResponse;
 import org.apache.http.HttpStatus;
 import org.apache.http.HttpVersion;
 import org.apache.http.entity.BasicHttpEntity;
-import org.apache.http.params.CoreProtocolPNames;
 import org.junit.Assert;
 import org.junit.Test;
 
 /**
- * Unit tests for {@link Header}.
+ * Unit tests for {@link org.apache.http.HttpMessage}.
  *
  */
 public class TestBasicMessages {
@@ -82,31 +80,24 @@ public class TestBasicMessages {
         try {
             response.setStatusCode(-23);
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
-            // expected
-        }
-        response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK");
-        try {
-            response.setStatusLine(null, 200);
-            Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
             // expected
         }
         response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK");
         try {
             response.setStatusLine(null);
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
             // expected
         }
     }
 
     @Test
     public void testSetResponseEntity() {
-        HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK");
+        final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK");
         Assert.assertNull(response.getEntity());
 
-        HttpEntity entity = new BasicHttpEntity();
+        final HttpEntity entity = new BasicHttpEntity();
         response.setEntity(entity);
         Assert.assertTrue(entity == response.getEntity());
     }
@@ -126,19 +117,19 @@ public class TestBasicMessages {
         try {
             new BasicHttpRequest(null, null);
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
             // expected
         }
         try {
             new BasicHttpRequest("GET", null);
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
             // expected
         }
         try {
             new BasicHttpRequest(null);
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
             // expected
         }
     }
@@ -158,19 +149,17 @@ public class TestBasicMessages {
 
     @Test
     public void testSetRequestEntity() {
-        BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("GET", "/");
+        final BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("GET", "/");
         Assert.assertNull(request.getEntity());
 
-        HttpEntity entity = new BasicHttpEntity();
+        final HttpEntity entity = new BasicHttpEntity();
         request.setEntity(entity);
         Assert.assertTrue(entity == request.getEntity());
     }
 
     @Test
     public void testExpectContinue() {
-        BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("GET", "/");
-        Assert.assertFalse(request.expectContinue());
-        request.getParams().setBooleanParameter(CoreProtocolPNames.USE_EXPECT_CONTINUE, true);
+        final BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("GET", "/");
         Assert.assertFalse(request.expectContinue());
         request.addHeader("Expect", "100-Continue");
         Assert.assertTrue(request.expectContinue());
diff --git a/httpcore/src/test/java/org/apache/http/message/TestBasicTokenIterator.java b/httpcore/src/test/java/org/apache/http/message/TestBasicTokenIterator.java
index ceed291..dbe0b08 100644
--- a/httpcore/src/test/java/org/apache/http/message/TestBasicTokenIterator.java
+++ b/httpcore/src/test/java/org/apache/http/message/TestBasicTokenIterator.java
@@ -76,7 +76,7 @@ public class TestBasicTokenIterator {
 
     @Test
     public void testMultiHeader() {
-        Header[] headers = new Header[]{
+        final Header[] headers = new Header[]{
             new BasicHeader("Name", "token0,token1"),
             new BasicHeader("Name", ""),
             new BasicHeader("Name", "token2"),
@@ -85,8 +85,8 @@ public class TestBasicTokenIterator {
             new BasicHeader("Name", ","),
             new BasicHeader("Name", "token4"),
         };
-        HeaderIterator hit = new BasicHeaderIterator(headers, null);
-        TokenIterator  ti  = new BasicTokenIterator(hit);
+        final HeaderIterator hit = new BasicHeaderIterator(headers, null);
+        final TokenIterator  ti  = new BasicTokenIterator(hit);
 
         Assert.assertTrue(ti.hasNext());
         Assert.assertEquals("token0", "token0", ti.nextToken());
@@ -104,7 +104,7 @@ public class TestBasicTokenIterator {
 
     @Test
     public void testEmpty() {
-        Header[] headers = new Header[]{
+        final Header[] headers = new Header[]{
             new BasicHeader("Name", " "),
             new BasicHeader("Name", ""),
             new BasicHeader("Name", ","),
@@ -125,7 +125,7 @@ public class TestBasicTokenIterator {
 
     @Test
     public void testValueStart() {
-        Header[] headers = new Header[]{
+        final Header[] headers = new Header[]{
             new BasicHeader("Name", "token0"),
             new BasicHeader("Name", " token1"),
             new BasicHeader("Name", ",token2"),
@@ -133,8 +133,8 @@ public class TestBasicTokenIterator {
             new BasicHeader("Name", ", token4"),
             new BasicHeader("Name", " , token5"),
         };
-        HeaderIterator hit = new BasicHeaderIterator(headers, null);
-        TokenIterator  ti  = new BasicTokenIterator(hit);
+        final HeaderIterator hit = new BasicHeaderIterator(headers, null);
+        final TokenIterator  ti  = new BasicTokenIterator(hit);
 
         Assert.assertTrue(ti.hasNext());
         Assert.assertEquals("token0", "token0", ti.nextToken());
@@ -154,7 +154,7 @@ public class TestBasicTokenIterator {
 
     @Test
     public void testValueEnd() {
-        Header[] headers = new Header[]{
+        final Header[] headers = new Header[]{
             new BasicHeader("Name", "token0"),
             new BasicHeader("Name", "token1 "),
             new BasicHeader("Name", "token2,"),
@@ -162,8 +162,8 @@ public class TestBasicTokenIterator {
             new BasicHeader("Name", "token4, "),
             new BasicHeader("Name", "token5 , "),
         };
-        HeaderIterator hit = new BasicHeaderIterator(headers, null);
-        TokenIterator  ti  = new BasicTokenIterator(hit);
+        final HeaderIterator hit = new BasicHeaderIterator(headers, null);
+        final TokenIterator  ti  = new BasicTokenIterator(hit);
 
         Assert.assertTrue(ti.hasNext());
         Assert.assertEquals("token0", "token0", ti.nextToken());
@@ -183,11 +183,11 @@ public class TestBasicTokenIterator {
 
     @Test
     public void testTokenChar() {
-        Header[] headers = new Header[]{
+        final Header[] headers = new Header[]{
             new BasicHeader("Name", "token0")
         };
-        HeaderIterator     hit = new BasicHeaderIterator(headers, null);
-        BasicTokenIterator bti = new BasicTokenIterator(hit);
+        final HeaderIterator     hit = new BasicHeaderIterator(headers, null);
+        final BasicTokenIterator bti = new BasicTokenIterator(hit);
 
         Assert.assertTrue ("letter"   , bti.isTokenChar('j'));
         Assert.assertFalse("control"  , bti.isTokenChar('\b'));
@@ -198,7 +198,7 @@ public class TestBasicTokenIterator {
 
     @Test
     public void testInvalid() {
-        Header[] headers = new Header[]{
+        final Header[] headers = new Header[]{
             new BasicHeader("in", "token0=token1"),
             new BasicHeader("no", "token0 token1"),
             new BasicHeader("pre", "<token0,token1"),
@@ -212,7 +212,7 @@ public class TestBasicTokenIterator {
         try {
             ti.nextToken();
             Assert.fail("invalid infix character not detected");
-        } catch (ParseException px) {
+        } catch (final ParseException px) {
             // expected
         }
 
@@ -224,7 +224,7 @@ public class TestBasicTokenIterator {
         try {
             ti.nextToken();
             Assert.fail("missing token separator not detected");
-        } catch (ParseException px) {
+        } catch (final ParseException px) {
             // expected
         }
 
@@ -234,7 +234,7 @@ public class TestBasicTokenIterator {
         try {
             new BasicTokenIterator(hit);
             Assert.fail("invalid prefix character not detected");
-        } catch (ParseException px) {
+        } catch (final ParseException px) {
             // expected
         }
 
@@ -249,7 +249,7 @@ public class TestBasicTokenIterator {
         try {
             ti.nextToken();
             Assert.fail("invalid postfix character not detected");
-        } catch (ParseException px) {
+        } catch (final ParseException px) {
             // expected
         }
     }
@@ -261,31 +261,31 @@ public class TestBasicTokenIterator {
         try {
             new BasicTokenIterator(null);
             Assert.fail("null argument not detected");
-        } catch (IllegalArgumentException iax) {
+        } catch (final IllegalArgumentException iax) {
             // expected
         }
 
-        Header[] headers = new Header[]{
+        final Header[] headers = new Header[]{
             new BasicHeader("Name", " "),
             new BasicHeader("Name", ""),
             new BasicHeader("Name", ","),
             new BasicHeader("Name", " ,, "),
         };
-        HeaderIterator hit = new BasicHeaderIterator(headers, null);
-        TokenIterator  ti  = new BasicTokenIterator(hit);
+        final HeaderIterator hit = new BasicHeaderIterator(headers, null);
+        final TokenIterator  ti  = new BasicTokenIterator(hit);
 
         try {
             // call next() instead of nextToken() to get that covered, too
             ti.next();
             Assert.fail("next after end not detected");
-        } catch (NoSuchElementException nsx) {
+        } catch (final NoSuchElementException nsx) {
             // expected
         }
 
         try {
             ti.remove();
             Assert.fail("unsupported remove not detected");
-        } catch (UnsupportedOperationException uox) {
+        } catch (final UnsupportedOperationException uox) {
             // expected
         }
     }
@@ -294,30 +294,30 @@ public class TestBasicTokenIterator {
     @Test
     public void testWrongProtected() {
 
-        Header[] headers = new Header[]{
+        final Header[] headers = new Header[]{
             new BasicHeader("Name", "token1,token2")
         };
-        HeaderIterator     hit = new BasicHeaderIterator(headers, null);
-        BasicTokenIterator bti = new BasicTokenIterator(hit);
+        final HeaderIterator     hit = new BasicHeaderIterator(headers, null);
+        final BasicTokenIterator bti = new BasicTokenIterator(hit);
 
         try {
             bti.findTokenStart(-1);
             Assert.fail("tokenStart: negative index not detected");
-        } catch (IllegalArgumentException iax) {
+        } catch (final IllegalArgumentException iax) {
             // expected
         }
 
         try {
             bti.findTokenSeparator(-1);
             Assert.fail("tokenSeparator: negative index not detected");
-        } catch (IllegalArgumentException iax) {
+        } catch (final IllegalArgumentException iax) {
             // expected
         }
 
         try {
             bti.findTokenEnd(-1);
             Assert.fail("tokenEnd: negative index not detected");
-        } catch (IllegalArgumentException iax) {
+        } catch (final IllegalArgumentException iax) {
             // expected
         }
     }
diff --git a/httpcore/src/test/java/org/apache/http/message/TestBufferedHeader.java b/httpcore/src/test/java/org/apache/http/message/TestBufferedHeader.java
index 7e8c445..ae26655 100644
--- a/httpcore/src/test/java/org/apache/http/message/TestBufferedHeader.java
+++ b/httpcore/src/test/java/org/apache/http/message/TestBufferedHeader.java
@@ -45,9 +45,9 @@ public class TestBufferedHeader {
 
     @Test
     public void testBasicConstructor() {
-        CharArrayBuffer buf = new CharArrayBuffer(32);
+        final CharArrayBuffer buf = new CharArrayBuffer(32);
         buf.append("name: value");
-        BufferedHeader header = new BufferedHeader(buf);
+        final BufferedHeader header = new BufferedHeader(buf);
         Assert.assertEquals("name", header.getName());
         Assert.assertEquals("value", header.getValue());
         Assert.assertSame(buf, header.getBuffer());
@@ -59,17 +59,17 @@ public class TestBufferedHeader {
         try {
             new BufferedHeader(null);
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
             //expected
         }
     }
 
     @Test
     public void testHeaderElements() {
-        CharArrayBuffer buf = new CharArrayBuffer(32);
+        final CharArrayBuffer buf = new CharArrayBuffer(32);
         buf.append("name: element1 = value1, element2; param1 = value1, element3");
-        BufferedHeader header = new BufferedHeader(buf);
-        HeaderElement[] elements = header.getElements();
+        final BufferedHeader header = new BufferedHeader(buf);
+        final HeaderElement[] elements = header.getElements();
         Assert.assertNotNull(elements);
         Assert.assertEquals(3, elements.length);
         Assert.assertEquals("element1", elements[0].getName());
@@ -83,27 +83,27 @@ public class TestBufferedHeader {
 
     @Test
     public void testCloning() throws Exception {
-        CharArrayBuffer buf = new CharArrayBuffer(32);
+        final CharArrayBuffer buf = new CharArrayBuffer(32);
         buf.append("name: value");
-        BufferedHeader orig = new BufferedHeader(buf);
-        BufferedHeader clone = (BufferedHeader) orig.clone();
+        final BufferedHeader orig = new BufferedHeader(buf);
+        final BufferedHeader clone = (BufferedHeader) orig.clone();
         Assert.assertEquals(orig.getName(), clone.getName());
         Assert.assertEquals(orig.getValue(), clone.getValue());
     }
 
     @Test
     public void testSerialization() throws Exception {
-        CharArrayBuffer buf = new CharArrayBuffer(32);
+        final CharArrayBuffer buf = new CharArrayBuffer(32);
         buf.append("name: value");
-        BufferedHeader orig = new BufferedHeader(buf);
-        ByteArrayOutputStream outbuffer = new ByteArrayOutputStream();
-        ObjectOutputStream outstream = new ObjectOutputStream(outbuffer);
+        final BufferedHeader orig = new BufferedHeader(buf);
+        final ByteArrayOutputStream outbuffer = new ByteArrayOutputStream();
+        final ObjectOutputStream outstream = new ObjectOutputStream(outbuffer);
         outstream.writeObject(orig);
         outstream.close();
-        byte[] raw = outbuffer.toByteArray();
-        ByteArrayInputStream inbuffer = new ByteArrayInputStream(raw);
-        ObjectInputStream instream = new ObjectInputStream(inbuffer);
-        BufferedHeader clone = (BufferedHeader) instream.readObject();
+        final byte[] raw = outbuffer.toByteArray();
+        final ByteArrayInputStream inbuffer = new ByteArrayInputStream(raw);
+        final ObjectInputStream instream = new ObjectInputStream(inbuffer);
+        final BufferedHeader clone = (BufferedHeader) instream.readObject();
         Assert.assertEquals(orig.getName(), clone.getName());
         Assert.assertEquals(orig.getValue(), clone.getValue());
     }
diff --git a/httpcore/src/test/java/org/apache/http/message/TestHeader.java b/httpcore/src/test/java/org/apache/http/message/TestHeader.java
index 900dc2c..57bf7ea 100644
--- a/httpcore/src/test/java/org/apache/http/message/TestHeader.java
+++ b/httpcore/src/test/java/org/apache/http/message/TestHeader.java
@@ -44,14 +44,14 @@ public class TestHeader {
 
     @Test
     public void testBasicConstructor() {
-        Header header = new BasicHeader("name", "value");
+        final Header header = new BasicHeader("name", "value");
         Assert.assertEquals("name", header.getName());
         Assert.assertEquals("value", header.getValue());
     }
 
     @Test
     public void testBasicConstructorNullValue() {
-        Header header = new BasicHeader("name", null);
+        final Header header = new BasicHeader("name", null);
         Assert.assertEquals("name", header.getName());
         Assert.assertEquals(null, header.getValue());
     }
@@ -61,16 +61,16 @@ public class TestHeader {
         try {
             new BasicHeader(null, null);
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
             //expected
         }
     }
 
     @Test
     public void testToString() {
-        Header header1 = new BasicHeader("name1", "value1");
+        final Header header1 = new BasicHeader("name1", "value1");
         Assert.assertEquals("name1: value1", header1.toString());
-        Header header2 = new BasicHeader("name2", null);
+        final Header header2 = new BasicHeader("name2", null);
         Assert.assertEquals("name2: ", header2.toString());
     }
 
@@ -96,23 +96,23 @@ public class TestHeader {
 
     @Test
     public void testCloning() throws Exception {
-        BasicHeader orig = new BasicHeader("name1", "value1");
-        BasicHeader clone = (BasicHeader) orig.clone();
+        final BasicHeader orig = new BasicHeader("name1", "value1");
+        final BasicHeader clone = (BasicHeader) orig.clone();
         Assert.assertEquals(orig.getName(), clone.getName());
         Assert.assertEquals(orig.getValue(), clone.getValue());
     }
 
     @Test
     public void testSerialization() throws Exception {
-        BasicHeader orig = new BasicHeader("name1", "value1");
-        ByteArrayOutputStream outbuffer = new ByteArrayOutputStream();
-        ObjectOutputStream outstream = new ObjectOutputStream(outbuffer);
+        final BasicHeader orig = new BasicHeader("name1", "value1");
+        final ByteArrayOutputStream outbuffer = new ByteArrayOutputStream();
+        final ObjectOutputStream outstream = new ObjectOutputStream(outbuffer);
         outstream.writeObject(orig);
         outstream.close();
-        byte[] raw = outbuffer.toByteArray();
-        ByteArrayInputStream inbuffer = new ByteArrayInputStream(raw);
-        ObjectInputStream instream = new ObjectInputStream(inbuffer);
-        BasicHeader clone = (BasicHeader) instream.readObject();
+        final byte[] raw = outbuffer.toByteArray();
+        final ByteArrayInputStream inbuffer = new ByteArrayInputStream(raw);
+        final ObjectInputStream instream = new ObjectInputStream(inbuffer);
+        final BasicHeader clone = (BasicHeader) instream.readObject();
         Assert.assertEquals(orig.getName(), clone.getName());
         Assert.assertEquals(orig.getValue(), clone.getValue());
     }
diff --git a/httpcore/src/test/java/org/apache/http/message/TestHeaderElement.java b/httpcore/src/test/java/org/apache/http/message/TestHeaderElement.java
index c3e9155..c43cd18 100644
--- a/httpcore/src/test/java/org/apache/http/message/TestHeaderElement.java
+++ b/httpcore/src/test/java/org/apache/http/message/TestHeaderElement.java
@@ -1,5 +1,4 @@
 /*
- * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//httpclient/src/test/org/apache/commons/httpclient/TestHeaderElement.java,v 1.7 2004/02/22 18:08:49 olegk Exp $
  * ====================================================================
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements.  See the NOTICE file
@@ -24,8 +23,6 @@
  * information on the Apache Software Foundation, please see
  * <http://www.apache.org/>.
  *
- * [Additional notices, if required by prior licensing conditions]
- *
  */
 
 package org.apache.http.message;
@@ -42,7 +39,7 @@ public class TestHeaderElement {
 
     @Test
     public void testConstructor3() throws Exception {
-        HeaderElement element = new BasicHeaderElement("name", "value",
+        final HeaderElement element = new BasicHeaderElement("name", "value",
                 new NameValuePair[] {
                     new BasicNameValuePair("param1", "value1"),
                     new BasicNameValuePair("param2", "value2")
@@ -56,7 +53,7 @@ public class TestHeaderElement {
 
     @Test
     public void testConstructor2() throws Exception {
-        HeaderElement element = new BasicHeaderElement("name", "value");
+        final HeaderElement element = new BasicHeaderElement("name", "value");
         Assert.assertEquals("name", element.getName());
         Assert.assertEquals("value", element.getValue());
         Assert.assertEquals(0, element.getParameters().length);
@@ -68,41 +65,41 @@ public class TestHeaderElement {
         try {
             new BasicHeaderElement(null, null, null);
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
             //expected
         }
     }
 
     @Test
     public void testParamByName() throws Exception {
-        String s = "name = value; param1 = value1; param2 = value2";
-        HeaderElement element = BasicHeaderValueParser.parseHeaderElement(s, null);
+        final String s = "name = value; param1 = value1; param2 = value2";
+        final HeaderElement element = BasicHeaderValueParser.parseHeaderElement(s, null);
         Assert.assertEquals("value1", element.getParameterByName("param1").getValue());
         Assert.assertEquals("value2", element.getParameterByName("param2").getValue());
         Assert.assertNull(element.getParameterByName("param3"));
         try {
             element.getParameterByName(null);
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
             //expected
         }
     }
 
     @Test
     public void testHashCode() {
-        HeaderElement element1 = new BasicHeaderElement("name", "value",
+        final HeaderElement element1 = new BasicHeaderElement("name", "value",
                 new NameValuePair[] {
                     new BasicNameValuePair("param1", "value1"),
                     new BasicNameValuePair("param2", "value2")
                 } );
-        HeaderElement element2 = new BasicHeaderElement("name", "value",
+        final HeaderElement element2 = new BasicHeaderElement("name", "value",
                 new NameValuePair[] {
                     new BasicNameValuePair("param2", "value2"),
                     new BasicNameValuePair("param1", "value1")
                 } );
-        HeaderElement element3 = new BasicHeaderElement("name", "value");
-        HeaderElement element4 = new BasicHeaderElement("name", "value");
-        HeaderElement element5 = new BasicHeaderElement("name", "value",
+        final HeaderElement element3 = new BasicHeaderElement("name", "value");
+        final HeaderElement element4 = new BasicHeaderElement("name", "value");
+        final HeaderElement element5 = new BasicHeaderElement("name", "value",
                 new NameValuePair[] {
                     new BasicNameValuePair("param1", "value1"),
                     new BasicNameValuePair("param2", "value2")
@@ -116,19 +113,19 @@ public class TestHeaderElement {
 
     @Test
     public void testEquals() {
-        HeaderElement element1 = new BasicHeaderElement("name", "value",
+        final HeaderElement element1 = new BasicHeaderElement("name", "value",
                 new NameValuePair[] {
                     new BasicNameValuePair("param1", "value1"),
                     new BasicNameValuePair("param2", "value2")
                 } );
-        HeaderElement element2 = new BasicHeaderElement("name", "value",
+        final HeaderElement element2 = new BasicHeaderElement("name", "value",
                 new NameValuePair[] {
                     new BasicNameValuePair("param2", "value2"),
                     new BasicNameValuePair("param1", "value1")
                 } );
-        HeaderElement element3 = new BasicHeaderElement("name", "value");
-        HeaderElement element4 = new BasicHeaderElement("name", "value");
-        HeaderElement element5 = new BasicHeaderElement("name", "value",
+        final HeaderElement element3 = new BasicHeaderElement("name", "value");
+        final HeaderElement element4 = new BasicHeaderElement("name", "value");
+        final HeaderElement element5 = new BasicHeaderElement("name", "value",
                 new NameValuePair[] {
                     new BasicNameValuePair("param1", "value1"),
                     new BasicNameValuePair("param2", "value2")
@@ -155,12 +152,12 @@ public class TestHeaderElement {
 
     @Test
     public void testCloning() throws Exception {
-        BasicHeaderElement orig = new BasicHeaderElement("name", "value",
+        final BasicHeaderElement orig = new BasicHeaderElement("name", "value",
                 new NameValuePair[] {
                     new BasicNameValuePair("param1", "value1"),
                     new BasicNameValuePair("param2", "value2")
                 } );
-        BasicHeaderElement clone = (BasicHeaderElement) orig.clone();
+        final BasicHeaderElement clone = (BasicHeaderElement) orig.clone();
         Assert.assertEquals(orig, clone);
     }
 
diff --git a/httpcore/src/test/java/org/apache/http/message/TestHeaderGroup.java b/httpcore/src/test/java/org/apache/http/message/TestHeaderGroup.java
index 722b19f..6fb6dfb 100644
--- a/httpcore/src/test/java/org/apache/http/message/TestHeaderGroup.java
+++ b/httpcore/src/test/java/org/apache/http/message/TestHeaderGroup.java
@@ -45,14 +45,14 @@ public class TestHeaderGroup {
 
     @Test
     public void testConstructor() {
-        HeaderGroup headergroup = new HeaderGroup();
+        final HeaderGroup headergroup = new HeaderGroup();
         Assert.assertNotNull(headergroup.getAllHeaders());
         Assert.assertEquals(0, headergroup.getAllHeaders().length);
     }
 
     @Test
     public void testClear() {
-        HeaderGroup headergroup = new HeaderGroup();
+        final HeaderGroup headergroup = new HeaderGroup();
         headergroup.addHeader(new BasicHeader("name", "value"));
         Assert.assertEquals(1, headergroup.getAllHeaders().length);
         headergroup.clear();
@@ -61,8 +61,8 @@ public class TestHeaderGroup {
 
     @Test
     public void testAddRemoveHeader() {
-        HeaderGroup headergroup = new HeaderGroup();
-        Header header = new BasicHeader("name", "value");
+        final HeaderGroup headergroup = new HeaderGroup();
+        final Header header = new BasicHeader("name", "value");
         headergroup.addHeader(header);
         headergroup.addHeader(null);
         Assert.assertEquals(1, headergroup.getAllHeaders().length);
@@ -73,10 +73,10 @@ public class TestHeaderGroup {
 
     @Test
     public void testUpdateHeader() {
-        HeaderGroup headergroup = new HeaderGroup();
-        Header header1 = new BasicHeader("name1", "value1");
-        Header header2 = new BasicHeader("name2", "value2");
-        Header header3 = new BasicHeader("name3", "value3");
+        final HeaderGroup headergroup = new HeaderGroup();
+        final Header header1 = new BasicHeader("name1", "value1");
+        final Header header2 = new BasicHeader("name2", "value2");
+        final Header header3 = new BasicHeader("name3", "value3");
         headergroup.addHeader(header1);
         headergroup.addHeader(header2);
         headergroup.addHeader(header3);
@@ -89,10 +89,10 @@ public class TestHeaderGroup {
 
     @Test
     public void testSetHeaders() {
-        HeaderGroup headergroup = new HeaderGroup();
-        Header header1 = new BasicHeader("name1", "value1");
-        Header header2 = new BasicHeader("name2", "value2");
-        Header header3 = new BasicHeader("name3", "value3");
+        final HeaderGroup headergroup = new HeaderGroup();
+        final Header header1 = new BasicHeader("name1", "value1");
+        final Header header2 = new BasicHeader("name2", "value2");
+        final Header header3 = new BasicHeader("name3", "value3");
         headergroup.addHeader(header1);
         headergroup.setHeaders(new Header[] { header2, header3 });
         Assert.assertEquals(2, headergroup.getAllHeaders().length);
@@ -108,10 +108,10 @@ public class TestHeaderGroup {
 
     @Test
     public void testFirstLastHeaders() {
-        HeaderGroup headergroup = new HeaderGroup();
-        Header header1 = new BasicHeader("name", "value1");
-        Header header2 = new BasicHeader("name", "value2");
-        Header header3 = new BasicHeader("name", "value3");
+        final HeaderGroup headergroup = new HeaderGroup();
+        final Header header1 = new BasicHeader("name", "value1");
+        final Header header2 = new BasicHeader("name", "value2");
+        final Header header3 = new BasicHeader("name", "value3");
         headergroup.setHeaders(new Header[] { header1, header2, header3 });
 
         Assert.assertNull(headergroup.getFirstHeader("whatever"));
@@ -123,12 +123,12 @@ public class TestHeaderGroup {
 
     @Test
     public void testCondensedHeader() {
-        HeaderGroup headergroup = new HeaderGroup();
+        final HeaderGroup headergroup = new HeaderGroup();
         Assert.assertNull(headergroup.getCondensedHeader("name"));
 
-        Header header1 = new BasicHeader("name", "value1");
-        Header header2 = new BasicHeader("name", "value2");
-        Header header3 = new BasicHeader("name", "value3");
+        final Header header1 = new BasicHeader("name", "value1");
+        final Header header2 = new BasicHeader("name", "value2");
+        final Header header3 = new BasicHeader("name", "value3");
         headergroup.setHeaders(new Header[] { header1, header2, header3 });
 
         Assert.assertEquals("value1, value2, value3", headergroup.getCondensedHeader("name").getValue());
@@ -139,20 +139,20 @@ public class TestHeaderGroup {
 
     @Test
     public void testIterator() {
-        HeaderGroup headergroup = new HeaderGroup();
-        HeaderIterator i = headergroup.iterator();
+        final HeaderGroup headergroup = new HeaderGroup();
+        final HeaderIterator i = headergroup.iterator();
         Assert.assertNotNull(i);
         Assert.assertFalse(i.hasNext());
     }
 
     @Test
     public void testHeaderRemove() {
-        HeaderGroup headergroup = new HeaderGroup();
-        Header header1 = new BasicHeader("name", "value1");
-        Header header2 = new BasicHeader("name", "value2");
-        Header header3 = new BasicHeader("name", "value3");
+        final HeaderGroup headergroup = new HeaderGroup();
+        final Header header1 = new BasicHeader("name", "value1");
+        final Header header2 = new BasicHeader("name", "value2");
+        final Header header3 = new BasicHeader("name", "value3");
         headergroup.setHeaders(new Header[] { header1, header2, header3 });
-        HeaderIterator i = headergroup.iterator();
+        final HeaderIterator i = headergroup.iterator();
         Assert.assertNotNull(i);
         Assert.assertTrue(i.hasNext());
         i.next();
@@ -169,14 +169,14 @@ public class TestHeaderGroup {
 
     @Test
     public void testCloning() throws Exception {
-        HeaderGroup orig = new HeaderGroup();
-        Header header1 = new BasicHeader("name", "value1");
-        Header header2 = new BasicHeader("name", "value2");
-        Header header3 = new BasicHeader("name", "value3");
+        final HeaderGroup orig = new HeaderGroup();
+        final Header header1 = new BasicHeader("name", "value1");
+        final Header header2 = new BasicHeader("name", "value2");
+        final Header header3 = new BasicHeader("name", "value3");
         orig.setHeaders(new Header[] { header1, header2, header3 });
-        HeaderGroup clone = (HeaderGroup) orig.clone();
-        Header[] headers1 = orig.getAllHeaders();
-        Header[] headers2 = clone.getAllHeaders();
+        final HeaderGroup clone = (HeaderGroup) orig.clone();
+        final Header[] headers1 = orig.getAllHeaders();
+        final Header[] headers2 = clone.getAllHeaders();
         Assert.assertNotNull(headers1);
         Assert.assertNotNull(headers2);
         Assert.assertEquals(3, headers2.length);
@@ -189,21 +189,21 @@ public class TestHeaderGroup {
 
     @Test
     public void testSerialization() throws Exception {
-        HeaderGroup orig = new HeaderGroup();
-        Header header1 = new BasicHeader("name", "value1");
-        Header header2 = new BasicHeader("name", "value2");
-        Header header3 = new BasicHeader("name", "value3");
+        final HeaderGroup orig = new HeaderGroup();
+        final Header header1 = new BasicHeader("name", "value1");
+        final Header header2 = new BasicHeader("name", "value2");
+        final Header header3 = new BasicHeader("name", "value3");
         orig.setHeaders(new Header[] { header1, header2, header3 });
-        ByteArrayOutputStream outbuffer = new ByteArrayOutputStream();
-        ObjectOutputStream outstream = new ObjectOutputStream(outbuffer);
+        final ByteArrayOutputStream outbuffer = new ByteArrayOutputStream();
+        final ObjectOutputStream outstream = new ObjectOutputStream(outbuffer);
         outstream.writeObject(orig);
         outstream.close();
-        byte[] raw = outbuffer.toByteArray();
-        ByteArrayInputStream inbuffer = new ByteArrayInputStream(raw);
-        ObjectInputStream instream = new ObjectInputStream(inbuffer);
-        HeaderGroup clone = (HeaderGroup) instream.readObject();
-        Header[] headers1 = orig.getAllHeaders();
-        Header[] headers2 = clone.getAllHeaders();
+        final byte[] raw = outbuffer.toByteArray();
+        final ByteArrayInputStream inbuffer = new ByteArrayInputStream(raw);
+        final ObjectInputStream instream = new ObjectInputStream(inbuffer);
+        final HeaderGroup clone = (HeaderGroup) instream.readObject();
+        final Header[] headers1 = orig.getAllHeaders();
+        final Header[] headers2 = clone.getAllHeaders();
         Assert.assertNotNull(headers1);
         Assert.assertNotNull(headers2);
         Assert.assertEquals(headers1.length, headers2.length);
diff --git a/httpcore/src/test/java/org/apache/http/message/TestNameValuePair.java b/httpcore/src/test/java/org/apache/http/message/TestNameValuePair.java
index a53152d..89e2ebf 100644
--- a/httpcore/src/test/java/org/apache/http/message/TestNameValuePair.java
+++ b/httpcore/src/test/java/org/apache/http/message/TestNameValuePair.java
@@ -39,7 +39,7 @@ public class TestNameValuePair {
 
     @Test
     public void testConstructor() {
-        NameValuePair param = new BasicNameValuePair("name", "value");
+        final NameValuePair param = new BasicNameValuePair("name", "value");
         Assert.assertEquals("name", param.getName());
         Assert.assertEquals("value", param.getValue());
     }
@@ -49,25 +49,25 @@ public class TestNameValuePair {
         try {
             new BasicNameValuePair(null, null);
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
             //expected
         }
     }
 
     @Test
     public void testHashCode() {
-        NameValuePair param1 = new BasicNameValuePair("name1", "value1");
-        NameValuePair param2 = new BasicNameValuePair("name2", "value2");
-        NameValuePair param3 = new BasicNameValuePair("name1", "value1");
+        final NameValuePair param1 = new BasicNameValuePair("name1", "value1");
+        final NameValuePair param2 = new BasicNameValuePair("name2", "value2");
+        final NameValuePair param3 = new BasicNameValuePair("name1", "value1");
         Assert.assertTrue(param1.hashCode() != param2.hashCode());
         Assert.assertTrue(param1.hashCode() == param3.hashCode());
     }
 
     @Test
     public void testEquals() {
-        NameValuePair param1 = new BasicNameValuePair("name1", "value1");
-        NameValuePair param2 = new BasicNameValuePair("name2", "value2");
-        NameValuePair param3 = new BasicNameValuePair("name1", "value1");
+        final NameValuePair param1 = new BasicNameValuePair("name1", "value1");
+        final NameValuePair param2 = new BasicNameValuePair("name2", "value2");
+        final NameValuePair param3 = new BasicNameValuePair("name1", "value1");
         Assert.assertFalse(param1.equals(param2));
         Assert.assertFalse(param1.equals(null));
         Assert.assertFalse(param1.equals("name1 = value1"));
@@ -78,16 +78,16 @@ public class TestNameValuePair {
 
     @Test
     public void testToString() {
-        NameValuePair param1 = new BasicNameValuePair("name1", "value1");
+        final NameValuePair param1 = new BasicNameValuePair("name1", "value1");
         Assert.assertEquals("name1=value1", param1.toString());
-        NameValuePair param2 = new BasicNameValuePair("name1", null);
+        final NameValuePair param2 = new BasicNameValuePair("name1", null);
         Assert.assertEquals("name1", param2.toString());
     }
 
     @Test
     public void testCloning() throws Exception {
-        BasicNameValuePair orig = new BasicNameValuePair("name1", "value1");
-        BasicNameValuePair clone = (BasicNameValuePair) orig.clone();
+        final BasicNameValuePair orig = new BasicNameValuePair("name1", "value1");
+        final BasicNameValuePair clone = (BasicNameValuePair) orig.clone();
         Assert.assertEquals(orig, clone);
     }
 
diff --git a/httpcore/src/test/java/org/apache/http/message/TestRequestLine.java b/httpcore/src/test/java/org/apache/http/message/TestRequestLine.java
index 3ef9905..8432830 100644
--- a/httpcore/src/test/java/org/apache/http/message/TestRequestLine.java
+++ b/httpcore/src/test/java/org/apache/http/message/TestRequestLine.java
@@ -44,7 +44,7 @@ public class TestRequestLine {
 
     @Test
     public void testConstructor() {
-        RequestLine requestline = new BasicRequestLine("GET", "/stuff", HttpVersion.HTTP_1_1);
+        final RequestLine requestline = new BasicRequestLine("GET", "/stuff", HttpVersion.HTTP_1_1);
         Assert.assertEquals("GET", requestline.getMethod());
         Assert.assertEquals("/stuff", requestline.getUri());
         Assert.assertEquals(HttpVersion.HTTP_1_1, requestline.getProtocolVersion());
@@ -55,21 +55,21 @@ public class TestRequestLine {
         try {
             new BasicRequestLine(null, "/stuff", HttpVersion.HTTP_1_1);
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException e) { /* expected */ }
+        } catch (final IllegalArgumentException e) { /* expected */ }
         try {
             new BasicRequestLine("GET", null, HttpVersion.HTTP_1_1);
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException e) { /* expected */ }
+        } catch (final IllegalArgumentException e) { /* expected */ }
         try {
             new BasicRequestLine("GET", "/stuff", (HttpVersion)null);
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException e) { /* expected */ }
+        } catch (final IllegalArgumentException e) { /* expected */ }
     }
 
     @Test
     public void testCloning() throws Exception {
-        BasicRequestLine orig = new BasicRequestLine("GET", "/stuff", HttpVersion.HTTP_1_1);
-        BasicRequestLine clone = (BasicRequestLine) orig.clone();
+        final BasicRequestLine orig = new BasicRequestLine("GET", "/stuff", HttpVersion.HTTP_1_1);
+        final BasicRequestLine clone = (BasicRequestLine) orig.clone();
         Assert.assertEquals(orig.getMethod(), clone.getMethod());
         Assert.assertEquals(orig.getUri(), clone.getUri());
         Assert.assertEquals(orig.getProtocolVersion(), clone.getProtocolVersion());
@@ -77,15 +77,15 @@ public class TestRequestLine {
 
     @Test
     public void testSerialization() throws Exception {
-        BasicRequestLine orig = new BasicRequestLine("GET", "/stuff", HttpVersion.HTTP_1_1);
-        ByteArrayOutputStream outbuffer = new ByteArrayOutputStream();
-        ObjectOutputStream outstream = new ObjectOutputStream(outbuffer);
+        final BasicRequestLine orig = new BasicRequestLine("GET", "/stuff", HttpVersion.HTTP_1_1);
+        final ByteArrayOutputStream outbuffer = new ByteArrayOutputStream();
+        final ObjectOutputStream outstream = new ObjectOutputStream(outbuffer);
         outstream.writeObject(orig);
         outstream.close();
-        byte[] raw = outbuffer.toByteArray();
-        ByteArrayInputStream inbuffer = new ByteArrayInputStream(raw);
-        ObjectInputStream instream = new ObjectInputStream(inbuffer);
-        BasicRequestLine clone = (BasicRequestLine) instream.readObject();
+        final byte[] raw = outbuffer.toByteArray();
+        final ByteArrayInputStream inbuffer = new ByteArrayInputStream(raw);
+        final ObjectInputStream instream = new ObjectInputStream(inbuffer);
+        final BasicRequestLine clone = (BasicRequestLine) instream.readObject();
         Assert.assertEquals(orig.getMethod(), clone.getMethod());
         Assert.assertEquals(orig.getUri(), clone.getUri());
         Assert.assertEquals(orig.getProtocolVersion(), clone.getProtocolVersion());
diff --git a/httpcore/src/test/java/org/apache/http/message/TestStatusLine.java b/httpcore/src/test/java/org/apache/http/message/TestStatusLine.java
index db7ddc5..d1f7e58 100644
--- a/httpcore/src/test/java/org/apache/http/message/TestStatusLine.java
+++ b/httpcore/src/test/java/org/apache/http/message/TestStatusLine.java
@@ -45,7 +45,7 @@ public class TestStatusLine {
 
     @Test
     public void testConstructor() {
-        StatusLine statusline = new BasicStatusLine(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK");
+        final StatusLine statusline = new BasicStatusLine(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK");
         Assert.assertEquals(HttpVersion.HTTP_1_1, statusline.getProtocolVersion());
         Assert.assertEquals(HttpStatus.SC_OK, statusline.getStatusCode());
         Assert.assertEquals("OK", statusline.getReasonPhrase());
@@ -56,11 +56,11 @@ public class TestStatusLine {
         try {
             new BasicStatusLine(null, HttpStatus.SC_OK, "OK");
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException e) { /* expected */ }
+        } catch (final IllegalArgumentException e) { /* expected */ }
         try {
             new BasicStatusLine(HttpVersion.HTTP_1_1, -1, "OK");
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException e) { /* expected */ }
+        } catch (final IllegalArgumentException e) { /* expected */ }
     }
 
     @Test
@@ -74,8 +74,8 @@ public class TestStatusLine {
 
     @Test
     public void testCloning() throws Exception {
-        BasicStatusLine orig = new BasicStatusLine(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK");
-        BasicStatusLine clone = (BasicStatusLine) orig.clone();
+        final BasicStatusLine orig = new BasicStatusLine(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK");
+        final BasicStatusLine clone = (BasicStatusLine) orig.clone();
         Assert.assertEquals(orig.getReasonPhrase(), clone.getReasonPhrase());
         Assert.assertEquals(orig.getStatusCode(), clone.getStatusCode());
         Assert.assertEquals(orig.getProtocolVersion(), clone.getProtocolVersion());
@@ -83,15 +83,15 @@ public class TestStatusLine {
 
     @Test
     public void testSerialization() throws Exception {
-        BasicStatusLine orig = new BasicStatusLine(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK");
-        ByteArrayOutputStream outbuffer = new ByteArrayOutputStream();
-        ObjectOutputStream outstream = new ObjectOutputStream(outbuffer);
+        final BasicStatusLine orig = new BasicStatusLine(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK");
+        final ByteArrayOutputStream outbuffer = new ByteArrayOutputStream();
+        final ObjectOutputStream outstream = new ObjectOutputStream(outbuffer);
         outstream.writeObject(orig);
         outstream.close();
-        byte[] raw = outbuffer.toByteArray();
-        ByteArrayInputStream inbuffer = new ByteArrayInputStream(raw);
-        ObjectInputStream instream = new ObjectInputStream(inbuffer);
-        BasicStatusLine clone = (BasicStatusLine) instream.readObject();
+        final byte[] raw = outbuffer.toByteArray();
+        final ByteArrayInputStream inbuffer = new ByteArrayInputStream(raw);
+        final ObjectInputStream instream = new ObjectInputStream(inbuffer);
+        final BasicStatusLine clone = (BasicStatusLine) instream.readObject();
         Assert.assertEquals(orig.getReasonPhrase(), clone.getReasonPhrase());
         Assert.assertEquals(orig.getStatusCode(), clone.getStatusCode());
         Assert.assertEquals(orig.getProtocolVersion(), clone.getProtocolVersion());
diff --git a/httpcore/src/test/java/org/apache/http/params/TestBasicHttpParams.java b/httpcore/src/test/java/org/apache/http/params/TestBasicHttpParams.java
deleted file mode 100644
index 07cfd85..0000000
--- a/httpcore/src/test/java/org/apache/http/params/TestBasicHttpParams.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * ====================================================================
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- *
- */
-
-package org.apache.http.params;
-
-import java.util.Iterator;
-import java.util.Set;
-
-import org.junit.Assert;
-import org.junit.Test;
-
-/**
- * Unit tests for {@link BasicHttpParams}.
- *
- */
-public class TestBasicHttpParams {
-
-    @Test
-    public void testRemoveParam() {
-        BasicHttpParams params = new BasicHttpParams();
-        params.setParameter("param1", "paramValue1");
-        Assert.assertTrue("The parameter should be removed successfully",
-                params.removeParameter("param1"));
-        Assert.assertFalse("The parameter should not be present",
-                params.removeParameter("param1"));
-
-        //try a remove from an empty params
-        params = new BasicHttpParams();
-        Assert.assertFalse("The parameter should not be present",
-                params.removeParameter("param1"));
-    }
-
-    @Test
-    public void testgetNames() {
-        BasicHttpParams params = new BasicHttpParams();
-        Set<String> nameSet = params.getNames();
-        Assert.assertTrue(nameSet.isEmpty());
-        params.setBooleanParameter("true", true);
-        Assert.assertTrue(nameSet.isEmpty()); // Still empty, as it is a snapshot
-        nameSet = params.getNames();
-        Assert.assertFalse(nameSet.isEmpty());
-        Assert.assertEquals(1, nameSet.size());
-        Iterator<String> iterator = nameSet.iterator(); // refetch, as iterator is a snapshot
-        Assert.assertTrue("Iterator has an entry",iterator.hasNext());
-        String entry = iterator.next();
-        // Note: Java 1.3 requires JUnit 3.8.1 which does not have Assert.assertTrue(Boolean)
-        Assert.assertTrue(((Boolean) params.getParameter(entry)).booleanValue());
-    }
-}
diff --git a/httpcore/src/test/java/org/apache/http/params/TestDefaultedHttpParams.java b/httpcore/src/test/java/org/apache/http/params/TestDefaultedHttpParams.java
deleted file mode 100644
index 08b5f7e..0000000
--- a/httpcore/src/test/java/org/apache/http/params/TestDefaultedHttpParams.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * ====================================================================
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- *
- */
-
-package org.apache.http.params;
-
-import java.util.Set;
-
-import org.junit.Assert;
-import org.junit.Test;
-
-/**
- * Unit tests for {@link BasicHttpParams}.
- *
- */
-public class TestDefaultedHttpParams {
-
-    @Test
-    public void testAddRemoveParam() {
-        DefaultedHttpParams deflt = new DefaultedHttpParams(new BasicHttpParams(), new BasicHttpParams());
-        Assert.assertFalse("The parameter should not be removed successfully", deflt.removeParameter("param1"));
-        deflt.setParameter("param1", "paramValue1");
-        Assert.assertEquals(0, deflt.getDefaultNames().size());
-        Assert.assertEquals(1, deflt.getNames().size());
-        Assert.assertEquals(1, deflt.getLocalNames().size());
-        Assert.assertTrue("The parameter should be removed successfully", deflt.removeParameter("param1"));
-        Assert.assertFalse("The parameter should not be present", deflt.removeParameter("param1"));
-        Assert.assertEquals(0, deflt.getDefaultNames().size());
-        Assert.assertEquals(0, deflt.getNames().size());
-        Assert.assertEquals(0, deflt.getLocalNames().size());
-    }
-
-    @Test
-    public void testEmptyParams() {
-        DefaultedHttpParams deflt = new DefaultedHttpParams(new BasicHttpParams(), new BasicHttpParams());
-        Assert.assertNull("The parameter should not be present", deflt.getParameter("param1"));
-        //try a remove from an empty params
-        Assert.assertFalse("The parameter should not be present", deflt.removeParameter("param1"));
-
-        Assert.assertEquals(0, deflt.getNames().size());
-        Assert.assertEquals(0, deflt.getLocalNames().size());
-        Assert.assertEquals(0, deflt.getDefaultNames().size());
-    }
-
-    private HttpParams addParams(String name){
-        BasicHttpParams params = new BasicHttpParams();
-        params.setParameter("common","both");
-        params.setParameter(name,"value");
-        return params;
-    }
-
-    @Test
-    public void testgetNames() {
-        DefaultedHttpParams params = new DefaultedHttpParams(addParams("local"), addParams("default"));
-
-        Set<String> nameSet = params.getNames();
-        Assert.assertEquals(3, nameSet.size());
-        Set<String> localnameSet = params.getLocalNames();
-        Assert.assertEquals(2, localnameSet.size());
-        Set<String> defaultnameSet = params.getDefaultNames();
-        Assert.assertEquals(2, defaultnameSet.size());
-
-        params.setParameter("new", null);
-        Assert.assertEquals(3, nameSet.size()); // Name set not yet updated
-        Assert.assertEquals(2, localnameSet.size());
-        Assert.assertEquals(2, defaultnameSet.size());
-
-        nameSet = params.getNames();
-        localnameSet = params.getLocalNames();
-        defaultnameSet = params.getDefaultNames();
-        Assert.assertEquals(4, nameSet.size());
-        Assert.assertEquals(3, localnameSet.size());
-        Assert.assertEquals(2, defaultnameSet.size());
-    }
-}
diff --git a/httpcore/src/test/java/org/apache/http/pool/TestConnPool.java b/httpcore/src/test/java/org/apache/http/pool/TestConnPool.java
index 1d77c6a..816f9fc 100644
--- a/httpcore/src/test/java/org/apache/http/pool/TestConnPool.java
+++ b/httpcore/src/test/java/org/apache/http/pool/TestConnPool.java
@@ -32,9 +32,8 @@ import java.util.concurrent.Future;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
 
-import junit.framework.Assert;
-
 import org.apache.http.HttpConnection;
+import org.junit.Assert;
 import org.junit.Test;
 import org.mockito.Mockito;
 
@@ -47,21 +46,27 @@ public class TestConnPool {
 
     static class LocalPoolEntry extends PoolEntry<String, HttpConnection> {
 
+        private boolean closed;
+
         public LocalPoolEntry(final String route, final HttpConnection conn) {
             super(null, route, conn);
         }
 
         @Override
         public void close() {
+            if (this.closed) {
+                return;
+            }
+            this.closed = true;
             try {
                 getConnection().close();
-            } catch (IOException ignore) {
+            } catch (final IOException ignore) {
             }
         }
 
         @Override
         public boolean isClosed() {
-            return !getConnection().isOpen();
+            return this.closed;
         }
 
     }
@@ -70,7 +75,7 @@ public class TestConnPool {
 
         public LocalConnPool(
                 final ConnFactory<String, HttpConnection> connFactory,
-                int defaultMaxPerRoute, int maxTotal) {
+                final int defaultMaxPerRoute, final int maxTotal) {
             super(connFactory, defaultMaxPerRoute, maxTotal);
         }
 
@@ -83,15 +88,15 @@ public class TestConnPool {
 
     @Test
     public void testEmptyPool() throws Exception {
-        LocalConnFactory connFactory = Mockito.mock(LocalConnFactory.class);
-        LocalConnPool pool = new LocalConnPool(connFactory, 2, 10);
+        final LocalConnFactory connFactory = Mockito.mock(LocalConnFactory.class);
+        final LocalConnPool pool = new LocalConnPool(connFactory, 2, 10);
         pool.setDefaultMaxPerRoute(5);
         pool.setMaxPerRoute("somehost", 3);
-        PoolStats totals = pool.getTotalStats();
+        final PoolStats totals = pool.getTotalStats();
         Assert.assertEquals(0, totals.getAvailable());
         Assert.assertEquals(0, totals.getLeased());
         Assert.assertEquals(10, totals.getMax());
-        PoolStats stats = pool.getStats("somehost");
+        final PoolStats stats = pool.getStats("somehost");
         Assert.assertEquals(0, stats.getAvailable());
         Assert.assertEquals(0, stats.getLeased());
         Assert.assertEquals(3, stats.getMax());
@@ -100,46 +105,46 @@ public class TestConnPool {
 
     @Test
     public void testInvalidConstruction() throws Exception {
-        LocalConnFactory connFactory = Mockito.mock(LocalConnFactory.class);
+        final LocalConnFactory connFactory = Mockito.mock(LocalConnFactory.class);
         try {
             new LocalConnPool(connFactory, -1, 1);
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException expected) {
+        } catch (final IllegalArgumentException expected) {
         }
         try {
             new LocalConnPool(connFactory, 1, -1);
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException expected) {
+        } catch (final IllegalArgumentException expected) {
         }
     }
 
     @Test
     public void testLeaseRelease() throws Exception {
-        HttpConnection conn1 = Mockito.mock(HttpConnection.class);
+        final HttpConnection conn1 = Mockito.mock(HttpConnection.class);
         Mockito.when(conn1.isOpen()).thenReturn(true);
-        HttpConnection conn2 = Mockito.mock(HttpConnection.class);
+        final HttpConnection conn2 = Mockito.mock(HttpConnection.class);
         Mockito.when(conn2.isOpen()).thenReturn(true);
 
-        LocalConnFactory connFactory = Mockito.mock(LocalConnFactory.class);
+        final LocalConnFactory connFactory = Mockito.mock(LocalConnFactory.class);
         Mockito.when(connFactory.create(Mockito.eq("somehost"))).thenReturn(conn1);
         Mockito.when(connFactory.create(Mockito.eq("otherhost"))).thenReturn(conn2);
 
-        LocalConnPool pool = new LocalConnPool(connFactory, 2, 10);
-        Future<LocalPoolEntry> future1 = pool.lease("somehost", null);
-        LocalPoolEntry entry1 = future1.get(1, TimeUnit.SECONDS);
+        final LocalConnPool pool = new LocalConnPool(connFactory, 2, 10);
+        final Future<LocalPoolEntry> future1 = pool.lease("somehost", null);
+        final LocalPoolEntry entry1 = future1.get(1, TimeUnit.SECONDS);
         Assert.assertNotNull(entry1);
-        Future<LocalPoolEntry> future2 = pool.lease("somehost", null);
-        LocalPoolEntry entry2 = future2.get(1, TimeUnit.SECONDS);
+        final Future<LocalPoolEntry> future2 = pool.lease("somehost", null);
+        final LocalPoolEntry entry2 = future2.get(1, TimeUnit.SECONDS);
         Assert.assertNotNull(entry2);
-        Future<LocalPoolEntry> future3 = pool.lease("otherhost", null);
-        LocalPoolEntry entry3 = future3.get(1, TimeUnit.SECONDS);
+        final Future<LocalPoolEntry> future3 = pool.lease("otherhost", null);
+        final LocalPoolEntry entry3 = future3.get(1, TimeUnit.SECONDS);
         Assert.assertNotNull(entry3);
 
         PoolStats totals = pool.getTotalStats();
         Assert.assertEquals(0, totals.getAvailable());
         Assert.assertEquals(3, totals.getLeased());
 
-        LocalPoolEntry entry = future1.get();
+        final LocalPoolEntry entry = future1.get();
         Assert.assertSame(entry1, entry);
 
         pool.release(entry1, true);
@@ -155,19 +160,19 @@ public class TestConnPool {
 
     @Test
     public void testLeaseIllegal() throws Exception {
-        LocalConnFactory connFactory = Mockito.mock(LocalConnFactory.class);
-        LocalConnPool pool = new LocalConnPool(connFactory, 2, 10);
+        final LocalConnFactory connFactory = Mockito.mock(LocalConnFactory.class);
+        final LocalConnPool pool = new LocalConnPool(connFactory, 2, 10);
         try {
             pool.lease(null, null);
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException expected) {
+        } catch (final IllegalArgumentException expected) {
         }
     }
 
     @Test
     public void testReleaseUnknownEntry() throws Exception {
-        LocalConnFactory connFactory = Mockito.mock(LocalConnFactory.class);
-        LocalConnPool pool = new LocalConnPool(connFactory, 2, 10);
+        final LocalConnFactory connFactory = Mockito.mock(LocalConnFactory.class);
+        final LocalConnPool pool = new LocalConnPool(connFactory, 2, 10);
         pool.release(new LocalPoolEntry("somehost", Mockito.mock(HttpConnection.class)), true);
     }
 
@@ -196,7 +201,7 @@ public class TestConnPool {
         public void run() {
             try {
                 this.entry = this.future.get(this.time, this.tunit);
-            } catch (Exception ex) {
+            } catch (final Exception ex) {
                 this.ex = ex;
             }
         }
@@ -217,83 +222,83 @@ public class TestConnPool {
 
     @Test
     public void testMaxLimits() throws Exception {
-        LocalConnFactory connFactory = Mockito.mock(LocalConnFactory.class);
+        final LocalConnFactory connFactory = Mockito.mock(LocalConnFactory.class);
 
-        HttpConnection conn1 = Mockito.mock(HttpConnection.class);
+        final HttpConnection conn1 = Mockito.mock(HttpConnection.class);
         Mockito.when(conn1.isOpen()).thenReturn(true);
         Mockito.when(connFactory.create(Mockito.eq("somehost"))).thenReturn(conn1);
 
-        HttpConnection conn2 = Mockito.mock(HttpConnection.class);
+        final HttpConnection conn2 = Mockito.mock(HttpConnection.class);
         Mockito.when(conn2.isOpen()).thenReturn(true);
         Mockito.when(connFactory.create(Mockito.eq("otherhost"))).thenReturn(conn2);
 
-        LocalConnPool pool = new LocalConnPool(connFactory, 2, 10);
+        final LocalConnPool pool = new LocalConnPool(connFactory, 2, 10);
         pool.setMaxPerRoute("somehost", 2);
         pool.setMaxPerRoute("otherhost", 1);
         pool.setMaxTotal(3);
 
-        Future<LocalPoolEntry> future1 = pool.lease("somehost", null);
-        GetPoolEntryThread t1 = new GetPoolEntryThread(future1);
+        final Future<LocalPoolEntry> future1 = pool.lease("somehost", null);
+        final GetPoolEntryThread t1 = new GetPoolEntryThread(future1);
         t1.start();
-        Future<LocalPoolEntry> future2 = pool.lease("somehost", null);
-        GetPoolEntryThread t2 = new GetPoolEntryThread(future2);
+        final Future<LocalPoolEntry> future2 = pool.lease("somehost", null);
+        final GetPoolEntryThread t2 = new GetPoolEntryThread(future2);
         t2.start();
-        Future<LocalPoolEntry> future3 = pool.lease("otherhost", null);
-        GetPoolEntryThread t3 = new GetPoolEntryThread(future3);
+        final Future<LocalPoolEntry> future3 = pool.lease("otherhost", null);
+        final GetPoolEntryThread t3 = new GetPoolEntryThread(future3);
         t3.start();
 
         t1.join(GRACE_PERIOD);
         Assert.assertTrue(future1.isDone());
-        LocalPoolEntry entry1 = t1.getEntry();
+        final LocalPoolEntry entry1 = t1.getEntry();
         Assert.assertNotNull(entry1);
         t2.join(GRACE_PERIOD);
         Assert.assertTrue(future2.isDone());
-        LocalPoolEntry entry2 = t2.getEntry();
+        final LocalPoolEntry entry2 = t2.getEntry();
         Assert.assertNotNull(entry2);
         t3.join(GRACE_PERIOD);
         Assert.assertTrue(future3.isDone());
-        LocalPoolEntry entry3 = t3.getEntry();
+        final LocalPoolEntry entry3 = t3.getEntry();
         Assert.assertNotNull(entry3);
 
         pool.release(entry1, true);
         pool.release(entry2, true);
         pool.release(entry3, true);
 
-        PoolStats totals = pool.getTotalStats();
+        final PoolStats totals = pool.getTotalStats();
         Assert.assertEquals(3, totals.getAvailable());
         Assert.assertEquals(0, totals.getLeased());
 
-        Future<LocalPoolEntry> future4 = pool.lease("somehost", null);
-        GetPoolEntryThread t4 = new GetPoolEntryThread(future4);
+        final Future<LocalPoolEntry> future4 = pool.lease("somehost", null);
+        final GetPoolEntryThread t4 = new GetPoolEntryThread(future4);
         t4.start();
-        Future<LocalPoolEntry> future5 = pool.lease("somehost", null);
-        GetPoolEntryThread t5 = new GetPoolEntryThread(future5);
+        final Future<LocalPoolEntry> future5 = pool.lease("somehost", null);
+        final GetPoolEntryThread t5 = new GetPoolEntryThread(future5);
         t5.start();
-        Future<LocalPoolEntry> future6 = pool.lease("otherhost", null);
-        GetPoolEntryThread t6 = new GetPoolEntryThread(future6);
+        final Future<LocalPoolEntry> future6 = pool.lease("otherhost", null);
+        final GetPoolEntryThread t6 = new GetPoolEntryThread(future6);
         t6.start();
 
         t4.join(GRACE_PERIOD);
         Assert.assertTrue(future4.isDone());
-        LocalPoolEntry entry4 = t4.getEntry();
+        final LocalPoolEntry entry4 = t4.getEntry();
         Assert.assertNotNull(entry4);
         t5.join(GRACE_PERIOD);
         Assert.assertTrue(future5.isDone());
-        LocalPoolEntry entry5 = t5.getEntry();
+        final LocalPoolEntry entry5 = t5.getEntry();
         Assert.assertNotNull(entry5);
         t6.join(GRACE_PERIOD);
         Assert.assertTrue(future6.isDone());
-        LocalPoolEntry entry6 = t6.getEntry();
+        final LocalPoolEntry entry6 = t6.getEntry();
         Assert.assertNotNull(entry6);
 
-        Future<LocalPoolEntry> future7 = pool.lease("somehost", null);
-        GetPoolEntryThread t7 = new GetPoolEntryThread(future7);
+        final Future<LocalPoolEntry> future7 = pool.lease("somehost", null);
+        final GetPoolEntryThread t7 = new GetPoolEntryThread(future7);
         t7.start();
-        Future<LocalPoolEntry> future8 = pool.lease("somehost", null);
-        GetPoolEntryThread t8 = new GetPoolEntryThread(future8);
+        final Future<LocalPoolEntry> future8 = pool.lease("somehost", null);
+        final GetPoolEntryThread t8 = new GetPoolEntryThread(future8);
         t8.start();
-        Future<LocalPoolEntry> future9 = pool.lease("otherhost", null);
-        GetPoolEntryThread t9 = new GetPoolEntryThread(future9);
+        final Future<LocalPoolEntry> future9 = pool.lease("otherhost", null);
+        final GetPoolEntryThread t9 = new GetPoolEntryThread(future9);
         t9.start();
 
         Assert.assertFalse(t7.isDone());
@@ -318,48 +323,48 @@ public class TestConnPool {
 
     @Test
     public void testConnectionRedistributionOnTotalMaxLimit() throws Exception {
-        LocalConnFactory connFactory = Mockito.mock(LocalConnFactory.class);
+        final LocalConnFactory connFactory = Mockito.mock(LocalConnFactory.class);
 
-        HttpConnection conn1 = Mockito.mock(HttpConnection.class);
+        final HttpConnection conn1 = Mockito.mock(HttpConnection.class);
         Mockito.when(conn1.isOpen()).thenReturn(true);
-        HttpConnection conn2 = Mockito.mock(HttpConnection.class);
+        final HttpConnection conn2 = Mockito.mock(HttpConnection.class);
         Mockito.when(conn2.isOpen()).thenReturn(true);
-        HttpConnection conn3 = Mockito.mock(HttpConnection.class);
+        final HttpConnection conn3 = Mockito.mock(HttpConnection.class);
         Mockito.when(conn3.isOpen()).thenReturn(true);
         Mockito.when(connFactory.create(Mockito.eq("somehost"))).thenReturn(conn1, conn2, conn3);
 
-        HttpConnection conn4 = Mockito.mock(HttpConnection.class);
+        final HttpConnection conn4 = Mockito.mock(HttpConnection.class);
         Mockito.when(conn4.isOpen()).thenReturn(true);
-        HttpConnection conn5 = Mockito.mock(HttpConnection.class);
+        final HttpConnection conn5 = Mockito.mock(HttpConnection.class);
         Mockito.when(conn5.isOpen()).thenReturn(true);
         Mockito.when(connFactory.create(Mockito.eq("otherhost"))).thenReturn(conn4, conn5);
 
-        LocalConnPool pool = new LocalConnPool(connFactory, 2, 10);
+        final LocalConnPool pool = new LocalConnPool(connFactory, 2, 10);
         pool.setMaxPerRoute("somehost", 2);
         pool.setMaxPerRoute("otherhost", 2);
         pool.setMaxTotal(2);
 
-        Future<LocalPoolEntry> future1 = pool.lease("somehost", null);
-        GetPoolEntryThread t1 = new GetPoolEntryThread(future1);
+        final Future<LocalPoolEntry> future1 = pool.lease("somehost", null);
+        final GetPoolEntryThread t1 = new GetPoolEntryThread(future1);
         t1.start();
-        Future<LocalPoolEntry> future2 = pool.lease("somehost", null);
-        GetPoolEntryThread t2 = new GetPoolEntryThread(future2);
+        final Future<LocalPoolEntry> future2 = pool.lease("somehost", null);
+        final GetPoolEntryThread t2 = new GetPoolEntryThread(future2);
         t2.start();
 
         t1.join(GRACE_PERIOD);
         Assert.assertTrue(future1.isDone());
-        LocalPoolEntry entry1 = t1.getEntry();
+        final LocalPoolEntry entry1 = t1.getEntry();
         Assert.assertNotNull(entry1);
         t2.join(GRACE_PERIOD);
         Assert.assertTrue(future2.isDone());
-        LocalPoolEntry entry2 = t2.getEntry();
+        final LocalPoolEntry entry2 = t2.getEntry();
         Assert.assertNotNull(entry2);
 
-        Future<LocalPoolEntry> future3 = pool.lease("otherhost", null);
-        GetPoolEntryThread t3 = new GetPoolEntryThread(future3);
+        final Future<LocalPoolEntry> future3 = pool.lease("otherhost", null);
+        final GetPoolEntryThread t3 = new GetPoolEntryThread(future3);
         t3.start();
-        Future<LocalPoolEntry> future4 = pool.lease("otherhost", null);
-        GetPoolEntryThread t4 = new GetPoolEntryThread(future4);
+        final Future<LocalPoolEntry> future4 = pool.lease("otherhost", null);
+        final GetPoolEntryThread t4 = new GetPoolEntryThread(future4);
         t4.start();
 
         Assert.assertFalse(t3.isDone());
@@ -377,11 +382,11 @@ public class TestConnPool {
 
         t3.join(GRACE_PERIOD);
         Assert.assertTrue(future3.isDone());
-        LocalPoolEntry entry3 = t3.getEntry();
+        final LocalPoolEntry entry3 = t3.getEntry();
         Assert.assertNotNull(entry3);
         t4.join(GRACE_PERIOD);
         Assert.assertTrue(future4.isDone());
-        LocalPoolEntry entry4 = t4.getEntry();
+        final LocalPoolEntry entry4 = t4.getEntry();
         Assert.assertNotNull(entry4);
 
         Mockito.verify(connFactory, Mockito.times(2)).create(Mockito.eq("somehost"));
@@ -391,11 +396,11 @@ public class TestConnPool {
         Assert.assertEquals(0, totals.getAvailable());
         Assert.assertEquals(2, totals.getLeased());
 
-        Future<LocalPoolEntry> future5 = pool.lease("somehost", null);
-        GetPoolEntryThread t5 = new GetPoolEntryThread(future5);
+        final Future<LocalPoolEntry> future5 = pool.lease("somehost", null);
+        final GetPoolEntryThread t5 = new GetPoolEntryThread(future5);
         t5.start();
-        Future<LocalPoolEntry> future6 = pool.lease("otherhost", null);
-        GetPoolEntryThread t6 = new GetPoolEntryThread(future6);
+        final Future<LocalPoolEntry> future6 = pool.lease("otherhost", null);
+        final GetPoolEntryThread t6 = new GetPoolEntryThread(future6);
         t6.start();
 
         pool.release(entry3, true);
@@ -403,11 +408,11 @@ public class TestConnPool {
 
         t5.join(GRACE_PERIOD);
         Assert.assertTrue(future5.isDone());
-        LocalPoolEntry entry5 = t5.getEntry();
+        final LocalPoolEntry entry5 = t5.getEntry();
         Assert.assertNotNull(entry5);
         t6.join(GRACE_PERIOD);
         Assert.assertTrue(future6.isDone());
-        LocalPoolEntry entry6 = t6.getEntry();
+        final LocalPoolEntry entry6 = t6.getEntry();
         Assert.assertNotNull(entry6);
 
         Mockito.verify(connFactory, Mockito.times(3)).create(Mockito.eq("somehost"));
@@ -427,36 +432,36 @@ public class TestConnPool {
 
     @Test
     public void testStatefulConnectionRedistributionOnPerRouteMaxLimit() throws Exception {
-        LocalConnFactory connFactory = Mockito.mock(LocalConnFactory.class);
+        final LocalConnFactory connFactory = Mockito.mock(LocalConnFactory.class);
 
-        HttpConnection conn1 = Mockito.mock(HttpConnection.class);
+        final HttpConnection conn1 = Mockito.mock(HttpConnection.class);
         Mockito.when(conn1.isOpen()).thenReturn(true);
-        HttpConnection conn2 = Mockito.mock(HttpConnection.class);
+        final HttpConnection conn2 = Mockito.mock(HttpConnection.class);
         Mockito.when(conn2.isOpen()).thenReturn(true);
-        HttpConnection conn3 = Mockito.mock(HttpConnection.class);
+        final HttpConnection conn3 = Mockito.mock(HttpConnection.class);
         Mockito.when(conn3.isOpen()).thenReturn(true);
         Mockito.when(connFactory.create(Mockito.eq("somehost"))).thenReturn(conn1, conn2, conn3);
 
-        LocalConnPool pool = new LocalConnPool(connFactory, 2, 10);
+        final LocalConnPool pool = new LocalConnPool(connFactory, 2, 10);
         pool.setMaxPerRoute("somehost", 2);
         pool.setMaxTotal(2);
 
-        Future<LocalPoolEntry> future1 = pool.lease("somehost", null);
-        GetPoolEntryThread t1 = new GetPoolEntryThread(future1);
+        final Future<LocalPoolEntry> future1 = pool.lease("somehost", null);
+        final GetPoolEntryThread t1 = new GetPoolEntryThread(future1);
         t1.start();
 
         t1.join(GRACE_PERIOD);
         Assert.assertTrue(future1.isDone());
-        LocalPoolEntry entry1 = t1.getEntry();
+        final LocalPoolEntry entry1 = t1.getEntry();
         Assert.assertNotNull(entry1);
 
-        Future<LocalPoolEntry> future2 = pool.lease("somehost", null);
-        GetPoolEntryThread t2 = new GetPoolEntryThread(future2);
+        final Future<LocalPoolEntry> future2 = pool.lease("somehost", null);
+        final GetPoolEntryThread t2 = new GetPoolEntryThread(future2);
         t2.start();
 
         t2.join(GRACE_PERIOD);
         Assert.assertTrue(future2.isDone());
-        LocalPoolEntry entry2 = t2.getEntry();
+        final LocalPoolEntry entry2 = t2.getEntry();
         Assert.assertNotNull(entry2);
 
         PoolStats totals = pool.getTotalStats();
@@ -471,13 +476,13 @@ public class TestConnPool {
 
         Mockito.verify(connFactory, Mockito.times(2)).create(Mockito.eq("somehost"));
 
-        Future<LocalPoolEntry> future3 = pool.lease("somehost", "some-other-stuff");
-        GetPoolEntryThread t3 = new GetPoolEntryThread(future3);
+        final Future<LocalPoolEntry> future3 = pool.lease("somehost", "some-other-stuff");
+        final GetPoolEntryThread t3 = new GetPoolEntryThread(future3);
         t3.start();
 
         t3.join(GRACE_PERIOD);
         Assert.assertTrue(future3.isDone());
-        LocalPoolEntry entry3 = t3.getEntry();
+        final LocalPoolEntry entry3 = t3.getEntry();
         Assert.assertNotNull(entry3);
 
         Mockito.verify(connFactory, Mockito.times(3)).create(Mockito.eq("somehost"));
@@ -493,16 +498,16 @@ public class TestConnPool {
 
     @Test
     public void testCreateNewIfExpired() throws Exception {
-        LocalConnFactory connFactory = Mockito.mock(LocalConnFactory.class);
+        final LocalConnFactory connFactory = Mockito.mock(LocalConnFactory.class);
 
-        HttpConnection conn1 = Mockito.mock(HttpConnection.class);
+        final HttpConnection conn1 = Mockito.mock(HttpConnection.class);
         Mockito.when(conn1.isOpen()).thenReturn(true);
         Mockito.when(connFactory.create(Mockito.eq("somehost"))).thenReturn(conn1);
 
-        LocalConnPool pool = new LocalConnPool(connFactory, 2, 2);
+        final LocalConnPool pool = new LocalConnPool(connFactory, 2, 2);
 
-        Future<LocalPoolEntry> future1 = pool.lease("somehost", null);
-        LocalPoolEntry entry1 = future1.get(1, TimeUnit.SECONDS);
+        final Future<LocalPoolEntry> future1 = pool.lease("somehost", null);
+        final LocalPoolEntry entry1 = future1.get(1, TimeUnit.SECONDS);
         Assert.assertNotNull(entry1);
 
         Mockito.verify(connFactory, Mockito.times(1)).create(Mockito.eq("somehost"));
@@ -512,38 +517,38 @@ public class TestConnPool {
 
         Thread.sleep(200L);
 
-        Future<LocalPoolEntry> future2 = pool.lease("somehost", null);
-        LocalPoolEntry entry2 = future2.get(1, TimeUnit.SECONDS);
+        final Future<LocalPoolEntry> future2 = pool.lease("somehost", null);
+        final LocalPoolEntry entry2 = future2.get(1, TimeUnit.SECONDS);
         Assert.assertNotNull(entry2);
 
         Mockito.verify(connFactory, Mockito.times(2)).create(Mockito.eq("somehost"));
 
-        PoolStats totals = pool.getTotalStats();
+        final PoolStats totals = pool.getTotalStats();
         Assert.assertEquals(0, totals.getAvailable());
         Assert.assertEquals(1, totals.getLeased());
-        PoolStats stats = pool.getStats("somehost");
+        final PoolStats stats = pool.getStats("somehost");
         Assert.assertEquals(0, stats.getAvailable());
         Assert.assertEquals(1, stats.getLeased());
     }
 
     @Test
     public void testCloseExpired() throws Exception {
-        LocalConnFactory connFactory = Mockito.mock(LocalConnFactory.class);
+        final LocalConnFactory connFactory = Mockito.mock(LocalConnFactory.class);
 
-        HttpConnection conn1 = Mockito.mock(HttpConnection.class);
+        final HttpConnection conn1 = Mockito.mock(HttpConnection.class);
         Mockito.when(conn1.isOpen()).thenReturn(Boolean.FALSE);
-        HttpConnection conn2 = Mockito.mock(HttpConnection.class);
+        final HttpConnection conn2 = Mockito.mock(HttpConnection.class);
         Mockito.when(conn2.isOpen()).thenReturn(Boolean.TRUE);
 
         Mockito.when(connFactory.create(Mockito.eq("somehost"))).thenReturn(conn1, conn2);
 
-        LocalConnPool pool = new LocalConnPool(connFactory, 2, 2);
+        final LocalConnPool pool = new LocalConnPool(connFactory, 2, 2);
 
-        Future<LocalPoolEntry> future1 = pool.lease("somehost", null);
-        LocalPoolEntry entry1 = future1.get(1, TimeUnit.SECONDS);
+        final Future<LocalPoolEntry> future1 = pool.lease("somehost", null);
+        final LocalPoolEntry entry1 = future1.get(1, TimeUnit.SECONDS);
         Assert.assertNotNull(entry1);
-        Future<LocalPoolEntry> future2 = pool.lease("somehost", null);
-        LocalPoolEntry entry2 = future2.get(1, TimeUnit.SECONDS);
+        final Future<LocalPoolEntry> future2 = pool.lease("somehost", null);
+        final LocalPoolEntry entry2 = future2.get(1, TimeUnit.SECONDS);
         Assert.assertNotNull(entry2);
 
         entry1.updateExpiry(1, TimeUnit.MILLISECONDS);
@@ -559,35 +564,35 @@ public class TestConnPool {
         Mockito.verify(conn1).close();
         Mockito.verify(conn2, Mockito.never()).close();
 
-        PoolStats totals = pool.getTotalStats();
+        final PoolStats totals = pool.getTotalStats();
         Assert.assertEquals(1, totals.getAvailable());
         Assert.assertEquals(0, totals.getLeased());
-        PoolStats stats = pool.getStats("somehost");
+        final PoolStats stats = pool.getStats("somehost");
         Assert.assertEquals(1, stats.getAvailable());
         Assert.assertEquals(0, stats.getLeased());
     }
 
     @Test
     public void testLeaseTimeout() throws Exception {
-        LocalConnFactory connFactory = Mockito.mock(LocalConnFactory.class);
+        final LocalConnFactory connFactory = Mockito.mock(LocalConnFactory.class);
 
-        HttpConnection conn1 = Mockito.mock(HttpConnection.class);
+        final HttpConnection conn1 = Mockito.mock(HttpConnection.class);
         Mockito.when(conn1.isOpen()).thenReturn(true);
         Mockito.when(connFactory.create(Mockito.eq("somehost"))).thenReturn(conn1);
 
-        LocalConnPool pool = new LocalConnPool(connFactory, 1, 1);
+        final LocalConnPool pool = new LocalConnPool(connFactory, 1, 1);
 
-        Future<LocalPoolEntry> future1 = pool.lease("somehost", null);
-        GetPoolEntryThread t1 = new GetPoolEntryThread(future1);
+        final Future<LocalPoolEntry> future1 = pool.lease("somehost", null);
+        final GetPoolEntryThread t1 = new GetPoolEntryThread(future1);
         t1.start();
 
         t1.join(GRACE_PERIOD);
         Assert.assertTrue(future1.isDone());
-        LocalPoolEntry entry1 = t1.getEntry();
+        final LocalPoolEntry entry1 = t1.getEntry();
         Assert.assertNotNull(entry1);
 
-        Future<LocalPoolEntry> future2 = pool.lease("somehost", null);
-        GetPoolEntryThread t2 = new GetPoolEntryThread(future2, 50, TimeUnit.MICROSECONDS);
+        final Future<LocalPoolEntry> future2 = pool.lease("somehost", null);
+        final GetPoolEntryThread t2 = new GetPoolEntryThread(future2, 50, TimeUnit.MICROSECONDS);
         t2.start();
 
         t2.join(GRACE_PERIOD);
@@ -598,13 +603,13 @@ public class TestConnPool {
 
     @Test
     public void testLeaseIOException() throws Exception {
-        LocalConnFactory connFactory = Mockito.mock(LocalConnFactory.class);
+        final LocalConnFactory connFactory = Mockito.mock(LocalConnFactory.class);
         Mockito.doThrow(new IOException("Oppsie")).when(connFactory).create("somehost");
 
-        LocalConnPool pool = new LocalConnPool(connFactory, 2, 10);
+        final LocalConnPool pool = new LocalConnPool(connFactory, 2, 10);
 
-        Future<LocalPoolEntry> future1 = pool.lease("somehost", null);
-        GetPoolEntryThread t1 = new GetPoolEntryThread(future1);
+        final Future<LocalPoolEntry> future1 = pool.lease("somehost", null);
+        final GetPoolEntryThread t1 = new GetPoolEntryThread(future1);
         t1.start();
 
         t1.join(GRACE_PERIOD);
@@ -616,25 +621,25 @@ public class TestConnPool {
 
     @Test
     public void testLeaseCancel() throws Exception {
-        LocalConnFactory connFactory = Mockito.mock(LocalConnFactory.class);
+        final LocalConnFactory connFactory = Mockito.mock(LocalConnFactory.class);
 
-        HttpConnection conn1 = Mockito.mock(HttpConnection.class);
+        final HttpConnection conn1 = Mockito.mock(HttpConnection.class);
         Mockito.when(conn1.isOpen()).thenReturn(true);
         Mockito.when(connFactory.create(Mockito.eq("somehost"))).thenReturn(conn1);
 
-        LocalConnPool pool = new LocalConnPool(connFactory, 1, 1);
+        final LocalConnPool pool = new LocalConnPool(connFactory, 1, 1);
 
-        Future<LocalPoolEntry> future1 = pool.lease("somehost", null);
-        GetPoolEntryThread t1 = new GetPoolEntryThread(future1);
+        final Future<LocalPoolEntry> future1 = pool.lease("somehost", null);
+        final GetPoolEntryThread t1 = new GetPoolEntryThread(future1);
         t1.start();
 
         t1.join(GRACE_PERIOD);
         Assert.assertTrue(future1.isDone());
-        LocalPoolEntry entry1 = t1.getEntry();
+        final LocalPoolEntry entry1 = t1.getEntry();
         Assert.assertNotNull(entry1);
 
-        Future<LocalPoolEntry> future2 = pool.lease("somehost", null);
-        GetPoolEntryThread t2 = new GetPoolEntryThread(future2);
+        final Future<LocalPoolEntry> future2 = pool.lease("somehost", null);
+        final GetPoolEntryThread t2 = new GetPoolEntryThread(future2);
         t2.start();
 
         Thread.sleep(5);
@@ -652,22 +657,22 @@ public class TestConnPool {
 
     @Test
     public void testCloseIdle() throws Exception {
-        LocalConnFactory connFactory = Mockito.mock(LocalConnFactory.class);
+        final LocalConnFactory connFactory = Mockito.mock(LocalConnFactory.class);
 
-        HttpConnection conn1 = Mockito.mock(HttpConnection.class);
+        final HttpConnection conn1 = Mockito.mock(HttpConnection.class);
         Mockito.when(conn1.isOpen()).thenReturn(true);
-        HttpConnection conn2 = Mockito.mock(HttpConnection.class);
+        final HttpConnection conn2 = Mockito.mock(HttpConnection.class);
         Mockito.when(conn2.isOpen()).thenReturn(true);
 
         Mockito.when(connFactory.create(Mockito.eq("somehost"))).thenReturn(conn1, conn2);
 
-        LocalConnPool pool = new LocalConnPool(connFactory, 2, 2);
+        final LocalConnPool pool = new LocalConnPool(connFactory, 2, 2);
 
-        Future<LocalPoolEntry> future1 = pool.lease("somehost", null);
-        LocalPoolEntry entry1 = future1.get(1, TimeUnit.SECONDS);
+        final Future<LocalPoolEntry> future1 = pool.lease("somehost", null);
+        final LocalPoolEntry entry1 = future1.get(1, TimeUnit.SECONDS);
         Assert.assertNotNull(entry1);
-        Future<LocalPoolEntry> future2 = pool.lease("somehost", null);
-        LocalPoolEntry entry2 = future2.get(1, TimeUnit.SECONDS);
+        final Future<LocalPoolEntry> future2 = pool.lease("somehost", null);
+        final LocalPoolEntry entry2 = future2.get(1, TimeUnit.SECONDS);
         Assert.assertNotNull(entry2);
 
         entry1.updateExpiry(0, TimeUnit.MILLISECONDS);
@@ -704,66 +709,66 @@ public class TestConnPool {
 
     @Test(expected=IllegalArgumentException.class)
     public void testCloseIdleInvalid() throws Exception {
-        LocalConnFactory connFactory = Mockito.mock(LocalConnFactory.class);
-        LocalConnPool pool = new LocalConnPool(connFactory, 2, 2);
+        final LocalConnFactory connFactory = Mockito.mock(LocalConnFactory.class);
+        final LocalConnPool pool = new LocalConnPool(connFactory, 2, 2);
         pool.closeIdle(50, null);
     }
 
     @Test(expected=IllegalArgumentException.class)
     public void testGetStatsInvalid() throws Exception {
-        LocalConnFactory connFactory = Mockito.mock(LocalConnFactory.class);
-        LocalConnPool pool = new LocalConnPool(connFactory, 2, 2);
+        final LocalConnFactory connFactory = Mockito.mock(LocalConnFactory.class);
+        final LocalConnPool pool = new LocalConnPool(connFactory, 2, 2);
         pool.getStats(null);
     }
 
     @Test
     public void testSetMaxInvalid() throws Exception {
-        LocalConnFactory connFactory = Mockito.mock(LocalConnFactory.class);
-        LocalConnPool pool = new LocalConnPool(connFactory, 2, 2);
+        final LocalConnFactory connFactory = Mockito.mock(LocalConnFactory.class);
+        final LocalConnPool pool = new LocalConnPool(connFactory, 2, 2);
         try {
             pool.setMaxTotal(-1);
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException expected) {
+        } catch (final IllegalArgumentException expected) {
         }
         try {
             pool.setMaxPerRoute(null, 1);
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException expected) {
+        } catch (final IllegalArgumentException expected) {
         }
         try {
             pool.setMaxPerRoute("somehost", -1);
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException expected) {
+        } catch (final IllegalArgumentException expected) {
         }
         try {
             pool.setDefaultMaxPerRoute(-1);
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException expected) {
+        } catch (final IllegalArgumentException expected) {
         }
     }
 
     @Test
     public void testShutdown() throws Exception {
-        LocalConnFactory connFactory = Mockito.mock(LocalConnFactory.class);
+        final LocalConnFactory connFactory = Mockito.mock(LocalConnFactory.class);
 
-        HttpConnection conn1 = Mockito.mock(HttpConnection.class);
+        final HttpConnection conn1 = Mockito.mock(HttpConnection.class);
         Mockito.when(conn1.isOpen()).thenReturn(true);
         Mockito.when(connFactory.create(Mockito.eq("somehost"))).thenReturn(conn1);
-        HttpConnection conn2 = Mockito.mock(HttpConnection.class);
+        final HttpConnection conn2 = Mockito.mock(HttpConnection.class);
         Mockito.when(conn2.isOpen()).thenReturn(true);
         Mockito.when(connFactory.create(Mockito.eq("otherhost"))).thenReturn(conn2);
 
-        LocalConnPool pool = new LocalConnPool(connFactory, 2, 2);
-        Future<LocalPoolEntry> future1 = pool.lease("somehost", null);
-        LocalPoolEntry entry1 = future1.get(1, TimeUnit.SECONDS);
+        final LocalConnPool pool = new LocalConnPool(connFactory, 2, 2);
+        final Future<LocalPoolEntry> future1 = pool.lease("somehost", null);
+        final LocalPoolEntry entry1 = future1.get(1, TimeUnit.SECONDS);
         Assert.assertNotNull(entry1);
-        Future<LocalPoolEntry> future2 = pool.lease("otherhost", null);
-        LocalPoolEntry entry2 = future2.get(1, TimeUnit.SECONDS);
+        final Future<LocalPoolEntry> future2 = pool.lease("otherhost", null);
+        final LocalPoolEntry entry2 = future2.get(1, TimeUnit.SECONDS);
         Assert.assertNotNull(entry2);
 
         pool.release(entry2, true);
 
-        PoolStats totals = pool.getTotalStats();
+        final PoolStats totals = pool.getTotalStats();
         Assert.assertEquals(1, totals.getAvailable());
         Assert.assertEquals(1, totals.getLeased());
 
@@ -778,7 +783,7 @@ public class TestConnPool {
         try {
             pool.lease("somehost", null);
             Assert.fail("IllegalStateException should have been thrown");
-        } catch (IllegalStateException expected) {
+        } catch (final IllegalStateException expected) {
         }
         // Ignored if shut down
         pool.release(new LocalPoolEntry("somehost", Mockito.mock(HttpConnection.class)), true);
diff --git a/httpcore/src/test/java/org/apache/http/pool/TestPoolEntry.java b/httpcore/src/test/java/org/apache/http/pool/TestPoolEntry.java
index eeac63f..fb558b9 100644
--- a/httpcore/src/test/java/org/apache/http/pool/TestPoolEntry.java
+++ b/httpcore/src/test/java/org/apache/http/pool/TestPoolEntry.java
@@ -29,9 +29,8 @@ package org.apache.http.pool;
 import java.io.IOException;
 import java.util.concurrent.TimeUnit;
 
-import junit.framework.Assert;
-
 import org.apache.http.HttpConnection;
+import org.junit.Assert;
 import org.junit.Test;
 import org.mockito.Mockito;
 
@@ -40,12 +39,12 @@ public class TestPoolEntry {
     static class MockPoolEntry extends PoolEntry<String, HttpConnection> {
 
         public MockPoolEntry(final String route,
-                long timeToLive, final TimeUnit tunit) {
+                final long timeToLive, final TimeUnit tunit) {
             super(null, route, Mockito.mock(HttpConnection.class), timeToLive, tunit);
         }
 
         public MockPoolEntry(final String route, final HttpConnection conn,
-                long timeToLive, final TimeUnit tunit) {
+                final long timeToLive, final TimeUnit tunit) {
             super(null, route, conn, timeToLive, tunit);
         }
 
@@ -53,7 +52,7 @@ public class TestPoolEntry {
         public void close() {
             try {
                 getConnection().close();
-            } catch (IOException ignore) {
+            } catch (final IOException ignore) {
             }
         }
 
@@ -66,8 +65,8 @@ public class TestPoolEntry {
 
     @Test
     public void testBasics() throws Exception {
-        MockPoolEntry entry1 = new MockPoolEntry("route1", 10L, TimeUnit.MILLISECONDS);
-        long now = System.currentTimeMillis();
+        final MockPoolEntry entry1 = new MockPoolEntry("route1", 10L, TimeUnit.MILLISECONDS);
+        final long now = System.currentTimeMillis();
         Assert.assertEquals("route1", entry1.getRoute());
         Assert.assertTrue(now >= entry1.getCreated());
         Assert.assertEquals(entry1.getValidUnit(), entry1.getExpiry());
@@ -79,37 +78,37 @@ public class TestPoolEntry {
         try {
             new MockPoolEntry(null, Mockito.mock(HttpConnection.class), 0L, TimeUnit.MILLISECONDS);
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException expected) {
+        } catch (final IllegalArgumentException expected) {
         }
         try {
             new MockPoolEntry("stuff", null, 0L, TimeUnit.MILLISECONDS);
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException expected) {
+        } catch (final IllegalArgumentException expected) {
         }
         try {
             new MockPoolEntry("stuff", Mockito.mock(HttpConnection.class), 0L, null);
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException expected) {
+        } catch (final IllegalArgumentException expected) {
         }
     }
 
     @Test
     public void testValidInfinitely() throws Exception {
-        MockPoolEntry entry1 = new MockPoolEntry("route1", 0L, TimeUnit.MILLISECONDS);
+        final MockPoolEntry entry1 = new MockPoolEntry("route1", 0L, TimeUnit.MILLISECONDS);
         Assert.assertEquals(Long.MAX_VALUE, entry1.getValidUnit());
         Assert.assertEquals(entry1.getValidUnit(), entry1.getExpiry());
     }
 
     @Test
     public void testExpiry() throws Exception {
-        MockPoolEntry entry1 = new MockPoolEntry("route1", 0L, TimeUnit.MILLISECONDS);
+        final MockPoolEntry entry1 = new MockPoolEntry("route1", 0L, TimeUnit.MILLISECONDS);
         Assert.assertEquals(Long.MAX_VALUE, entry1.getExpiry());
         entry1.updateExpiry(50L, TimeUnit.MILLISECONDS);
         Assert.assertEquals(entry1.getUpdated() + 50L, entry1.getExpiry());
         entry1.updateExpiry(0L, TimeUnit.MILLISECONDS);
         Assert.assertEquals(Long.MAX_VALUE, entry1.getExpiry());
 
-        MockPoolEntry entry2 = new MockPoolEntry("route1", 100L, TimeUnit.MILLISECONDS);
+        final MockPoolEntry entry2 = new MockPoolEntry("route1", 100L, TimeUnit.MILLISECONDS);
         Assert.assertEquals(entry2.getCreated() + 100L, entry2.getExpiry());
         entry2.updateExpiry(150L, TimeUnit.MILLISECONDS);
         Assert.assertEquals(entry2.getCreated() + 100L, entry2.getExpiry());
@@ -119,7 +118,7 @@ public class TestPoolEntry {
 
     @Test(expected=IllegalArgumentException.class)
     public void testInvalidExpiry() throws Exception {
-        MockPoolEntry entry1 = new MockPoolEntry("route1", 0L, TimeUnit.MILLISECONDS);
+        final MockPoolEntry entry1 = new MockPoolEntry("route1", 0L, TimeUnit.MILLISECONDS);
         entry1.updateExpiry(50L, null);
     }
 
diff --git a/httpcore/src/test/java/org/apache/http/pool/TestRouteSpecificPool.java b/httpcore/src/test/java/org/apache/http/pool/TestRouteSpecificPool.java
index b515ff8..1f150d1 100644
--- a/httpcore/src/test/java/org/apache/http/pool/TestRouteSpecificPool.java
+++ b/httpcore/src/test/java/org/apache/http/pool/TestRouteSpecificPool.java
@@ -28,9 +28,8 @@ package org.apache.http.pool;
 
 import java.io.IOException;
 
-import junit.framework.Assert;
-
 import org.apache.http.HttpConnection;
+import org.junit.Assert;
 import org.junit.Test;
 import org.mockito.Mockito;
 
@@ -48,7 +47,7 @@ public class TestRouteSpecificPool {
         public void close() {
             try {
                 getConnection().close();
-            } catch (IOException ignore) {
+            } catch (final IOException ignore) {
             }
         }
 
@@ -74,7 +73,7 @@ public class TestRouteSpecificPool {
 
     @Test
     public void testEmptyPool() throws Exception {
-        LocalRoutePool pool = new LocalRoutePool();
+        final LocalRoutePool pool = new LocalRoutePool();
         Assert.assertEquals(ROUTE, pool.getRoute());
         Assert.assertEquals(0, pool.getAllocatedCount());
         Assert.assertEquals(0, pool.getAvailableCount());
@@ -86,9 +85,9 @@ public class TestRouteSpecificPool {
 
     @Test
     public void testAdd() throws Exception {
-        LocalRoutePool pool = new LocalRoutePool();
-        HttpConnection conn = Mockito.mock(HttpConnection.class);
-        PoolEntry<String, HttpConnection> entry = pool.add(conn);
+        final LocalRoutePool pool = new LocalRoutePool();
+        final HttpConnection conn = Mockito.mock(HttpConnection.class);
+        final PoolEntry<String, HttpConnection> entry = pool.add(conn);
         Assert.assertEquals(1, pool.getAllocatedCount());
         Assert.assertEquals(0, pool.getAvailableCount());
         Assert.assertEquals(1, pool.getLeasedCount());
@@ -99,13 +98,13 @@ public class TestRouteSpecificPool {
 
     @Test
     public void testLeaseRelease() throws Exception {
-        LocalRoutePool pool = new LocalRoutePool();
-        HttpConnection conn1 = Mockito.mock(HttpConnection.class);
-        LocalPoolEntry entry1 = pool.add(conn1);
-        HttpConnection conn2 = Mockito.mock(HttpConnection.class);
-        LocalPoolEntry entry2 = pool.add(conn2);
-        HttpConnection conn3 = Mockito.mock(HttpConnection.class);
-        LocalPoolEntry entry3 = pool.add(conn3);
+        final LocalRoutePool pool = new LocalRoutePool();
+        final HttpConnection conn1 = Mockito.mock(HttpConnection.class);
+        final LocalPoolEntry entry1 = pool.add(conn1);
+        final HttpConnection conn2 = Mockito.mock(HttpConnection.class);
+        final LocalPoolEntry entry2 = pool.add(conn2);
+        final HttpConnection conn3 = Mockito.mock(HttpConnection.class);
+        final LocalPoolEntry entry3 = pool.add(conn3);
 
         Assert.assertNotNull(entry1);
         Assert.assertNotNull(entry2);
@@ -139,13 +138,13 @@ public class TestRouteSpecificPool {
 
     @Test
     public void testLeaseOrder() throws Exception {
-        LocalRoutePool pool = new LocalRoutePool();
-        HttpConnection conn1 = Mockito.mock(HttpConnection.class);
-        LocalPoolEntry entry1 = pool.add(conn1);
-        HttpConnection conn2 = Mockito.mock(HttpConnection.class);
-        LocalPoolEntry entry2 = pool.add(conn2);
-        HttpConnection conn3 = Mockito.mock(HttpConnection.class);
-        LocalPoolEntry entry3 = pool.add(conn3);
+        final LocalRoutePool pool = new LocalRoutePool();
+        final HttpConnection conn1 = Mockito.mock(HttpConnection.class);
+        final LocalPoolEntry entry1 = pool.add(conn1);
+        final HttpConnection conn2 = Mockito.mock(HttpConnection.class);
+        final LocalPoolEntry entry2 = pool.add(conn2);
+        final HttpConnection conn3 = Mockito.mock(HttpConnection.class);
+        final LocalPoolEntry entry3 = pool.add(conn3);
 
         Assert.assertNotNull(entry1);
         Assert.assertNotNull(entry2);
@@ -169,13 +168,13 @@ public class TestRouteSpecificPool {
 
     @Test
     public void testLeaseReleaseStateful() throws Exception {
-        LocalRoutePool pool = new LocalRoutePool();
-        HttpConnection conn1 = Mockito.mock(HttpConnection.class);
-        LocalPoolEntry entry1 = pool.add(conn1);
-        HttpConnection conn2 = Mockito.mock(HttpConnection.class);
-        LocalPoolEntry entry2 = pool.add(conn2);
-        HttpConnection conn3 = Mockito.mock(HttpConnection.class);
-        LocalPoolEntry entry3 = pool.add(conn3);
+        final LocalRoutePool pool = new LocalRoutePool();
+        final HttpConnection conn1 = Mockito.mock(HttpConnection.class);
+        final LocalPoolEntry entry1 = pool.add(conn1);
+        final HttpConnection conn2 = Mockito.mock(HttpConnection.class);
+        final LocalPoolEntry entry2 = pool.add(conn2);
+        final HttpConnection conn3 = Mockito.mock(HttpConnection.class);
+        final LocalPoolEntry entry3 = pool.add(conn3);
 
         Assert.assertNotNull(entry1);
         Assert.assertNotNull(entry2);
@@ -213,21 +212,21 @@ public class TestRouteSpecificPool {
 
     @Test(expected=IllegalStateException.class)
     public void testReleaseInvalidEntry() throws Exception {
-        LocalRoutePool pool = new LocalRoutePool();
-        HttpConnection conn = Mockito.mock(HttpConnection.class);
-        LocalPoolEntry entry = new LocalPoolEntry(ROUTE, conn);
+        final LocalRoutePool pool = new LocalRoutePool();
+        final HttpConnection conn = Mockito.mock(HttpConnection.class);
+        final LocalPoolEntry entry = new LocalPoolEntry(ROUTE, conn);
         pool.free(entry, true);
     }
 
     @Test
     public void testRemove() throws Exception {
-        LocalRoutePool pool = new LocalRoutePool();
-        HttpConnection conn1 = Mockito.mock(HttpConnection.class);
-        LocalPoolEntry entry1 = pool.add(conn1);
-        HttpConnection conn2 = Mockito.mock(HttpConnection.class);
-        LocalPoolEntry entry2 = pool.add(conn2);
-        HttpConnection conn3 = Mockito.mock(HttpConnection.class);
-        LocalPoolEntry entry3 = pool.add(conn3);
+        final LocalRoutePool pool = new LocalRoutePool();
+        final HttpConnection conn1 = Mockito.mock(HttpConnection.class);
+        final LocalPoolEntry entry1 = pool.add(conn1);
+        final HttpConnection conn2 = Mockito.mock(HttpConnection.class);
+        final LocalPoolEntry entry2 = pool.add(conn2);
+        final HttpConnection conn3 = Mockito.mock(HttpConnection.class);
+        final LocalPoolEntry entry3 = pool.add(conn3);
 
         Assert.assertNotNull(entry1);
         Assert.assertNotNull(entry2);
@@ -265,22 +264,22 @@ public class TestRouteSpecificPool {
 
     @Test(expected=IllegalArgumentException.class)
     public void testReleaseInvalid() throws Exception {
-        LocalRoutePool pool = new LocalRoutePool();
+        final LocalRoutePool pool = new LocalRoutePool();
         pool.free(null, true);
     }
 
     @Test(expected=IllegalArgumentException.class)
     public void testRemoveInvalid() throws Exception {
-        LocalRoutePool pool = new LocalRoutePool();
+        final LocalRoutePool pool = new LocalRoutePool();
         pool.remove(null);
     }
 
     @SuppressWarnings("unchecked")
     @Test
     public void testWaitingThreadQueuing() throws Exception {
-        LocalRoutePool pool = new LocalRoutePool();
-        PoolEntryFuture<LocalPoolEntry> future1 = Mockito.mock(PoolEntryFuture.class);
-        PoolEntryFuture<LocalPoolEntry> future2 = Mockito.mock(PoolEntryFuture.class);
+        final LocalRoutePool pool = new LocalRoutePool();
+        final PoolEntryFuture<LocalPoolEntry> future1 = Mockito.mock(PoolEntryFuture.class);
+        final PoolEntryFuture<LocalPoolEntry> future2 = Mockito.mock(PoolEntryFuture.class);
 
         Assert.assertEquals(0, pool.getPendingCount());
         pool.queue(future1);
@@ -302,13 +301,13 @@ public class TestRouteSpecificPool {
     @SuppressWarnings("unchecked")
     @Test
     public void testShutdown() throws Exception {
-        LocalRoutePool pool = new LocalRoutePool();
-        HttpConnection conn1 = Mockito.mock(HttpConnection.class);
-        LocalPoolEntry entry1 = pool.add(conn1);
-        HttpConnection conn2 = Mockito.mock(HttpConnection.class);
-        LocalPoolEntry entry2 = pool.add(conn2);
+        final LocalRoutePool pool = new LocalRoutePool();
+        final HttpConnection conn1 = Mockito.mock(HttpConnection.class);
+        final LocalPoolEntry entry1 = pool.add(conn1);
+        final HttpConnection conn2 = Mockito.mock(HttpConnection.class);
+        final LocalPoolEntry entry2 = pool.add(conn2);
 
-        PoolEntryFuture<LocalPoolEntry> future1 = Mockito.mock(PoolEntryFuture.class);
+        final PoolEntryFuture<LocalPoolEntry> future1 = Mockito.mock(PoolEntryFuture.class);
         pool.queue(future1);
 
         Assert.assertNotNull(entry1);
diff --git a/httpcore/src/test/java/org/apache/http/protocol/TestBasicHttpProcessor.java b/httpcore/src/test/java/org/apache/http/protocol/TestBasicHttpProcessor.java
deleted file mode 100644
index bc9ad46..0000000
--- a/httpcore/src/test/java/org/apache/http/protocol/TestBasicHttpProcessor.java
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * ====================================================================
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- *
- */
-
-package org.apache.http.protocol;
-
-import java.io.IOException;
-
-import org.apache.http.HttpException;
-import org.apache.http.HttpRequest;
-import org.apache.http.HttpRequestInterceptor;
-import org.junit.Assert;
-import org.junit.Test;
-
-public class TestBasicHttpProcessor {
-
-    static class TestHttpRequestInterceptorPlaceHolder implements HttpRequestInterceptor {
-
-        public void process(
-                HttpRequest request,
-                HttpContext context) throws HttpException, IOException {
-        }
-    }
-
-    @Test
-    public void testAddFirstRequestInterceptorNull() {
-        HttpRequestInterceptor itcp = null;
-        BasicHttpProcessor instance = new BasicHttpProcessor();
-
-        instance.addRequestInterceptor(itcp, 0);
-        int itcpCount = instance.getRequestInterceptorCount();
-        Assert.assertEquals(0, itcpCount);
-        Assert.assertEquals(null, instance.getRequestInterceptor(0));
-    }
-
-    @Test
-    public void testAddFirstRequestInterceptor() {
-        HttpRequestInterceptor itcp1 = new TestHttpRequestInterceptorPlaceHolder();
-        HttpRequestInterceptor itcp2 = new TestHttpRequestInterceptorPlaceHolder();
-        BasicHttpProcessor instance = new BasicHttpProcessor();
-
-        Assert.assertEquals(0, instance.getRequestInterceptorCount());
-        instance.addRequestInterceptor(itcp1);
-        Assert.assertEquals(1, instance.getRequestInterceptorCount());
-        Assert.assertSame(itcp1, instance.getRequestInterceptor(0));
-
-        instance.addRequestInterceptor(itcp2, 0);
-        Assert.assertEquals(2, instance.getRequestInterceptorCount());
-        Assert.assertSame(itcp2, instance.getRequestInterceptor(0));
-        Assert.assertSame(itcp1, instance.getRequestInterceptor(1));
-    }
-
-    @Test
-    public void testAddTailRequestInterceptorNull() {
-        HttpRequestInterceptor itcp = null;
-        BasicHttpProcessor instance = new BasicHttpProcessor();
-
-        instance.addRequestInterceptor(itcp, 0);
-        int itcpCount = instance.getRequestInterceptorCount();
-        Assert.assertEquals(0, itcpCount);
-        Assert.assertEquals(null, instance.getRequestInterceptor(itcpCount - 1));
-    }
-
-    @Test
-    public void testAddTailRequestInterceptor() {
-        HttpRequestInterceptor itcp1 = new TestHttpRequestInterceptorPlaceHolder();
-        HttpRequestInterceptor itcp2 = new TestHttpRequestInterceptorPlaceHolder();
-        BasicHttpProcessor instance = new BasicHttpProcessor();
-
-        instance.addRequestInterceptor(itcp1);
-        Assert.assertEquals(1, instance.getRequestInterceptorCount());
-        Assert.assertSame(itcp1, instance.getRequestInterceptor(0));
-
-        instance.addRequestInterceptor(itcp2, 1);
-        int itcpCount = instance.getRequestInterceptorCount();
-        Assert.assertEquals(2, itcpCount);
-        Assert.assertSame(itcp1, instance.getRequestInterceptor(0));
-        Assert.assertSame(itcp2, instance.getRequestInterceptor(itcpCount - 1));
-    }
-
-    @Test
-    public void testClearByClass() {
-        // remove a present class
-        HttpRequestInterceptor itcp1 = new TestHttpRequestInterceptorPlaceHolder();
-        HttpRequestInterceptor itcp2 = new TestHttpRequestInterceptorPlaceHolder();
-        HttpRequestInterceptor itcp3 = new HttpRequestInterceptor() {
-
-            public void process(
-                    HttpRequest request,
-                    HttpContext context) throws HttpException, IOException {
-            }
-
-        };
-        BasicHttpProcessor instance = new BasicHttpProcessor();
-        instance.addRequestInterceptor(itcp1);
-        instance.addRequestInterceptor(itcp2);
-        instance.addRequestInterceptor(itcp3);
-        instance.removeRequestInterceptorByClass(itcp1.getClass());
-        Assert.assertEquals(1, instance.getRequestInterceptorCount());
-        instance.removeRequestInterceptorByClass(itcp3.getClass());
-        Assert.assertEquals(0, instance.getRequestInterceptorCount());
-    }
-
-}
diff --git a/httpcore/src/test/java/org/apache/http/protocol/TestChainBuilder.java b/httpcore/src/test/java/org/apache/http/protocol/TestChainBuilder.java
new file mode 100644
index 0000000..199790c
--- /dev/null
+++ b/httpcore/src/test/java/org/apache/http/protocol/TestChainBuilder.java
@@ -0,0 +1,67 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+
+package org.apache.http.protocol;
+
+import java.util.LinkedList;
+import java.util.List;
+
+import org.apache.http.HttpRequestInterceptor;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class TestChainBuilder {
+
+    @Test
+    public void testBuildChain() throws Exception {
+        final ChainBuilder<HttpRequestInterceptor> cb = new ChainBuilder<HttpRequestInterceptor>();
+        final HttpRequestInterceptor i1 = new RequestContent();
+        final HttpRequestInterceptor i2 = new RequestTargetHost();
+        final HttpRequestInterceptor i3 = new RequestConnControl();
+        final HttpRequestInterceptor i4 = new RequestUserAgent();
+        final HttpRequestInterceptor i5 = new RequestExpectContinue(true);
+        cb.addFirst(i1);
+        cb.addAllFirst(i2, i3);
+        cb.addFirst(null);
+        cb.addAllFirst((List<HttpRequestInterceptor>) null);
+        cb.addLast(i4);
+        cb.addLast(null);
+        cb.addAllLast(i5);
+        cb.addAllLast((List<HttpRequestInterceptor>) null);
+        cb.addFirst(i1);
+        cb.addAllLast(i3, i4, i5);
+        final LinkedList<HttpRequestInterceptor> list = cb.build();
+        Assert.assertNotNull(list);
+        Assert.assertEquals(5, list.size());
+        Assert.assertSame(i1, list.get(0));
+        Assert.assertSame(i2, list.get(1));
+        Assert.assertSame(i3, list.get(2));
+        Assert.assertSame(i4, list.get(3));
+        Assert.assertSame(i5, list.get(4));
+    }
+
+}
diff --git a/httpcore/src/test/java/org/apache/http/protocol/TestHttpExecutionContext.java b/httpcore/src/test/java/org/apache/http/protocol/TestHttpExecutionContext.java
index 49664c7..029c851 100644
--- a/httpcore/src/test/java/org/apache/http/protocol/TestHttpExecutionContext.java
+++ b/httpcore/src/test/java/org/apache/http/protocol/TestHttpExecutionContext.java
@@ -36,8 +36,8 @@ public class TestHttpExecutionContext {
 
     @Test
     public void testContextOperations() {
-        HttpContext parentContext = new BasicHttpContext(null);
-        HttpContext currentContext = new BasicHttpContext(parentContext);
+        final HttpContext parentContext = new BasicHttpContext(null);
+        final HttpContext currentContext = new BasicHttpContext(parentContext);
 
         parentContext.setAttribute("param1", "1");
         parentContext.setAttribute("param2", "2");
@@ -66,7 +66,7 @@ public class TestHttpExecutionContext {
 
     @Test
     public void testEmptyContextOperations() {
-        HttpContext currentContext = new BasicHttpContext(null);
+        final HttpContext currentContext = new BasicHttpContext(null);
         Assert.assertEquals(null, currentContext.getAttribute("param1"));
         currentContext.removeAttribute("param1");
         Assert.assertEquals(null, currentContext.getAttribute("param1"));
@@ -74,23 +74,23 @@ public class TestHttpExecutionContext {
 
     @Test
     public void testContextInvalidInput() throws Exception {
-        HttpContext currentContext = new BasicHttpContext(null);
+        final HttpContext currentContext = new BasicHttpContext(null);
         try {
             currentContext.setAttribute(null, null);
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
             // expected
         }
         try {
             currentContext.getAttribute(null);
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
             // expected
         }
         try {
             currentContext.removeAttribute(null);
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
             // expected
         }
     }
diff --git a/httpcore/src/test/java/org/apache/http/protocol/TestHttpRequestExecutor.java b/httpcore/src/test/java/org/apache/http/protocol/TestHttpRequestExecutor.java
index 176bd85..8370c2a 100644
--- a/httpcore/src/test/java/org/apache/http/protocol/TestHttpRequestExecutor.java
+++ b/httpcore/src/test/java/org/apache/http/protocol/TestHttpRequestExecutor.java
@@ -48,115 +48,115 @@ public class TestHttpRequestExecutor {
 
     @Test
     public void testInvalidInput() throws Exception {
-        HttpContext context = new BasicHttpContext();
-        HttpRequest request = new BasicHttpRequest("GET", "/");
-        HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
-        HttpClientConnection conn = Mockito.mock(HttpClientConnection.class);
-        HttpProcessor httprocessor = Mockito.mock(HttpProcessor.class);
+        final HttpCoreContext context = HttpCoreContext.create();
+        final HttpRequest request = new BasicHttpRequest("GET", "/");
+        final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
+        final HttpClientConnection conn = Mockito.mock(HttpClientConnection.class);
+        final HttpProcessor httprocessor = Mockito.mock(HttpProcessor.class);
         try {
-            HttpRequestExecutor executor = new HttpRequestExecutor();
+            final HttpRequestExecutor executor = new HttpRequestExecutor();
             executor.execute(null, conn, context);
             Assert.fail("IllegalArgumentException expected");
-        } catch (IllegalArgumentException expected) {
+        } catch (final IllegalArgumentException expected) {
         }
         try {
-            HttpRequestExecutor executor = new HttpRequestExecutor();
+            final HttpRequestExecutor executor = new HttpRequestExecutor();
             executor.execute(request, null, context);
             Assert.fail("IllegalArgumentException expected");
-        } catch (IllegalArgumentException expected) {
+        } catch (final IllegalArgumentException expected) {
         }
         try {
-            HttpRequestExecutor executor = new HttpRequestExecutor();
+            final HttpRequestExecutor executor = new HttpRequestExecutor();
             executor.execute(request, conn, null);
             Assert.fail("IllegalArgumentException expected");
-        } catch (IllegalArgumentException expected) {
+        } catch (final IllegalArgumentException expected) {
         }
 
         try {
-            HttpRequestExecutor executor = new HttpRequestExecutor();
+            final HttpRequestExecutor executor = new HttpRequestExecutor();
             executor.doSendRequest(null, conn, context);
             Assert.fail("IllegalArgumentException expected");
-        } catch (IllegalArgumentException expected) {
+        } catch (final IllegalArgumentException expected) {
         }
         try {
-            HttpRequestExecutor executor = new HttpRequestExecutor();
+            final HttpRequestExecutor executor = new HttpRequestExecutor();
             executor.doSendRequest(request, null, context);
             Assert.fail("IllegalArgumentException expected");
-        } catch (IllegalArgumentException expected) {
+        } catch (final IllegalArgumentException expected) {
         }
         try {
-            HttpRequestExecutor executor = new HttpRequestExecutor();
+            final HttpRequestExecutor executor = new HttpRequestExecutor();
             executor.doSendRequest(request, conn, null);
             Assert.fail("IllegalArgumentException expected");
-        } catch (IllegalArgumentException expected) {
+        } catch (final IllegalArgumentException expected) {
         }
 
         try {
-            HttpRequestExecutor executor = new HttpRequestExecutor();
+            final HttpRequestExecutor executor = new HttpRequestExecutor();
             executor.doReceiveResponse(null, conn, context);
             Assert.fail("IllegalArgumentException expected");
-        } catch (IllegalArgumentException expected) {
+        } catch (final IllegalArgumentException expected) {
         }
         try {
-            HttpRequestExecutor executor = new HttpRequestExecutor();
+            final HttpRequestExecutor executor = new HttpRequestExecutor();
             executor.doReceiveResponse(request, null, context);
             Assert.fail("IllegalArgumentException expected");
-        } catch (IllegalArgumentException expected) {
+        } catch (final IllegalArgumentException expected) {
         }
         try {
-            HttpRequestExecutor executor = new HttpRequestExecutor();
+            final HttpRequestExecutor executor = new HttpRequestExecutor();
             executor.doReceiveResponse(request, conn, null);
             Assert.fail("IllegalArgumentException expected");
-        } catch (IllegalArgumentException expected) {
+        } catch (final IllegalArgumentException expected) {
         }
 
         try {
-            HttpRequestExecutor executor = new HttpRequestExecutor();
+            final HttpRequestExecutor executor = new HttpRequestExecutor();
             executor.preProcess(null, httprocessor, context);
             Assert.fail("IllegalArgumentException expected");
-        } catch (IllegalArgumentException expected) {
+        } catch (final IllegalArgumentException expected) {
         }
         try {
-            HttpRequestExecutor executor = new HttpRequestExecutor();
+            final HttpRequestExecutor executor = new HttpRequestExecutor();
             executor.preProcess(request, null, context);
             Assert.fail("IllegalArgumentException expected");
-        } catch (IllegalArgumentException expected) {
+        } catch (final IllegalArgumentException expected) {
         }
         try {
-            HttpRequestExecutor executor = new HttpRequestExecutor();
+            final HttpRequestExecutor executor = new HttpRequestExecutor();
             executor.preProcess(request, httprocessor, null);
             Assert.fail("IllegalArgumentException expected");
-        } catch (IllegalArgumentException expected) {
+        } catch (final IllegalArgumentException expected) {
         }
 
         try {
-            HttpRequestExecutor executor = new HttpRequestExecutor();
+            final HttpRequestExecutor executor = new HttpRequestExecutor();
             executor.postProcess(null, httprocessor, context);
             Assert.fail("IllegalArgumentException expected");
-        } catch (IllegalArgumentException expected) {
+        } catch (final IllegalArgumentException expected) {
         }
         try {
-            HttpRequestExecutor executor = new HttpRequestExecutor();
+            final HttpRequestExecutor executor = new HttpRequestExecutor();
             executor.postProcess(response, null, context);
             Assert.fail("IllegalArgumentException expected");
-        } catch (IllegalArgumentException expected) {
+        } catch (final IllegalArgumentException expected) {
         }
         try {
-            HttpRequestExecutor executor = new HttpRequestExecutor();
+            final HttpRequestExecutor executor = new HttpRequestExecutor();
             executor.postProcess(response, httprocessor, null);
             Assert.fail("IllegalArgumentException expected");
-        } catch (IllegalArgumentException expected) {
+        } catch (final IllegalArgumentException expected) {
         }
     }
 
     @Test
     public void testBasicExecution() throws Exception {
-        HttpProcessor httprocessor = Mockito.mock(HttpProcessor.class);
-        HttpClientConnection conn = Mockito.mock(HttpClientConnection.class);
-        HttpRequestExecutor executor = new HttpRequestExecutor();
+        final HttpProcessor httprocessor = Mockito.mock(HttpProcessor.class);
+        final HttpClientConnection conn = Mockito.mock(HttpClientConnection.class);
+        final HttpRequestExecutor executor = new HttpRequestExecutor();
 
-        HttpContext context = new BasicHttpContext();
-        HttpRequest request = new BasicHttpRequest("GET", "/");
+        final HttpCoreContext context = HttpCoreContext.create();
+        final HttpRequest request = new BasicHttpRequest("GET", "/");
 
         executor.preProcess(request, httprocessor, context);
         Mockito.verify(httprocessor).process(request, context);
@@ -164,7 +164,7 @@ public class TestHttpRequestExecutor {
         Mockito.when(conn.receiveResponseHeader()).thenReturn(
                 new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK"));
 
-        HttpResponse response = executor.execute(request, conn, context);
+        final HttpResponse response = executor.execute(request, conn, context);
         Mockito.verify(conn).sendRequestHeader(request);
         Mockito.verify(conn).flush();
         Mockito.verify(conn).receiveResponseHeader();
@@ -173,19 +173,19 @@ public class TestHttpRequestExecutor {
         executor.postProcess(response, httprocessor, context);
         Mockito.verify(httprocessor).process(response, context);
 
-        Assert.assertSame(conn, context.getAttribute(ExecutionContext.HTTP_CONNECTION));
-        Assert.assertSame(request, context.getAttribute(ExecutionContext.HTTP_REQUEST));
-        Assert.assertSame(response, context.getAttribute(ExecutionContext.HTTP_RESPONSE));
+        Assert.assertSame(conn, context.getConnection());
+        Assert.assertSame(request, context.getRequest());
+        Assert.assertSame(response, context.getResponse());
     }
 
     @Test
     public void testExecutionSkipIntermediateResponses() throws Exception {
-        HttpProcessor httprocessor = Mockito.mock(HttpProcessor.class);
-        HttpClientConnection conn = Mockito.mock(HttpClientConnection.class);
-        HttpRequestExecutor executor = new HttpRequestExecutor();
+        final HttpProcessor httprocessor = Mockito.mock(HttpProcessor.class);
+        final HttpClientConnection conn = Mockito.mock(HttpClientConnection.class);
+        final HttpRequestExecutor executor = new HttpRequestExecutor();
 
-        HttpContext context = new BasicHttpContext();
-        HttpRequest request = new BasicHttpRequest("GET", "/");
+        final HttpCoreContext context = HttpCoreContext.create();
+        final HttpRequest request = new BasicHttpRequest("GET", "/");
 
         executor.preProcess(request, httprocessor, context);
         Mockito.verify(httprocessor).process(request, context);
@@ -196,7 +196,7 @@ public class TestHttpRequestExecutor {
                 new BasicHttpResponse(HttpVersion.HTTP_1_1, 102, "OK"),
                 new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK"));
 
-        HttpResponse response = executor.execute(request, conn, context);
+        final HttpResponse response = executor.execute(request, conn, context);
         Mockito.verify(conn).sendRequestHeader(request);
         Mockito.verify(conn).flush();
         Mockito.verify(conn, Mockito.times(4)).receiveResponseHeader();
@@ -205,19 +205,19 @@ public class TestHttpRequestExecutor {
         executor.postProcess(response, httprocessor, context);
         Mockito.verify(httprocessor).process(response, context);
 
-        Assert.assertSame(conn, context.getAttribute(ExecutionContext.HTTP_CONNECTION));
-        Assert.assertSame(request, context.getAttribute(ExecutionContext.HTTP_REQUEST));
-        Assert.assertSame(response, context.getAttribute(ExecutionContext.HTTP_RESPONSE));
+        Assert.assertSame(conn, context.getConnection());
+        Assert.assertSame(request, context.getRequest());
+        Assert.assertSame(response, context.getResponse());
     }
 
     @Test
     public void testExecutionNoResponseBody() throws Exception {
-        HttpProcessor httprocessor = Mockito.mock(HttpProcessor.class);
-        HttpClientConnection conn = Mockito.mock(HttpClientConnection.class);
-        HttpRequestExecutor executor = new HttpRequestExecutor();
+        final HttpProcessor httprocessor = Mockito.mock(HttpProcessor.class);
+        final HttpClientConnection conn = Mockito.mock(HttpClientConnection.class);
+        final HttpRequestExecutor executor = new HttpRequestExecutor();
 
-        HttpContext context = new BasicHttpContext();
-        HttpRequest request = new BasicHttpRequest("GET", "/");
+        final HttpCoreContext context = HttpCoreContext.create();
+        final HttpRequest request = new BasicHttpRequest("GET", "/");
 
         executor.preProcess(request, httprocessor, context);
         Mockito.verify(httprocessor).process(request, context);
@@ -225,7 +225,7 @@ public class TestHttpRequestExecutor {
         Mockito.when(conn.receiveResponseHeader()).thenReturn(
                 new BasicHttpResponse(HttpVersion.HTTP_1_1, 204, "OK"));
 
-        HttpResponse response = executor.execute(request, conn, context);
+        final HttpResponse response = executor.execute(request, conn, context);
         Mockito.verify(conn).sendRequestHeader(request);
         Mockito.verify(conn).flush();
         Mockito.verify(conn).receiveResponseHeader();
@@ -237,12 +237,12 @@ public class TestHttpRequestExecutor {
 
     @Test
     public void testExecutionHead() throws Exception {
-        HttpProcessor httprocessor = Mockito.mock(HttpProcessor.class);
-        HttpClientConnection conn = Mockito.mock(HttpClientConnection.class);
-        HttpRequestExecutor executor = new HttpRequestExecutor();
+        final HttpProcessor httprocessor = Mockito.mock(HttpProcessor.class);
+        final HttpClientConnection conn = Mockito.mock(HttpClientConnection.class);
+        final HttpRequestExecutor executor = new HttpRequestExecutor();
 
-        HttpContext context = new BasicHttpContext();
-        HttpRequest request = new BasicHttpRequest("HEAD", "/");
+        final HttpCoreContext context = HttpCoreContext.create();
+        final HttpRequest request = new BasicHttpRequest("HEAD", "/");
 
         executor.preProcess(request, httprocessor, context);
         Mockito.verify(httprocessor).process(request, context);
@@ -250,7 +250,7 @@ public class TestHttpRequestExecutor {
         Mockito.when(conn.receiveResponseHeader()).thenReturn(
                 new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK"));
 
-        HttpResponse response = executor.execute(request, conn, context);
+        final HttpResponse response = executor.execute(request, conn, context);
         Mockito.verify(conn).sendRequestHeader(request);
         Mockito.verify(conn).flush();
         Mockito.verify(conn).receiveResponseHeader();
@@ -262,14 +262,14 @@ public class TestHttpRequestExecutor {
 
     @Test
     public void testExecutionEntityEnclosingRequest() throws Exception {
-        HttpProcessor httprocessor = Mockito.mock(HttpProcessor.class);
-        HttpClientConnection conn = Mockito.mock(HttpClientConnection.class);
-        HttpRequestExecutor executor = new HttpRequestExecutor();
+        final HttpProcessor httprocessor = Mockito.mock(HttpProcessor.class);
+        final HttpClientConnection conn = Mockito.mock(HttpClientConnection.class);
+        final HttpRequestExecutor executor = new HttpRequestExecutor();
 
-        HttpContext context = new BasicHttpContext();
-        HttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/");
+        final HttpCoreContext context = HttpCoreContext.create();
+        final HttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/");
 //        request.addHeader(HTTP.EXPECT_DIRECTIVE, HTTP.EXPECT_CONTINUE);
-        HttpEntity entity = Mockito.mock(HttpEntity.class);
+        final HttpEntity entity = Mockito.mock(HttpEntity.class);
         request.setEntity(entity);
 
         executor.preProcess(request, httprocessor, context);
@@ -278,7 +278,7 @@ public class TestHttpRequestExecutor {
         Mockito.when(conn.receiveResponseHeader()).thenReturn(
                 new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK"));
 
-        HttpResponse response = executor.execute(request, conn, context);
+        final HttpResponse response = executor.execute(request, conn, context);
         Mockito.verify(conn).sendRequestHeader(request);
         Mockito.verify(conn).sendRequestEntity(request);
         Mockito.verify(conn).flush();
@@ -291,14 +291,14 @@ public class TestHttpRequestExecutor {
 
     @Test
     public void testExecutionEntityEnclosingRequestWithExpectContinueSuccess() throws Exception {
-        HttpProcessor httprocessor = Mockito.mock(HttpProcessor.class);
-        HttpClientConnection conn = Mockito.mock(HttpClientConnection.class);
-        HttpRequestExecutor executor = new HttpRequestExecutor();
+        final HttpProcessor httprocessor = Mockito.mock(HttpProcessor.class);
+        final HttpClientConnection conn = Mockito.mock(HttpClientConnection.class);
+        final HttpRequestExecutor executor = new HttpRequestExecutor();
 
-        HttpContext context = new BasicHttpContext();
-        HttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/");
+        final HttpCoreContext context = HttpCoreContext.create();
+        final HttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/");
         request.addHeader(HTTP.EXPECT_DIRECTIVE, HTTP.EXPECT_CONTINUE);
-        HttpEntity entity = Mockito.mock(HttpEntity.class);
+        final HttpEntity entity = Mockito.mock(HttpEntity.class);
         request.setEntity(entity);
 
         executor.preProcess(request, httprocessor, context);
@@ -307,32 +307,32 @@ public class TestHttpRequestExecutor {
         Mockito.when(conn.receiveResponseHeader()).thenReturn(
                 new BasicHttpResponse(HttpVersion.HTTP_1_1, 100, "Continue"),
                 new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK"));
-        Mockito.when(conn.isResponseAvailable(Mockito.anyInt())).thenReturn(true);
+        Mockito.when(conn.isResponseAvailable(Mockito.anyInt())).thenReturn(Boolean.TRUE);
 
-        HttpResponse response = executor.execute(request, conn, context);
+        final HttpResponse response = executor.execute(request, conn, context);
         Mockito.verify(conn).sendRequestHeader(request);
         Mockito.verify(conn).sendRequestEntity(request);
         Mockito.verify(conn, Mockito.times(2)).flush();
-        Mockito.verify(conn).isResponseAvailable(2000);
+        Mockito.verify(conn).isResponseAvailable(3000);
         Mockito.verify(conn, Mockito.times(2)).receiveResponseHeader();
         Mockito.verify(conn).receiveResponseEntity(response);
 
         executor.postProcess(response, httprocessor, context);
         Mockito.verify(httprocessor).process(response, context);
 
-        Assert.assertEquals(Boolean.TRUE, context.getAttribute(ExecutionContext.HTTP_REQ_SENT));
+        Assert.assertEquals(Boolean.TRUE, context.isRequestSent());
     }
 
     @Test
     public void testExecutionEntityEnclosingRequestWithExpectContinueFailure() throws Exception {
-        HttpProcessor httprocessor = Mockito.mock(HttpProcessor.class);
-        HttpClientConnection conn = Mockito.mock(HttpClientConnection.class);
-        HttpRequestExecutor executor = new HttpRequestExecutor();
+        final HttpProcessor httprocessor = Mockito.mock(HttpProcessor.class);
+        final HttpClientConnection conn = Mockito.mock(HttpClientConnection.class);
+        final HttpRequestExecutor executor = new HttpRequestExecutor();
 
-        HttpContext context = new BasicHttpContext();
-        HttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/");
+        final HttpCoreContext context = HttpCoreContext.create();
+        final HttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/");
         request.addHeader(HTTP.EXPECT_DIRECTIVE, HTTP.EXPECT_CONTINUE);
-        HttpEntity entity = Mockito.mock(HttpEntity.class);
+        final HttpEntity entity = Mockito.mock(HttpEntity.class);
         request.setEntity(entity);
 
         executor.preProcess(request, httprocessor, context);
@@ -340,13 +340,13 @@ public class TestHttpRequestExecutor {
 
         Mockito.when(conn.receiveResponseHeader()).thenReturn(
                 new BasicHttpResponse(HttpVersion.HTTP_1_1, 402, "OK"));
-        Mockito.when(conn.isResponseAvailable(Mockito.anyInt())).thenReturn(true);
+        Mockito.when(conn.isResponseAvailable(Mockito.anyInt())).thenReturn(Boolean.TRUE);
 
-        HttpResponse response = executor.execute(request, conn, context);
+        final HttpResponse response = executor.execute(request, conn, context);
         Mockito.verify(conn).sendRequestHeader(request);
         Mockito.verify(conn, Mockito.never()).sendRequestEntity(request);
         Mockito.verify(conn, Mockito.times(2)).flush();
-        Mockito.verify(conn).isResponseAvailable(2000);
+        Mockito.verify(conn).isResponseAvailable(3000);
         Mockito.verify(conn).receiveResponseHeader();
         Mockito.verify(conn).receiveResponseEntity(response);
 
@@ -356,14 +356,14 @@ public class TestHttpRequestExecutor {
 
     @Test
     public void testExecutionEntityEnclosingRequestUnsupportedIntermediateResponse() throws Exception {
-        HttpProcessor httprocessor = Mockito.mock(HttpProcessor.class);
-        HttpClientConnection conn = Mockito.mock(HttpClientConnection.class);
-        HttpRequestExecutor executor = new HttpRequestExecutor();
+        final HttpProcessor httprocessor = Mockito.mock(HttpProcessor.class);
+        final HttpClientConnection conn = Mockito.mock(HttpClientConnection.class);
+        final HttpRequestExecutor executor = new HttpRequestExecutor();
 
-        HttpContext context = new BasicHttpContext();
-        HttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/");
+        final HttpCoreContext context = HttpCoreContext.create();
+        final HttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/");
         request.addHeader(HTTP.EXPECT_DIRECTIVE, HTTP.EXPECT_CONTINUE);
-        HttpEntity entity = Mockito.mock(HttpEntity.class);
+        final HttpEntity entity = Mockito.mock(HttpEntity.class);
         request.setEntity(entity);
 
         executor.preProcess(request, httprocessor, context);
@@ -371,27 +371,27 @@ public class TestHttpRequestExecutor {
 
         Mockito.when(conn.receiveResponseHeader()).thenReturn(
                 new BasicHttpResponse(HttpVersion.HTTP_1_1, 101, "OK"));
-        Mockito.when(conn.isResponseAvailable(Mockito.anyInt())).thenReturn(true);
+        Mockito.when(conn.isResponseAvailable(Mockito.anyInt())).thenReturn(Boolean.TRUE);
 
         try {
             executor.execute(request, conn, context);
             Assert.fail("ProtocolException should have been thrown");
-        } catch (ProtocolException ex) {
+        } catch (final ProtocolException ex) {
             Mockito.verify(conn).close();
-            Assert.assertEquals(Boolean.FALSE, context.getAttribute(ExecutionContext.HTTP_REQ_SENT));
+            Assert.assertEquals(Boolean.FALSE, context.isRequestSent());
         }
     }
 
     @Test
     public void testExecutionEntityEnclosingRequestWithExpectContinueNoResponse() throws Exception {
-        HttpProcessor httprocessor = Mockito.mock(HttpProcessor.class);
-        HttpClientConnection conn = Mockito.mock(HttpClientConnection.class);
-        HttpRequestExecutor executor = new HttpRequestExecutor();
+        final HttpProcessor httprocessor = Mockito.mock(HttpProcessor.class);
+        final HttpClientConnection conn = Mockito.mock(HttpClientConnection.class);
+        final HttpRequestExecutor executor = new HttpRequestExecutor();
 
-        HttpContext context = new BasicHttpContext();
-        HttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/");
+        final HttpCoreContext context = HttpCoreContext.create();
+        final HttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/");
         request.addHeader(HTTP.EXPECT_DIRECTIVE, HTTP.EXPECT_CONTINUE);
-        HttpEntity entity = Mockito.mock(HttpEntity.class);
+        final HttpEntity entity = Mockito.mock(HttpEntity.class);
         request.setEntity(entity);
 
         executor.preProcess(request, httprocessor, context);
@@ -399,13 +399,13 @@ public class TestHttpRequestExecutor {
 
         Mockito.when(conn.receiveResponseHeader()).thenReturn(
                 new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK"));
-        Mockito.when(conn.isResponseAvailable(Mockito.anyInt())).thenReturn(false);
+        Mockito.when(conn.isResponseAvailable(Mockito.anyInt())).thenReturn(Boolean.FALSE);
 
-        HttpResponse response = executor.execute(request, conn, context);
+        final HttpResponse response = executor.execute(request, conn, context);
         Mockito.verify(conn).sendRequestHeader(request);
         Mockito.verify(conn).sendRequestEntity(request);
         Mockito.verify(conn, Mockito.times(2)).flush();
-        Mockito.verify(conn).isResponseAvailable(2000);
+        Mockito.verify(conn).isResponseAvailable(3000);
         Mockito.verify(conn).receiveResponseHeader();
         Mockito.verify(conn).receiveResponseEntity(response);
 
@@ -415,37 +415,37 @@ public class TestHttpRequestExecutor {
 
     @Test
     public void testExecutionIOException() throws Exception {
-        HttpClientConnection conn = Mockito.mock(HttpClientConnection.class);
-        HttpRequestExecutor executor = new HttpRequestExecutor();
+        final HttpClientConnection conn = Mockito.mock(HttpClientConnection.class);
+        final HttpRequestExecutor executor = new HttpRequestExecutor();
 
-        HttpContext context = new BasicHttpContext();
-        HttpRequest request = new BasicHttpRequest("GET", "/");
+        final HttpCoreContext context = HttpCoreContext.create();
+        final HttpRequest request = new BasicHttpRequest("GET", "/");
 
         Mockito.doThrow(new IOException("Oopsie")).when(conn).sendRequestHeader(request);
         try {
             executor.execute(request, conn, context);
             Assert.fail("IOException should have been thrown");
-        } catch (IOException ex) {
+        } catch (final IOException ex) {
             Mockito.verify(conn).close();
-            Assert.assertEquals(Boolean.FALSE, context.getAttribute(ExecutionContext.HTTP_REQ_SENT));
+            Assert.assertEquals(Boolean.FALSE, context.isRequestSent());
         }
     }
 
     @Test
     public void testExecutionRuntimeException() throws Exception {
-        HttpClientConnection conn = Mockito.mock(HttpClientConnection.class);
-        HttpRequestExecutor executor = new HttpRequestExecutor();
+        final HttpClientConnection conn = Mockito.mock(HttpClientConnection.class);
+        final HttpRequestExecutor executor = new HttpRequestExecutor();
 
-        HttpContext context = new BasicHttpContext();
-        HttpRequest request = new BasicHttpRequest("GET", "/");
+        final HttpCoreContext context = HttpCoreContext.create();
+        final HttpRequest request = new BasicHttpRequest("GET", "/");
 
         Mockito.doThrow(new RuntimeException("Oopsie")).when(conn).receiveResponseHeader();
         try {
             executor.execute(request, conn, context);
             Assert.fail("IOException should have been thrown");
-        } catch (RuntimeException ex) {
+        } catch (final RuntimeException ex) {
             Mockito.verify(conn).close();
-            Assert.assertEquals(Boolean.TRUE, context.getAttribute(ExecutionContext.HTTP_REQ_SENT));
+            Assert.assertEquals(Boolean.TRUE, context.isRequestSent());
         }
     }
 
diff --git a/httpcore/src/test/java/org/apache/http/protocol/TestHttpRequestHandlerRegistry.java b/httpcore/src/test/java/org/apache/http/protocol/TestHttpRequestHandlerRegistry.java
deleted file mode 100644
index 93f88c1..0000000
--- a/httpcore/src/test/java/org/apache/http/protocol/TestHttpRequestHandlerRegistry.java
+++ /dev/null
@@ -1,244 +0,0 @@
-/*
- * ====================================================================
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- *
- */
-
-package org.apache.http.protocol;
-
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.Map;
-
-import org.apache.http.HttpException;
-import org.apache.http.HttpRequest;
-import org.apache.http.HttpResponse;
-import org.junit.Assert;
-import org.junit.Test;
-
-public class TestHttpRequestHandlerRegistry {
-
-    private static class DummyHttpRequestHandler implements HttpRequestHandler {
-
-        public void handle(
-                final HttpRequest request,
-                final HttpResponse response,
-                final HttpContext context) throws HttpException, IOException {
-        }
-
-    }
-
-    @Test
-    public void testRegisterUnregister() throws Exception {
-        HttpRequestHandler h1 = new DummyHttpRequestHandler();
-        HttpRequestHandler h2 = new DummyHttpRequestHandler();
-        HttpRequestHandler h3 = new DummyHttpRequestHandler();
-
-        HttpRequestHandlerRegistry registry = new HttpRequestHandlerRegistry();
-        registry.register("/h1", h1);
-        registry.register("/h2", h2);
-        registry.register("/h3", h3);
-
-        Map<String, HttpRequestHandler> handlers = registry.getHandlers();
-        Assert.assertEquals(3, handlers.size());
-
-        HttpRequestHandler h;
-
-        h = registry.lookup("/h1");
-        Assert.assertNotNull(h);
-        Assert.assertTrue(h1 == h);
-        h = registry.lookup("/h2");
-        Assert.assertNotNull(h);
-        Assert.assertTrue(h2 == h);
-        h = registry.lookup("/h3");
-        Assert.assertNotNull(h);
-        Assert.assertTrue(h3 == h);
-
-        registry.unregister("/h1");
-        h = registry.lookup("/h1");
-        Assert.assertNull(h);
-
-        handlers = registry.getHandlers();
-        Assert.assertEquals(2, handlers.size());
-
-        Map<String, HttpRequestHandler> map = new HashMap<String, HttpRequestHandler>();
-        map.put("/a1", h1);
-        map.put("/a2", h2);
-        map.put("/a3", h3);
-        registry.setHandlers(map);
-
-        handlers = registry.getHandlers();
-        Assert.assertEquals(3, handlers.size());
-
-        h = registry.lookup("/h2");
-        Assert.assertNull(h);
-        h = registry.lookup("/h3");
-        Assert.assertNull(h);
-
-        h = registry.lookup("/a1");
-        Assert.assertNotNull(h);
-        Assert.assertTrue(h1 == h);
-    }
-
-    @Test(expected=IllegalArgumentException.class)
-    public void testRegisterNull() throws Exception {
-        HttpRequestHandlerRegistry registry = new HttpRequestHandlerRegistry();
-        registry.register(null, null);
-    }
-
-    @Test
-    public void testWildCardMatching1() throws Exception {
-        HttpRequestHandler h1 = new DummyHttpRequestHandler();
-        HttpRequestHandler h2 = new DummyHttpRequestHandler();
-        HttpRequestHandler h3 = new DummyHttpRequestHandler();
-        HttpRequestHandler def = new DummyHttpRequestHandler();
-
-        HttpRequestHandlerRegistry registry = new HttpRequestHandlerRegistry();
-        registry.register("*", def);
-        registry.register("/one/*", h1);
-        registry.register("/one/two/*", h2);
-        registry.register("/one/two/three/*", h3);
-
-        HttpRequestHandler h;
-
-        h = registry.lookup("/one/request");
-        Assert.assertNotNull(h);
-        Assert.assertTrue(h1 == h);
-
-        h = registry.lookup("/one/two/request");
-        Assert.assertNotNull(h);
-        Assert.assertTrue(h2 == h);
-
-        h = registry.lookup("/one/two/three/request");
-        Assert.assertNotNull(h);
-        Assert.assertTrue(h3 == h);
-
-        h = registry.lookup("default/request");
-        Assert.assertNotNull(h);
-        Assert.assertTrue(def == h);
-    }
-
-    @Test
-    public void testWildCardMatching2() throws Exception {
-        HttpRequestHandler h1 = new DummyHttpRequestHandler();
-        HttpRequestHandler h2 = new DummyHttpRequestHandler();
-        HttpRequestHandler def = new DummyHttpRequestHandler();
-
-        HttpRequestHandlerRegistry registry = new HttpRequestHandlerRegistry();
-        registry.register("*", def);
-        registry.register("*.view", h1);
-        registry.register("*.form", h2);
-
-        HttpRequestHandler h;
-
-        h = registry.lookup("/that.view");
-        Assert.assertNotNull(h);
-        Assert.assertTrue(h1 == h);
-
-        h = registry.lookup("/that.form");
-        Assert.assertNotNull(h);
-        Assert.assertTrue(h2 == h);
-
-        h = registry.lookup("/whatever");
-        Assert.assertNotNull(h);
-        Assert.assertTrue(def == h);
-    }
-
-    @Test
-    public void testWildCardMatchingWithQuery() throws Exception {
-        HttpRequestHandler h1 = new DummyHttpRequestHandler();
-        HttpRequestHandler h2 = new DummyHttpRequestHandler();
-        HttpRequestHandler def = new DummyHttpRequestHandler();
-
-        HttpRequestHandlerRegistry registry = new HttpRequestHandlerRegistry();
-        registry.register("*", def);
-        registry.register("*.view", h1);
-        registry.register("*.form", h2);
-
-        HttpRequestHandler h;
-
-        h = registry.lookup("/that.view?param=value");
-        Assert.assertNotNull(h);
-        Assert.assertTrue(h1 == h);
-
-        h = registry.lookup("/that.form?whatever");
-        Assert.assertNotNull(h);
-        Assert.assertTrue(h2 == h);
-
-        h = registry.lookup("/whatever");
-        Assert.assertNotNull(h);
-        Assert.assertTrue(def == h);
-    }
-
-    @Test
-    public void testSuffixPatternOverPrefixPatternMatch() throws Exception {
-        HttpRequestHandler h1 = new DummyHttpRequestHandler();
-        HttpRequestHandler h2 = new DummyHttpRequestHandler();
-
-        HttpRequestHandlerRegistry registry = new HttpRequestHandlerRegistry();
-        registry.register("/ma*", h1);
-        registry.register("*tch", h2);
-
-        HttpRequestHandler h;
-
-        h = registry.lookup("/match");
-        Assert.assertNotNull(h);
-        Assert.assertTrue(h1 == h);
-    }
-
-    @Test
-    public void testInvalidInput() throws Exception {
-        HttpRequestHandlerRegistry registry = new HttpRequestHandlerRegistry();
-        try {
-            registry.register(null, null);
-            Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
-            // expected
-        }
-
-        try {
-            registry.register("", null);
-            Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
-            // expected
-        }
-
-        registry.unregister(null);
-
-        try {
-            registry.setHandlers(null);
-            Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
-            // expected
-        }
-
-        try {
-            registry.lookup(null);
-            Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
-            // expected
-        }
-    }
-
-}
diff --git a/httpcore/src/test/java/org/apache/http/protocol/TestHttpService.java b/httpcore/src/test/java/org/apache/http/protocol/TestHttpService.java
index 71081fa..1e99a32 100644
--- a/httpcore/src/test/java/org/apache/http/protocol/TestHttpService.java
+++ b/httpcore/src/test/java/org/apache/http/protocol/TestHttpService.java
@@ -45,8 +45,6 @@ import org.apache.http.entity.InputStreamEntity;
 import org.apache.http.message.BasicHttpEntityEnclosingRequest;
 import org.apache.http.message.BasicHttpRequest;
 import org.apache.http.message.BasicHttpResponse;
-import org.apache.http.params.HttpParams;
-import org.apache.http.params.SyncBasicHttpParams;
 import org.junit.Assert;
 import org.junit.Test;
 import org.mockito.Mockito;
@@ -55,82 +53,47 @@ public class TestHttpService {
 
     @Test
     public void testInvalidInitialization() throws Exception {
-        HttpProcessor httprocessor = Mockito.mock(HttpProcessor.class);
-        ConnectionReuseStrategy connReuseStrategy = Mockito.mock(ConnectionReuseStrategy.class);
-        HttpResponseFactory responseFactory = Mockito.mock(HttpResponseFactory.class);
-        HttpRequestHandlerResolver handlerResolver = Mockito.mock(HttpRequestHandlerResolver.class);
-        HttpParams params = new SyncBasicHttpParams();
+        final ConnectionReuseStrategy connReuseStrategy = Mockito.mock(ConnectionReuseStrategy.class);
+        final HttpResponseFactory responseFactory = Mockito.mock(HttpResponseFactory.class);
+        final HttpRequestHandlerMapper handlerResolver = Mockito.mock(HttpRequestHandlerMapper.class);
         try {
             new HttpService(
                     null,
                     connReuseStrategy,
                     responseFactory,
-                    handlerResolver,
-                    params);
+                    handlerResolver);
             Assert.fail("IllegalArgumentException expected");
-        } catch (IllegalArgumentException expected) {
-        }
-        try {
-            new HttpService(
-                    httprocessor,
-                    null,
-                    responseFactory,
-                    handlerResolver,
-                    params);
-            Assert.fail("IllegalArgumentException expected");
-        } catch (IllegalArgumentException expected) {
-        }
-        try {
-            new HttpService(
-                    httprocessor,
-                    connReuseStrategy,
-                    null,
-                    handlerResolver,
-                    params);
-            Assert.fail("IllegalArgumentException expected");
-        } catch (IllegalArgumentException expected) {
-        }
-        try {
-            new HttpService(
-                    httprocessor,
-                    connReuseStrategy,
-                    responseFactory,
-                    handlerResolver,
-                    null);
-            Assert.fail("IllegalArgumentException expected");
-        } catch (IllegalArgumentException expected) {
+        } catch (final IllegalArgumentException expected) {
         }
     }
 
     @Test
     public void testBasicExecution() throws Exception {
-        HttpProcessor httprocessor = Mockito.mock(HttpProcessor.class);
-        ConnectionReuseStrategy connReuseStrategy = Mockito.mock(ConnectionReuseStrategy.class);
-        HttpResponseFactory responseFactory = Mockito.mock(HttpResponseFactory.class);
-        HttpRequestHandlerResolver handlerResolver = Mockito.mock(HttpRequestHandlerResolver.class);
-        HttpParams params = new SyncBasicHttpParams();
+        final HttpProcessor httprocessor = Mockito.mock(HttpProcessor.class);
+        final ConnectionReuseStrategy connReuseStrategy = Mockito.mock(ConnectionReuseStrategy.class);
+        final HttpResponseFactory responseFactory = Mockito.mock(HttpResponseFactory.class);
+        final HttpRequestHandlerMapper handlerResolver = Mockito.mock(HttpRequestHandlerMapper.class);
 
-        HttpService httpservice = new HttpService(
+        final HttpService httpservice = new HttpService(
                 httprocessor,
                 connReuseStrategy,
                 responseFactory,
-                handlerResolver,
-                params);
-        HttpContext context = new BasicHttpContext();
-        HttpServerConnection conn = Mockito.mock(HttpServerConnection.class);
-        HttpRequest request = new BasicHttpRequest("GET", "/");
+                handlerResolver);
+        final HttpCoreContext context = HttpCoreContext.create();
+        final HttpServerConnection conn = Mockito.mock(HttpServerConnection.class);
+        final HttpRequest request = new BasicHttpRequest("GET", "/");
         Mockito.when(conn.receiveRequestHeader()).thenReturn(request);
-        HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
+        final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
         Mockito.when(responseFactory.newHttpResponse(HttpVersion.HTTP_1_1, 200, context)).thenReturn(response);
-        Mockito.when(connReuseStrategy.keepAlive(response, context)).thenReturn(false);
+        Mockito.when(connReuseStrategy.keepAlive(response, context)).thenReturn(Boolean.FALSE);
 
         httpservice.handleRequest(conn, context);
 
         Assert.assertEquals(HttpStatus.SC_NOT_IMPLEMENTED, response.getStatusLine().getStatusCode());
 
-        Assert.assertSame(conn, context.getAttribute(ExecutionContext.HTTP_CONNECTION));
-        Assert.assertSame(request, context.getAttribute(ExecutionContext.HTTP_REQUEST));
-        Assert.assertSame(response, context.getAttribute(ExecutionContext.HTTP_RESPONSE));
+        Assert.assertSame(conn, context.getConnection());
+        Assert.assertSame(request, context.getRequest());
+        Assert.assertSame(response, context.getResponse());
 
         Mockito.verify(httprocessor).process(request, context);
         Mockito.verify(httprocessor).process(response, context);
@@ -142,25 +105,23 @@ public class TestHttpService {
 
     @Test
     public void testBasicExecutionHTTP10() throws Exception {
-        HttpProcessor httprocessor = Mockito.mock(HttpProcessor.class);
-        ConnectionReuseStrategy connReuseStrategy = Mockito.mock(ConnectionReuseStrategy.class);
-        HttpResponseFactory responseFactory = Mockito.mock(HttpResponseFactory.class);
-        HttpRequestHandlerResolver handlerResolver = Mockito.mock(HttpRequestHandlerResolver.class);
-        HttpParams params = new SyncBasicHttpParams();
+        final HttpProcessor httprocessor = Mockito.mock(HttpProcessor.class);
+        final ConnectionReuseStrategy connReuseStrategy = Mockito.mock(ConnectionReuseStrategy.class);
+        final HttpResponseFactory responseFactory = Mockito.mock(HttpResponseFactory.class);
+        final HttpRequestHandlerMapper handlerResolver = Mockito.mock(HttpRequestHandlerMapper.class);
 
-        HttpService httpservice = new HttpService(
+        final HttpService httpservice = new HttpService(
                 httprocessor,
                 connReuseStrategy,
                 responseFactory,
-                handlerResolver,
-                params);
-        HttpContext context = new BasicHttpContext();
-        HttpServerConnection conn = Mockito.mock(HttpServerConnection.class);
-        HttpRequest request = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_0);
+                handlerResolver);
+        final HttpCoreContext context = HttpCoreContext.create();
+        final HttpServerConnection conn = Mockito.mock(HttpServerConnection.class);
+        final HttpRequest request = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_0);
         Mockito.when(conn.receiveRequestHeader()).thenReturn(request);
-        HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_0, 200, "OK");
+        final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_0, 200, "OK");
         Mockito.when(responseFactory.newHttpResponse(HttpVersion.HTTP_1_1, 200, context)).thenReturn(response);
-        Mockito.when(connReuseStrategy.keepAlive(response, context)).thenReturn(false);
+        Mockito.when(connReuseStrategy.keepAlive(response, context)).thenReturn(Boolean.FALSE);
 
         httpservice.handleRequest(conn, context);
 
@@ -169,25 +130,23 @@ public class TestHttpService {
 
     @Test
     public void testBasicProtocolDowngrade() throws Exception {
-        HttpProcessor httprocessor = Mockito.mock(HttpProcessor.class);
-        ConnectionReuseStrategy connReuseStrategy = Mockito.mock(ConnectionReuseStrategy.class);
-        HttpResponseFactory responseFactory = Mockito.mock(HttpResponseFactory.class);
-        HttpRequestHandlerResolver handlerResolver = Mockito.mock(HttpRequestHandlerResolver.class);
-        HttpParams params = new SyncBasicHttpParams();
+        final HttpProcessor httprocessor = Mockito.mock(HttpProcessor.class);
+        final ConnectionReuseStrategy connReuseStrategy = Mockito.mock(ConnectionReuseStrategy.class);
+        final HttpResponseFactory responseFactory = Mockito.mock(HttpResponseFactory.class);
+        final HttpRequestHandlerMapper handlerResolver = Mockito.mock(HttpRequestHandlerMapper.class);
 
-        HttpService httpservice = new HttpService(
+        final HttpService httpservice = new HttpService(
                 httprocessor,
                 connReuseStrategy,
                 responseFactory,
-                handlerResolver,
-                params);
-        HttpContext context = new BasicHttpContext();
-        HttpServerConnection conn = Mockito.mock(HttpServerConnection.class);
-        HttpRequest request = new BasicHttpRequest("GET", "/", new HttpVersion(20, 45));
+                handlerResolver);
+        final HttpCoreContext context = HttpCoreContext.create();
+        final HttpServerConnection conn = Mockito.mock(HttpServerConnection.class);
+        final HttpRequest request = new BasicHttpRequest("GET", "/", new HttpVersion(20, 45));
         Mockito.when(conn.receiveRequestHeader()).thenReturn(request);
-        HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
+        final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
         Mockito.when(responseFactory.newHttpResponse(HttpVersion.HTTP_1_1, 200, context)).thenReturn(response);
-        Mockito.when(connReuseStrategy.keepAlive(response, context)).thenReturn(false);
+        Mockito.when(connReuseStrategy.keepAlive(response, context)).thenReturn(Boolean.FALSE);
 
         httpservice.handleRequest(conn, context);
 
@@ -196,37 +155,35 @@ public class TestHttpService {
 
     @Test
     public void testExecutionEntityEclosingRequest() throws Exception {
-        HttpProcessor httprocessor = Mockito.mock(HttpProcessor.class);
-        ConnectionReuseStrategy connReuseStrategy = Mockito.mock(ConnectionReuseStrategy.class);
-        HttpResponseFactory responseFactory = Mockito.mock(HttpResponseFactory.class);
-        HttpRequestHandlerResolver handlerResolver = Mockito.mock(HttpRequestHandlerResolver.class);
-        HttpParams params = new SyncBasicHttpParams();
+        final HttpProcessor httprocessor = Mockito.mock(HttpProcessor.class);
+        final ConnectionReuseStrategy connReuseStrategy = Mockito.mock(ConnectionReuseStrategy.class);
+        final HttpResponseFactory responseFactory = Mockito.mock(HttpResponseFactory.class);
+        final HttpRequestHandlerMapper handlerResolver = Mockito.mock(HttpRequestHandlerMapper.class);
 
-        HttpService httpservice = new HttpService(
+        final HttpService httpservice = new HttpService(
                 httprocessor,
                 connReuseStrategy,
                 responseFactory,
-                handlerResolver,
-                params);
-        HttpContext context = new BasicHttpContext();
-        HttpServerConnection conn = Mockito.mock(HttpServerConnection.class);
-        HttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/");
-        InputStream instream = Mockito.mock(InputStream.class);
-        InputStreamEntity entity = new InputStreamEntity(instream, -1);
+                handlerResolver);
+        final HttpCoreContext context = HttpCoreContext.create();
+        final HttpServerConnection conn = Mockito.mock(HttpServerConnection.class);
+        final HttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/");
+        final InputStream instream = Mockito.mock(InputStream.class);
+        final InputStreamEntity entity = new InputStreamEntity(instream, -1);
         request.setEntity(entity);
 
         Mockito.when(conn.receiveRequestHeader()).thenReturn(request);
-        HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
+        final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
         Mockito.when(responseFactory.newHttpResponse(HttpVersion.HTTP_1_1, 200, context)).thenReturn(response);
-        Mockito.when(connReuseStrategy.keepAlive(response, context)).thenReturn(false);
+        Mockito.when(connReuseStrategy.keepAlive(response, context)).thenReturn(Boolean.FALSE);
 
         httpservice.handleRequest(conn, context);
 
         Assert.assertEquals(HttpStatus.SC_NOT_IMPLEMENTED, response.getStatusLine().getStatusCode());
 
-        Assert.assertSame(conn, context.getAttribute(ExecutionContext.HTTP_CONNECTION));
-        Assert.assertSame(request, context.getAttribute(ExecutionContext.HTTP_REQUEST));
-        Assert.assertSame(response, context.getAttribute(ExecutionContext.HTTP_RESPONSE));
+        Assert.assertSame(conn, context.getConnection());
+        Assert.assertSame(request, context.getRequest());
+        Assert.assertSame(response, context.getResponse());
 
         Mockito.verify(conn).receiveRequestEntity(request);
         Mockito.verify(httprocessor).process(request, context);
@@ -240,40 +197,38 @@ public class TestHttpService {
 
     @Test
     public void testExecutionEntityEclosingRequestWithExpectContinue() throws Exception {
-        HttpProcessor httprocessor = Mockito.mock(HttpProcessor.class);
-        ConnectionReuseStrategy connReuseStrategy = Mockito.mock(ConnectionReuseStrategy.class);
-        HttpResponseFactory responseFactory = Mockito.mock(HttpResponseFactory.class);
-        HttpRequestHandlerResolver handlerResolver = Mockito.mock(HttpRequestHandlerResolver.class);
-        HttpParams params = new SyncBasicHttpParams();
+        final HttpProcessor httprocessor = Mockito.mock(HttpProcessor.class);
+        final ConnectionReuseStrategy connReuseStrategy = Mockito.mock(ConnectionReuseStrategy.class);
+        final HttpResponseFactory responseFactory = Mockito.mock(HttpResponseFactory.class);
+        final HttpRequestHandlerMapper handlerResolver = Mockito.mock(HttpRequestHandlerMapper.class);
 
-        HttpService httpservice = new HttpService(
+        final HttpService httpservice = new HttpService(
                 httprocessor,
                 connReuseStrategy,
                 responseFactory,
-                handlerResolver,
-                params);
-        HttpContext context = new BasicHttpContext();
-        HttpServerConnection conn = Mockito.mock(HttpServerConnection.class);
-        HttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/");
+                handlerResolver);
+        final HttpCoreContext context = HttpCoreContext.create();
+        final HttpServerConnection conn = Mockito.mock(HttpServerConnection.class);
+        final HttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/");
         request.addHeader(HTTP.EXPECT_DIRECTIVE, HTTP.EXPECT_CONTINUE);
-        InputStream instream = Mockito.mock(InputStream.class);
-        InputStreamEntity entity = new InputStreamEntity(instream, -1);
+        final InputStream instream = Mockito.mock(InputStream.class);
+        final InputStreamEntity entity = new InputStreamEntity(instream, -1);
         request.setEntity(entity);
 
         Mockito.when(conn.receiveRequestHeader()).thenReturn(request);
-        HttpResponse resp100 = new BasicHttpResponse(HttpVersion.HTTP_1_1, 100, "Continue");
+        final HttpResponse resp100 = new BasicHttpResponse(HttpVersion.HTTP_1_1, 100, "Continue");
         Mockito.when(responseFactory.newHttpResponse(HttpVersion.HTTP_1_1, 100, context)).thenReturn(resp100);
-        HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
+        final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
         Mockito.when(responseFactory.newHttpResponse(HttpVersion.HTTP_1_1, 200, context)).thenReturn(response);
-        Mockito.when(connReuseStrategy.keepAlive(response, context)).thenReturn(false);
+        Mockito.when(connReuseStrategy.keepAlive(response, context)).thenReturn(Boolean.FALSE);
 
         httpservice.handleRequest(conn, context);
 
         Assert.assertEquals(HttpStatus.SC_NOT_IMPLEMENTED, response.getStatusLine().getStatusCode());
 
-        Assert.assertSame(conn, context.getAttribute(ExecutionContext.HTTP_CONNECTION));
-        Assert.assertSame(request, context.getAttribute(ExecutionContext.HTTP_REQUEST));
-        Assert.assertSame(response, context.getAttribute(ExecutionContext.HTTP_RESPONSE));
+        Assert.assertSame(conn, context.getConnection());
+        Assert.assertSame(request, context.getRequest());
+        Assert.assertSame(response, context.getResponse());
 
         Mockito.verify(conn).sendResponseHeader(resp100);
         Mockito.verify(conn).receiveRequestEntity(request);
@@ -288,13 +243,12 @@ public class TestHttpService {
 
     @Test
     public void testExecutionEntityEclosingRequestCustomExpectationVerifier() throws Exception {
-        HttpProcessor httprocessor = Mockito.mock(HttpProcessor.class);
-        ConnectionReuseStrategy connReuseStrategy = Mockito.mock(ConnectionReuseStrategy.class);
-        HttpResponseFactory responseFactory = Mockito.mock(HttpResponseFactory.class);
-        HttpRequestHandlerResolver handlerResolver = Mockito.mock(HttpRequestHandlerResolver.class);
-        HttpParams params = new SyncBasicHttpParams();
+        final HttpProcessor httprocessor = Mockito.mock(HttpProcessor.class);
+        final ConnectionReuseStrategy connReuseStrategy = Mockito.mock(ConnectionReuseStrategy.class);
+        final HttpResponseFactory responseFactory = Mockito.mock(HttpResponseFactory.class);
+        final HttpRequestHandlerMapper handlerResolver = Mockito.mock(HttpRequestHandlerMapper.class);
 
-        HttpExpectationVerifier expectationVerifier = new HttpExpectationVerifier() {
+        final HttpExpectationVerifier expectationVerifier = new HttpExpectationVerifier() {
 
             public void verify(
                     final HttpRequest request,
@@ -305,31 +259,30 @@ public class TestHttpService {
 
         };
 
-        HttpService httpservice = new HttpService(
+        final HttpService httpservice = new HttpService(
                 httprocessor,
                 connReuseStrategy,
                 responseFactory,
                 handlerResolver,
-                expectationVerifier,
-                params);
-        HttpContext context = new BasicHttpContext();
-        HttpServerConnection conn = Mockito.mock(HttpServerConnection.class);
-        HttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/");
+                expectationVerifier);
+        final HttpCoreContext context = HttpCoreContext.create();
+        final HttpServerConnection conn = Mockito.mock(HttpServerConnection.class);
+        final HttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/");
         request.addHeader(HTTP.EXPECT_DIRECTIVE, HTTP.EXPECT_CONTINUE);
-        InputStream instream = Mockito.mock(InputStream.class);
-        InputStreamEntity entity = new InputStreamEntity(instream, -1);
+        final InputStream instream = Mockito.mock(InputStream.class);
+        final InputStreamEntity entity = new InputStreamEntity(instream, -1);
         request.setEntity(entity);
 
         Mockito.when(conn.receiveRequestHeader()).thenReturn(request);
-        HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 100, "Continue");
+        final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 100, "Continue");
         Mockito.when(responseFactory.newHttpResponse(HttpVersion.HTTP_1_1, 100, context)).thenReturn(response);
-        Mockito.when(connReuseStrategy.keepAlive(response, context)).thenReturn(false);
+        Mockito.when(connReuseStrategy.keepAlive(response, context)).thenReturn(Boolean.FALSE);
 
         httpservice.handleRequest(conn, context);
 
-        Assert.assertSame(conn, context.getAttribute(ExecutionContext.HTTP_CONNECTION));
-        Assert.assertSame(request, context.getAttribute(ExecutionContext.HTTP_REQUEST));
-        Assert.assertSame(response, context.getAttribute(ExecutionContext.HTTP_RESPONSE));
+        Assert.assertSame(conn, context.getConnection());
+        Assert.assertSame(request, context.getRequest());
+        Assert.assertSame(response, context.getResponse());
 
         Assert.assertEquals(HttpStatus.SC_UNAUTHORIZED, response.getStatusLine().getStatusCode());
 
@@ -344,41 +297,39 @@ public class TestHttpService {
 
     @Test
     public void testExecutionExceptionInCustomExpectationVerifier() throws Exception {
-        HttpProcessor httprocessor = Mockito.mock(HttpProcessor.class);
-        ConnectionReuseStrategy connReuseStrategy = Mockito.mock(ConnectionReuseStrategy.class);
-        HttpResponseFactory responseFactory = Mockito.mock(HttpResponseFactory.class);
-        HttpExpectationVerifier expectationVerifier = Mockito.mock(HttpExpectationVerifier.class);
-        HttpRequestHandlerResolver handlerResolver = Mockito.mock(HttpRequestHandlerResolver.class);
-        HttpParams params = new SyncBasicHttpParams();
-
-        HttpService httpservice = new HttpService(
+        final HttpProcessor httprocessor = Mockito.mock(HttpProcessor.class);
+        final ConnectionReuseStrategy connReuseStrategy = Mockito.mock(ConnectionReuseStrategy.class);
+        final HttpResponseFactory responseFactory = Mockito.mock(HttpResponseFactory.class);
+        final HttpExpectationVerifier expectationVerifier = Mockito.mock(HttpExpectationVerifier.class);
+        final HttpRequestHandlerMapper handlerResolver = Mockito.mock(HttpRequestHandlerMapper.class);
+
+        final HttpService httpservice = new HttpService(
                 httprocessor,
                 connReuseStrategy,
                 responseFactory,
                 handlerResolver,
-                expectationVerifier,
-                params);
-        HttpContext context = new BasicHttpContext();
-        HttpServerConnection conn = Mockito.mock(HttpServerConnection.class);
-        HttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/");
+                expectationVerifier);
+        final HttpCoreContext context = HttpCoreContext.create();
+        final HttpServerConnection conn = Mockito.mock(HttpServerConnection.class);
+        final HttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/");
         request.addHeader(HTTP.EXPECT_DIRECTIVE, HTTP.EXPECT_CONTINUE);
-        InputStream instream = Mockito.mock(InputStream.class);
-        InputStreamEntity entity = new InputStreamEntity(instream, -1);
+        final InputStream instream = Mockito.mock(InputStream.class);
+        final InputStreamEntity entity = new InputStreamEntity(instream, -1);
         request.setEntity(entity);
 
         Mockito.when(conn.receiveRequestHeader()).thenReturn(request);
-        HttpResponse resp100 = new BasicHttpResponse(HttpVersion.HTTP_1_1, 100, "Continue");
+        final HttpResponse resp100 = new BasicHttpResponse(HttpVersion.HTTP_1_1, 100, "Continue");
         Mockito.when(responseFactory.newHttpResponse(HttpVersion.HTTP_1_1, 100, context)).thenReturn(resp100);
-        HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_0, 500, "Oppsie");
+        final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_0, 500, "Oppsie");
         Mockito.when(responseFactory.newHttpResponse(HttpVersion.HTTP_1_0, 500, context)).thenReturn(response);
         Mockito.doThrow(new HttpException("Oopsie")).when(expectationVerifier).verify(request, resp100, context);
-        Mockito.when(connReuseStrategy.keepAlive(response, context)).thenReturn(false);
+        Mockito.when(connReuseStrategy.keepAlive(response, context)).thenReturn(Boolean.FALSE);
 
         httpservice.handleRequest(conn, context);
 
-        Assert.assertSame(conn, context.getAttribute(ExecutionContext.HTTP_CONNECTION));
-        Assert.assertSame(request, context.getAttribute(ExecutionContext.HTTP_REQUEST));
-        Assert.assertSame(response, context.getAttribute(ExecutionContext.HTTP_RESPONSE));
+        Assert.assertSame(conn, context.getConnection());
+        Assert.assertSame(request, context.getRequest());
+        Assert.assertSame(response, context.getResponse());
 
         Assert.assertEquals(HttpStatus.SC_INTERNAL_SERVER_ERROR, response.getStatusLine().getStatusCode());
 
@@ -393,38 +344,36 @@ public class TestHttpService {
 
     @Test
     public void testMethodNotSupported() throws Exception {
-        HttpProcessor httprocessor = Mockito.mock(HttpProcessor.class);
-        ConnectionReuseStrategy connReuseStrategy = Mockito.mock(ConnectionReuseStrategy.class);
-        HttpResponseFactory responseFactory = Mockito.mock(HttpResponseFactory.class);
-        HttpRequestHandlerResolver handlerResolver = Mockito.mock(HttpRequestHandlerResolver.class);
-        HttpRequestHandler requestHandler = Mockito.mock(HttpRequestHandler.class);
-        HttpParams params = new SyncBasicHttpParams();
-
-        HttpService httpservice = new HttpService(
+        final HttpProcessor httprocessor = Mockito.mock(HttpProcessor.class);
+        final ConnectionReuseStrategy connReuseStrategy = Mockito.mock(ConnectionReuseStrategy.class);
+        final HttpResponseFactory responseFactory = Mockito.mock(HttpResponseFactory.class);
+        final HttpRequestHandlerMapper handlerResolver = Mockito.mock(HttpRequestHandlerMapper.class);
+        final HttpRequestHandler requestHandler = Mockito.mock(HttpRequestHandler.class);
+
+        final HttpService httpservice = new HttpService(
                 httprocessor,
                 connReuseStrategy,
                 responseFactory,
-                handlerResolver,
-                params);
-        HttpContext context = new BasicHttpContext();
-        HttpServerConnection conn = Mockito.mock(HttpServerConnection.class);
-        HttpRequest request = new BasicHttpRequest("whatever", "/");
+                handlerResolver);
+        final HttpCoreContext context = HttpCoreContext.create();
+        final HttpServerConnection conn = Mockito.mock(HttpServerConnection.class);
+        final HttpRequest request = new BasicHttpRequest("whatever", "/");
 
         Mockito.when(conn.receiveRequestHeader()).thenReturn(request);
-        HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
+        final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
         Mockito.when(responseFactory.newHttpResponse(HttpVersion.HTTP_1_1, 200, context)).thenReturn(response);
-        HttpResponse error = new BasicHttpResponse(HttpVersion.HTTP_1_0, 500, "Oppsie");
+        final HttpResponse error = new BasicHttpResponse(HttpVersion.HTTP_1_0, 500, "Oppsie");
         Mockito.when(responseFactory.newHttpResponse(HttpVersion.HTTP_1_0, 500, context)).thenReturn(error);
-        Mockito.when(handlerResolver.lookup("/")).thenReturn(requestHandler);
+        Mockito.when(handlerResolver.lookup(request)).thenReturn(requestHandler);
         Mockito.doThrow(new MethodNotSupportedException("whatever")).when(
                 requestHandler).handle(request, response, context);
-        Mockito.when(connReuseStrategy.keepAlive(error, context)).thenReturn(false);
+        Mockito.when(connReuseStrategy.keepAlive(error, context)).thenReturn(Boolean.FALSE);
 
         httpservice.handleRequest(conn, context);
 
-        Assert.assertSame(conn, context.getAttribute(ExecutionContext.HTTP_CONNECTION));
-        Assert.assertSame(request, context.getAttribute(ExecutionContext.HTTP_REQUEST));
-        Assert.assertSame(error, context.getAttribute(ExecutionContext.HTTP_RESPONSE));
+        Assert.assertSame(conn, context.getConnection());
+        Assert.assertSame(request, context.getRequest());
+        Assert.assertSame(error, context.getResponse());
 
         Assert.assertEquals(HttpStatus.SC_NOT_IMPLEMENTED, error.getStatusLine().getStatusCode());
 
@@ -438,38 +387,36 @@ public class TestHttpService {
 
     @Test
     public void testUnsupportedHttpVersionException() throws Exception {
-        HttpProcessor httprocessor = Mockito.mock(HttpProcessor.class);
-        ConnectionReuseStrategy connReuseStrategy = Mockito.mock(ConnectionReuseStrategy.class);
-        HttpResponseFactory responseFactory = Mockito.mock(HttpResponseFactory.class);
-        HttpRequestHandlerResolver handlerResolver = Mockito.mock(HttpRequestHandlerResolver.class);
-        HttpRequestHandler requestHandler = Mockito.mock(HttpRequestHandler.class);
-        HttpParams params = new SyncBasicHttpParams();
-
-        HttpService httpservice = new HttpService(
+        final HttpProcessor httprocessor = Mockito.mock(HttpProcessor.class);
+        final ConnectionReuseStrategy connReuseStrategy = Mockito.mock(ConnectionReuseStrategy.class);
+        final HttpResponseFactory responseFactory = Mockito.mock(HttpResponseFactory.class);
+        final HttpRequestHandlerMapper handlerResolver = Mockito.mock(HttpRequestHandlerMapper.class);
+        final HttpRequestHandler requestHandler = Mockito.mock(HttpRequestHandler.class);
+
+        final HttpService httpservice = new HttpService(
                 httprocessor,
                 connReuseStrategy,
                 responseFactory,
-                handlerResolver,
-                params);
-        HttpContext context = new BasicHttpContext();
-        HttpServerConnection conn = Mockito.mock(HttpServerConnection.class);
-        HttpRequest request = new BasicHttpRequest("whatever", "/");
+                handlerResolver);
+        final HttpCoreContext context = HttpCoreContext.create();
+        final HttpServerConnection conn = Mockito.mock(HttpServerConnection.class);
+        final HttpRequest request = new BasicHttpRequest("whatever", "/");
 
         Mockito.when(conn.receiveRequestHeader()).thenReturn(request);
-        HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
+        final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
         Mockito.when(responseFactory.newHttpResponse(HttpVersion.HTTP_1_1, 200, context)).thenReturn(response);
-        HttpResponse error = new BasicHttpResponse(HttpVersion.HTTP_1_0, 500, "Oppsie");
+        final HttpResponse error = new BasicHttpResponse(HttpVersion.HTTP_1_0, 500, "Oppsie");
         Mockito.when(responseFactory.newHttpResponse(HttpVersion.HTTP_1_0, 500, context)).thenReturn(error);
-        Mockito.when(handlerResolver.lookup("/")).thenReturn(requestHandler);
+        Mockito.when(handlerResolver.lookup(request)).thenReturn(requestHandler);
         Mockito.doThrow(new UnsupportedHttpVersionException()).when(
                 requestHandler).handle(request, response, context);
-        Mockito.when(connReuseStrategy.keepAlive(error, context)).thenReturn(false);
+        Mockito.when(connReuseStrategy.keepAlive(error, context)).thenReturn(Boolean.FALSE);
 
         httpservice.handleRequest(conn, context);
 
-        Assert.assertSame(conn, context.getAttribute(ExecutionContext.HTTP_CONNECTION));
-        Assert.assertSame(request, context.getAttribute(ExecutionContext.HTTP_REQUEST));
-        Assert.assertSame(error, context.getAttribute(ExecutionContext.HTTP_RESPONSE));
+        Assert.assertSame(conn, context.getConnection());
+        Assert.assertSame(request, context.getRequest());
+        Assert.assertSame(error, context.getResponse());
 
         Assert.assertEquals(HttpStatus.SC_HTTP_VERSION_NOT_SUPPORTED, error.getStatusLine().getStatusCode());
 
@@ -483,38 +430,36 @@ public class TestHttpService {
 
     @Test
     public void testProtocolException() throws Exception {
-        HttpProcessor httprocessor = Mockito.mock(HttpProcessor.class);
-        ConnectionReuseStrategy connReuseStrategy = Mockito.mock(ConnectionReuseStrategy.class);
-        HttpResponseFactory responseFactory = Mockito.mock(HttpResponseFactory.class);
-        HttpRequestHandlerResolver handlerResolver = Mockito.mock(HttpRequestHandlerResolver.class);
-        HttpRequestHandler requestHandler = Mockito.mock(HttpRequestHandler.class);
-        HttpParams params = new SyncBasicHttpParams();
-
-        HttpService httpservice = new HttpService(
+        final HttpProcessor httprocessor = Mockito.mock(HttpProcessor.class);
+        final ConnectionReuseStrategy connReuseStrategy = Mockito.mock(ConnectionReuseStrategy.class);
+        final HttpResponseFactory responseFactory = Mockito.mock(HttpResponseFactory.class);
+        final HttpRequestHandlerMapper handlerResolver = Mockito.mock(HttpRequestHandlerMapper.class);
+        final HttpRequestHandler requestHandler = Mockito.mock(HttpRequestHandler.class);
+
+        final HttpService httpservice = new HttpService(
                 httprocessor,
                 connReuseStrategy,
                 responseFactory,
-                handlerResolver,
-                params);
-        HttpContext context = new BasicHttpContext();
-        HttpServerConnection conn = Mockito.mock(HttpServerConnection.class);
-        HttpRequest request = new BasicHttpRequest("whatever", "/");
+                handlerResolver);
+        final HttpCoreContext context = HttpCoreContext.create();
+        final HttpServerConnection conn = Mockito.mock(HttpServerConnection.class);
+        final HttpRequest request = new BasicHttpRequest("whatever", "/");
 
         Mockito.when(conn.receiveRequestHeader()).thenReturn(request);
-        HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
+        final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
         Mockito.when(responseFactory.newHttpResponse(HttpVersion.HTTP_1_1, 200, context)).thenReturn(response);
-        HttpResponse error = new BasicHttpResponse(HttpVersion.HTTP_1_0, 500, "Oppsie");
+        final HttpResponse error = new BasicHttpResponse(HttpVersion.HTTP_1_0, 500, "Oppsie");
         Mockito.when(responseFactory.newHttpResponse(HttpVersion.HTTP_1_0, 500, context)).thenReturn(error);
-        Mockito.when(handlerResolver.lookup("/")).thenReturn(requestHandler);
+        Mockito.when(handlerResolver.lookup(request)).thenReturn(requestHandler);
         Mockito.doThrow(new ProtocolException("oh, this world is wrong")).when(
                 requestHandler).handle(request, response, context);
-        Mockito.when(connReuseStrategy.keepAlive(error, context)).thenReturn(false);
+        Mockito.when(connReuseStrategy.keepAlive(error, context)).thenReturn(Boolean.FALSE);
 
         httpservice.handleRequest(conn, context);
 
-        Assert.assertSame(conn, context.getAttribute(ExecutionContext.HTTP_CONNECTION));
-        Assert.assertSame(request, context.getAttribute(ExecutionContext.HTTP_REQUEST));
-        Assert.assertSame(error, context.getAttribute(ExecutionContext.HTTP_RESPONSE));
+        Assert.assertSame(conn, context.getConnection());
+        Assert.assertSame(request, context.getRequest());
+        Assert.assertSame(error, context.getResponse());
 
         Assert.assertEquals(HttpStatus.SC_BAD_REQUEST, error.getStatusLine().getStatusCode());
 
@@ -528,35 +473,33 @@ public class TestHttpService {
 
     @Test
     public void testConnectionKeepAlive() throws Exception {
-        HttpProcessor httprocessor = Mockito.mock(HttpProcessor.class);
-        ConnectionReuseStrategy connReuseStrategy = Mockito.mock(ConnectionReuseStrategy.class);
-        HttpResponseFactory responseFactory = Mockito.mock(HttpResponseFactory.class);
-        HttpRequestHandlerResolver handlerResolver = Mockito.mock(HttpRequestHandlerResolver.class);
-        HttpRequestHandler requestHandler = Mockito.mock(HttpRequestHandler.class);
-        HttpParams params = new SyncBasicHttpParams();
-
-        HttpService httpservice = new HttpService(
+        final HttpProcessor httprocessor = Mockito.mock(HttpProcessor.class);
+        final ConnectionReuseStrategy connReuseStrategy = Mockito.mock(ConnectionReuseStrategy.class);
+        final HttpResponseFactory responseFactory = Mockito.mock(HttpResponseFactory.class);
+        final HttpRequestHandlerMapper handlerResolver = Mockito.mock(HttpRequestHandlerMapper.class);
+        final HttpRequestHandler requestHandler = Mockito.mock(HttpRequestHandler.class);
+
+        final HttpService httpservice = new HttpService(
                 httprocessor,
                 connReuseStrategy,
                 responseFactory,
-                handlerResolver,
-                params);
-        HttpContext context = new BasicHttpContext();
-        HttpServerConnection conn = Mockito.mock(HttpServerConnection.class);
-        HttpRequest request = new BasicHttpRequest("GET", "/");
+                handlerResolver);
+        final HttpCoreContext context = HttpCoreContext.create();
+        final HttpServerConnection conn = Mockito.mock(HttpServerConnection.class);
+        final HttpRequest request = new BasicHttpRequest("GET", "/");
         Mockito.when(conn.receiveRequestHeader()).thenReturn(request);
-        HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
+        final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
         Mockito.when(responseFactory.newHttpResponse(HttpVersion.HTTP_1_1, 200, context)).thenReturn(response);
-        Mockito.when(handlerResolver.lookup("/")).thenReturn(requestHandler);
-        Mockito.when(connReuseStrategy.keepAlive(response, context)).thenReturn(true);
+        Mockito.when(handlerResolver.lookup(request)).thenReturn(requestHandler);
+        Mockito.when(connReuseStrategy.keepAlive(response, context)).thenReturn(Boolean.TRUE);
 
         httpservice.handleRequest(conn, context);
 
         Assert.assertEquals(HttpStatus.SC_OK, response.getStatusLine().getStatusCode());
 
-        Assert.assertSame(conn, context.getAttribute(ExecutionContext.HTTP_CONNECTION));
-        Assert.assertSame(request, context.getAttribute(ExecutionContext.HTTP_REQUEST));
-        Assert.assertSame(response, context.getAttribute(ExecutionContext.HTTP_RESPONSE));
+        Assert.assertSame(conn, context.getConnection());
+        Assert.assertSame(request, context.getRequest());
+        Assert.assertSame(response, context.getResponse());
 
         Mockito.verify(httprocessor).process(request, context);
         Mockito.verify(httprocessor).process(response, context);
diff --git a/httpcore/src/test/java/org/apache/http/protocol/TestStandardInterceptors.java b/httpcore/src/test/java/org/apache/http/protocol/TestStandardInterceptors.java
index 2ad1017..62749b6 100644
--- a/httpcore/src/test/java/org/apache/http/protocol/TestStandardInterceptors.java
+++ b/httpcore/src/test/java/org/apache/http/protocol/TestStandardInterceptors.java
@@ -42,7 +42,6 @@ import org.apache.http.message.BasicHeader;
 import org.apache.http.message.BasicHttpEntityEnclosingRequest;
 import org.apache.http.message.BasicHttpRequest;
 import org.apache.http.message.BasicHttpResponse;
-import org.apache.http.params.CoreProtocolPNames;
 import org.junit.Assert;
 import org.junit.Test;
 import org.mockito.Mockito;
@@ -51,34 +50,34 @@ public class TestStandardInterceptors {
 
     @Test
     public void testRequestConnControlGenerated() throws Exception {
-        HttpContext context = new BasicHttpContext(null);
-        BasicHttpRequest request = new BasicHttpRequest("GET", "/");
-        RequestConnControl interceptor = new RequestConnControl();
+        final HttpContext context = new BasicHttpContext(null);
+        final BasicHttpRequest request = new BasicHttpRequest("GET", "/");
+        final RequestConnControl interceptor = new RequestConnControl();
         interceptor.process(request, context);
-        Header header = request.getFirstHeader(HTTP.CONN_DIRECTIVE);
+        final Header header = request.getFirstHeader(HTTP.CONN_DIRECTIVE);
         Assert.assertNotNull(header);
         Assert.assertEquals(HTTP.CONN_KEEP_ALIVE, header.getValue());
     }
 
     @Test
     public void testRequestConnControlConnectMethod() throws Exception {
-        HttpContext context = new BasicHttpContext(null);
-        BasicHttpRequest request = new BasicHttpRequest("CONNECT", "/");
-        RequestConnControl interceptor = new RequestConnControl();
+        final HttpContext context = new BasicHttpContext(null);
+        final BasicHttpRequest request = new BasicHttpRequest("CONNECT", "/");
+        final RequestConnControl interceptor = new RequestConnControl();
         interceptor.process(request, context);
-        Header header = request.getFirstHeader(HTTP.CONN_DIRECTIVE);
+        final Header header = request.getFirstHeader(HTTP.CONN_DIRECTIVE);
         Assert.assertNull(header);
     }
 
     @Test
     public void testRequestConnControlCustom() throws Exception {
-        HttpContext context = new BasicHttpContext(null);
-        BasicHttpRequest request = new BasicHttpRequest("GET", "/");
-        Header myheader = new BasicHeader(HTTP.CONN_DIRECTIVE, HTTP.CONN_CLOSE);
+        final HttpContext context = new BasicHttpContext(null);
+        final BasicHttpRequest request = new BasicHttpRequest("GET", "/");
+        final Header myheader = new BasicHeader(HTTP.CONN_DIRECTIVE, HTTP.CONN_CLOSE);
         request.addHeader(myheader);
-        RequestConnControl interceptor = new RequestConnControl();
+        final RequestConnControl interceptor = new RequestConnControl();
         interceptor.process(request, context);
-        Header header = request.getFirstHeader(HTTP.CONN_DIRECTIVE);
+        final Header header = request.getFirstHeader(HTTP.CONN_DIRECTIVE);
         Assert.assertNotNull(header);
         Assert.assertEquals(HTTP.CONN_CLOSE, header.getValue());
         Assert.assertTrue(header == myheader);
@@ -86,46 +85,46 @@ public class TestStandardInterceptors {
 
     @Test
     public void testRequestConnControlInvalidInput() throws Exception {
-        RequestConnControl interceptor = new RequestConnControl();
+        final RequestConnControl interceptor = new RequestConnControl();
         try {
             interceptor.process(null, null);
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
             // expected
         }
     }
 
     @Test
     public void testRequestContentProtocolException() throws Exception {
-        HttpContext context = new BasicHttpContext(null);
-        BasicHttpRequest request1 = new BasicHttpEntityEnclosingRequest("POST", "/");
+        final HttpContext context = new BasicHttpContext(null);
+        final BasicHttpRequest request1 = new BasicHttpEntityEnclosingRequest("POST", "/");
         request1.addHeader(new BasicHeader(HTTP.TRANSFER_ENCODING, "chunked"));
-        BasicHttpRequest request2 = new BasicHttpEntityEnclosingRequest("POST", "/");
+        final BasicHttpRequest request2 = new BasicHttpEntityEnclosingRequest("POST", "/");
         request2.addHeader(new BasicHeader(HTTP.CONTENT_LEN, "12"));
 
-        RequestContent interceptor = new RequestContent();
+        final RequestContent interceptor = new RequestContent();
         try {
             interceptor.process(request1, context);
             Assert.fail("ProtocolException should have been thrown");
-        } catch (ProtocolException ex) {
+        } catch (final ProtocolException ex) {
             // expected
         }
         try {
             interceptor.process(request2, context);
             Assert.fail("ProtocolException should have been thrown");
-        } catch (ProtocolException ex) {
+        } catch (final ProtocolException ex) {
             // expected
         }
    }
 
     @Test
     public void testRequestContentNullEntity() throws Exception {
-        HttpContext context = new BasicHttpContext(null);
-        BasicHttpRequest request = new BasicHttpEntityEnclosingRequest("POST", "/");
+        final HttpContext context = new BasicHttpContext(null);
+        final BasicHttpRequest request = new BasicHttpEntityEnclosingRequest("POST", "/");
 
-        RequestContent interceptor = new RequestContent();
+        final RequestContent interceptor = new RequestContent();
         interceptor.process(request, context);
-        Header header = request.getFirstHeader(HTTP.CONTENT_LEN);
+        final Header header = request.getFirstHeader(HTTP.CONTENT_LEN);
         Assert.assertNotNull(header);
         Assert.assertEquals("0", header.getValue());
         Assert.assertNull(request.getFirstHeader(HTTP.TRANSFER_ENCODING));
@@ -133,15 +132,15 @@ public class TestStandardInterceptors {
 
     @Test
     public void testRequestContentEntityContentLengthDelimitedHTTP11() throws Exception {
-        HttpContext context = new BasicHttpContext(null);
-        BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/");
-        String s = "whatever";
-        StringEntity entity = new StringEntity(s, "US-ASCII");
+        final HttpContext context = new BasicHttpContext(null);
+        final BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/");
+        final String s = "whatever";
+        final StringEntity entity = new StringEntity(s, "US-ASCII");
         request.setEntity(entity);
 
-        RequestContent interceptor = new RequestContent();
+        final RequestContent interceptor = new RequestContent();
         interceptor.process(request, context);
-        Header header = request.getFirstHeader(HTTP.CONTENT_LEN);
+        final Header header = request.getFirstHeader(HTTP.CONTENT_LEN);
         Assert.assertNotNull(header);
         Assert.assertEquals(s.length(), Integer.parseInt(header.getValue()));
         Assert.assertNull(request.getFirstHeader(HTTP.TRANSFER_ENCODING));
@@ -149,16 +148,16 @@ public class TestStandardInterceptors {
 
     @Test
     public void testRequestContentEntityChunkedHTTP11() throws Exception {
-        HttpContext context = new BasicHttpContext(null);
-        BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/");
-        String s = "whatever";
-        StringEntity entity = new StringEntity(s, "US-ASCII");
+        final HttpContext context = new BasicHttpContext(null);
+        final BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/");
+        final String s = "whatever";
+        final StringEntity entity = new StringEntity(s, "US-ASCII");
         entity.setChunked(true);
         request.setEntity(entity);
 
-        RequestContent interceptor = new RequestContent();
+        final RequestContent interceptor = new RequestContent();
         interceptor.process(request, context);
-        Header header = request.getFirstHeader(HTTP.TRANSFER_ENCODING);
+        final Header header = request.getFirstHeader(HTTP.TRANSFER_ENCODING);
         Assert.assertNotNull(header);
         Assert.assertEquals("chunked", header.getValue());
         Assert.assertNull(request.getFirstHeader(HTTP.CONTENT_LEN));
@@ -166,16 +165,16 @@ public class TestStandardInterceptors {
 
     @Test
     public void testRequestContentEntityUnknownLengthHTTP11() throws Exception {
-        HttpContext context = new BasicHttpContext(null);
-        BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/");
-        BasicHttpEntity entity = new BasicHttpEntity();
+        final HttpContext context = new BasicHttpContext(null);
+        final BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/");
+        final BasicHttpEntity entity = new BasicHttpEntity();
         entity.setContentLength(-1);
         entity.setChunked(false);
         request.setEntity(entity);
 
-        RequestContent interceptor = new RequestContent();
+        final RequestContent interceptor = new RequestContent();
         interceptor.process(request, context);
-        Header header = request.getFirstHeader(HTTP.TRANSFER_ENCODING);
+        final Header header = request.getFirstHeader(HTTP.TRANSFER_ENCODING);
         Assert.assertNotNull(header);
         Assert.assertEquals("chunked", header.getValue());
         Assert.assertNull(request.getFirstHeader(HTTP.CONTENT_LEN));
@@ -183,50 +182,50 @@ public class TestStandardInterceptors {
 
     @Test
     public void testRequestContentEntityChunkedHTTP10() throws Exception {
-        HttpContext context = new BasicHttpContext(null);
-        BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest(
+        final HttpContext context = new BasicHttpContext(null);
+        final BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest(
                 "POST", "/", HttpVersion.HTTP_1_0);
-        String s = "whatever";
-        StringEntity entity = new StringEntity(s, "US-ASCII");
+        final String s = "whatever";
+        final StringEntity entity = new StringEntity(s, "US-ASCII");
         entity.setChunked(true);
         request.setEntity(entity);
 
-        RequestContent interceptor = new RequestContent();
+        final RequestContent interceptor = new RequestContent();
         try {
             interceptor.process(request, context);
             Assert.fail("ProtocolException should have been thrown");
-        } catch (ProtocolException ex) {
+        } catch (final ProtocolException ex) {
             // expected
         }
     }
 
     @Test
     public void testRequestContentTypeAndEncoding() throws Exception {
-        HttpContext context = new BasicHttpContext(null);
-        BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/");
-        BasicHttpEntity entity = new BasicHttpEntity();
+        final HttpContext context = new BasicHttpContext(null);
+        final BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/");
+        final BasicHttpEntity entity = new BasicHttpEntity();
         entity.setContentType("whatever");
         entity.setContentEncoding("whatever");
         request.setEntity(entity);
 
-        RequestContent interceptor = new RequestContent();
+        final RequestContent interceptor = new RequestContent();
         interceptor.process(request, context);
-        Header h1 = request.getFirstHeader(HTTP.CONTENT_TYPE);
+        final Header h1 = request.getFirstHeader(HTTP.CONTENT_TYPE);
         Assert.assertNotNull(h1);
         Assert.assertEquals("whatever", h1.getValue());
-        Header h2 = request.getFirstHeader(HTTP.CONTENT_ENCODING);
+        final Header h2 = request.getFirstHeader(HTTP.CONTENT_ENCODING);
         Assert.assertNotNull(h2);
         Assert.assertEquals("whatever", h2.getValue());
     }
 
     @Test
     public void testRequestContentNullTypeAndEncoding() throws Exception {
-        HttpContext context = new BasicHttpContext(null);
-        BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/");
-        BasicHttpEntity entity = new BasicHttpEntity();
+        final HttpContext context = new BasicHttpContext(null);
+        final BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/");
+        final BasicHttpEntity entity = new BasicHttpEntity();
         request.setEntity(entity);
 
-        RequestContent interceptor = new RequestContent();
+        final RequestContent interceptor = new RequestContent();
         interceptor.process(request, context);
         Assert.assertNull(request.getFirstHeader(HTTP.CONTENT_TYPE));
         Assert.assertNull(request.getFirstHeader(HTTP.CONTENT_ENCODING));
@@ -234,48 +233,48 @@ public class TestStandardInterceptors {
 
     @Test
     public void testRequestContentEntityUnknownLengthHTTP10() throws Exception {
-        HttpContext context = new BasicHttpContext(null);
-        BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest(
+        final HttpContext context = new BasicHttpContext(null);
+        final BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest(
                 "POST", "/", HttpVersion.HTTP_1_0);
-        BasicHttpEntity entity = new BasicHttpEntity();
+        final BasicHttpEntity entity = new BasicHttpEntity();
         entity.setContentLength(-1);
         entity.setChunked(false);
         request.setEntity(entity);
 
-        RequestContent interceptor = new RequestContent();
+        final RequestContent interceptor = new RequestContent();
         try {
             interceptor.process(request, context);
             Assert.fail("ProtocolException should have been thrown");
-        } catch (ProtocolException ex) {
+        } catch (final ProtocolException ex) {
             // expected
         }
    }
 
     @Test
     public void testRequestContentInvalidInput() throws Exception {
-        RequestContent interceptor = new RequestContent();
+        final RequestContent interceptor = new RequestContent();
         try {
             interceptor.process(null, null);
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
             // expected
         }
     }
 
     @Test
     public void testRequestContentIgnoreNonenclosingRequests() throws Exception {
-        HttpContext context = new BasicHttpContext(null);
-        BasicHttpRequest request = new BasicHttpRequest("POST", "/");
-        RequestContent interceptor = new RequestContent();
+        final HttpContext context = new BasicHttpContext(null);
+        final BasicHttpRequest request = new BasicHttpRequest("POST", "/");
+        final RequestContent interceptor = new RequestContent();
         interceptor.process(request, context);
         Assert.assertEquals(0, request.getAllHeaders().length);
     }
 
     @Test
     public void testRequestContentOverwriteHeaders() throws Exception {
-        RequestContent interceptor = new RequestContent(true);
-        HttpContext context = new BasicHttpContext(null);
-        BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/");
+        final RequestContent interceptor = new RequestContent(true);
+        final HttpContext context = new BasicHttpContext(null);
+        final BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/");
         request.addHeader(new BasicHeader(HTTP.CONTENT_LEN, "10"));
         request.addHeader(new BasicHeader(HTTP.TRANSFER_ENCODING, "whatever"));
         interceptor.process(request, context);
@@ -284,9 +283,9 @@ public class TestStandardInterceptors {
 
     @Test
     public void testRequestContentAddHeaders() throws Exception {
-        RequestContent interceptor = new RequestContent(true);
-        HttpContext context = new BasicHttpContext(null);
-        BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/");
+        final RequestContent interceptor = new RequestContent(true);
+        final HttpContext context = new BasicHttpContext(null);
+        final BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/");
         interceptor.process(request, context);
         Assert.assertEquals("0", request.getFirstHeader(HTTP.CONTENT_LEN).getValue());
         Assert.assertNull(request.getFirstHeader(HTTP.TRANSFER_ENCODING));
@@ -294,379 +293,360 @@ public class TestStandardInterceptors {
 
     @Test
     public void testRequestExpectContinueGenerated() throws Exception {
-        HttpContext context = new BasicHttpContext(null);
-        BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/");
-        String s = "whatever";
-        StringEntity entity = new StringEntity(s, "US-ASCII");
+        final HttpCoreContext context = HttpCoreContext.create();
+        final BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/");
+        final String s = "whatever";
+        final StringEntity entity = new StringEntity(s, "US-ASCII");
         request.setEntity(entity);
-        request.getParams().setBooleanParameter(CoreProtocolPNames.USE_EXPECT_CONTINUE, true);
-        RequestExpectContinue interceptor = new RequestExpectContinue();
+        final RequestExpectContinue interceptor = new RequestExpectContinue(true);
         interceptor.process(request, context);
-        Header header = request.getFirstHeader(HTTP.EXPECT_DIRECTIVE);
+        final Header header = request.getFirstHeader(HTTP.EXPECT_DIRECTIVE);
         Assert.assertNotNull(header);
         Assert.assertEquals(HTTP.EXPECT_CONTINUE, header.getValue());
     }
 
     @Test
-    public void testRequestExpectContinueNotGenerated() throws Exception {
-        HttpContext context = new BasicHttpContext(null);
-        BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/");
-        String s = "whatever";
-        StringEntity entity = new StringEntity(s, "US-ASCII");
-        request.setEntity(entity);
-        request.getParams().setBooleanParameter(CoreProtocolPNames.USE_EXPECT_CONTINUE, false);
-        RequestExpectContinue interceptor = new RequestExpectContinue();
-        interceptor.process(request, context);
-        Header header = request.getFirstHeader(HTTP.EXPECT_DIRECTIVE);
-        Assert.assertNull(header);
-    }
-
-    @Test
     public void testRequestExpectContinueHTTP10() throws Exception {
-        HttpContext context = new BasicHttpContext(null);
-        BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest(
+        final HttpCoreContext context = HttpCoreContext.create();
+        final BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest(
                 "POST", "/", HttpVersion.HTTP_1_0);
-        String s = "whatever";
-        StringEntity entity = new StringEntity(s, "US-ASCII");
+        final String s = "whatever";
+        final StringEntity entity = new StringEntity(s, "US-ASCII");
         request.setEntity(entity);
-        request.getParams().setBooleanParameter(CoreProtocolPNames.USE_EXPECT_CONTINUE, true);
-        RequestExpectContinue interceptor = new RequestExpectContinue();
+        final RequestExpectContinue interceptor = new RequestExpectContinue(true);
         interceptor.process(request, context);
-        Header header = request.getFirstHeader(HTTP.EXPECT_DIRECTIVE);
+        final Header header = request.getFirstHeader(HTTP.EXPECT_DIRECTIVE);
         Assert.assertNull(header);
     }
 
     @Test
     public void testRequestExpectContinueZeroContent() throws Exception {
-        HttpContext context = new BasicHttpContext(null);
-        BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/");
-        String s = "";
-        StringEntity entity = new StringEntity(s, "US-ASCII");
+        final HttpCoreContext context = HttpCoreContext.create();
+        final BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/");
+        final String s = "";
+        final StringEntity entity = new StringEntity(s, "US-ASCII");
         request.setEntity(entity);
-        request.getParams().setBooleanParameter(CoreProtocolPNames.USE_EXPECT_CONTINUE, true);
-        RequestExpectContinue interceptor = new RequestExpectContinue();
+        final RequestExpectContinue interceptor = new RequestExpectContinue(true);
         interceptor.process(request, context);
-        Header header = request.getFirstHeader(HTTP.EXPECT_DIRECTIVE);
+        final Header header = request.getFirstHeader(HTTP.EXPECT_DIRECTIVE);
         Assert.assertNull(header);
     }
 
     @Test
     public void testRequestExpectContinueInvalidInput() throws Exception {
-        RequestExpectContinue interceptor = new RequestExpectContinue();
+        final RequestExpectContinue interceptor = new RequestExpectContinue(true);
         try {
             interceptor.process(null, null);
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
             // expected
         }
     }
 
     @Test
     public void testRequestExpectContinueIgnoreNonenclosingRequests() throws Exception {
-        HttpContext context = new BasicHttpContext(null);
-        BasicHttpRequest request = new BasicHttpRequest("POST", "/");
-        RequestExpectContinue interceptor = new RequestExpectContinue();
+        final HttpContext context = new BasicHttpContext(null);
+        final BasicHttpRequest request = new BasicHttpRequest("POST", "/");
+        final RequestExpectContinue interceptor = new RequestExpectContinue(true);
         interceptor.process(request, context);
         Assert.assertEquals(0, request.getAllHeaders().length);
     }
 
     @Test
     public void testRequestTargetHostGenerated() throws Exception {
-        HttpContext context = new BasicHttpContext(null);
-        HttpHost host = new HttpHost("somehost", 8080, "http");
-        context.setAttribute(ExecutionContext.HTTP_TARGET_HOST, host);
-        BasicHttpRequest request = new BasicHttpRequest("GET", "/");
-        RequestTargetHost interceptor = new RequestTargetHost();
+        final HttpContext context = new BasicHttpContext(null);
+        final HttpHost host = new HttpHost("somehost", 8080, "http");
+        context.setAttribute(HttpCoreContext.HTTP_TARGET_HOST, host);
+        final BasicHttpRequest request = new BasicHttpRequest("GET", "/");
+        final RequestTargetHost interceptor = new RequestTargetHost();
         interceptor.process(request, context);
-        Header header = request.getFirstHeader(HTTP.TARGET_HOST);
+        final Header header = request.getFirstHeader(HTTP.TARGET_HOST);
         Assert.assertNotNull(header);
         Assert.assertEquals("somehost:8080", header.getValue());
     }
 
     @Test
     public void testRequestTargetHostFallback() throws Exception {
-        HttpContext context = new BasicHttpContext(null);
-        BasicHttpRequest request = new BasicHttpRequest("GET", "/");
-        InetAddress address = Mockito.mock(InetAddress.class);
+        final HttpContext context = new BasicHttpContext(null);
+        final BasicHttpRequest request = new BasicHttpRequest("GET", "/");
+        final InetAddress address = Mockito.mock(InetAddress.class);
         Mockito.when(address.getHostName()).thenReturn("somehost");
-        HttpInetConnection conn = Mockito.mock(HttpInetConnection.class);
+        final HttpInetConnection conn = Mockito.mock(HttpInetConnection.class);
         Mockito.when(conn.getRemoteAddress()).thenReturn(address);
         Mockito.when(conn.getRemotePort()).thenReturn(1234);
-        context.setAttribute(ExecutionContext.HTTP_TARGET_HOST, null);
-        context.setAttribute(ExecutionContext.HTTP_CONNECTION, conn);
-        RequestTargetHost interceptor = new RequestTargetHost();
+        context.setAttribute(HttpCoreContext.HTTP_TARGET_HOST, null);
+        context.setAttribute(HttpCoreContext.HTTP_CONNECTION, conn);
+        final RequestTargetHost interceptor = new RequestTargetHost();
         interceptor.process(request, context);
-        Header header = request.getFirstHeader(HTTP.TARGET_HOST);
+        final Header header = request.getFirstHeader(HTTP.TARGET_HOST);
         Assert.assertNotNull(header);
         Assert.assertEquals("somehost:1234", header.getValue());
     }
 
     @Test(expected=ProtocolException.class)
     public void testRequestTargetHostFallbackFailure() throws Exception {
-        HttpContext context = new BasicHttpContext(null);
-        BasicHttpRequest request = new BasicHttpRequest("GET", "/");
-        HttpInetConnection conn = Mockito.mock(HttpInetConnection.class);
+        final HttpContext context = new BasicHttpContext(null);
+        final BasicHttpRequest request = new BasicHttpRequest("GET", "/");
+        final HttpInetConnection conn = Mockito.mock(HttpInetConnection.class);
         Mockito.when(conn.getRemoteAddress()).thenReturn(null);
         Mockito.when(conn.getRemotePort()).thenReturn(1234);
-        context.setAttribute(ExecutionContext.HTTP_TARGET_HOST, null);
-        context.setAttribute(ExecutionContext.HTTP_CONNECTION, conn);
-        RequestTargetHost interceptor = new RequestTargetHost();
+        context.setAttribute(HttpCoreContext.HTTP_TARGET_HOST, null);
+        context.setAttribute(HttpCoreContext.HTTP_CONNECTION, conn);
+        final RequestTargetHost interceptor = new RequestTargetHost();
         interceptor.process(request, context);
     }
 
     @Test
     public void testRequestTargetHostNotGenerated() throws Exception {
-        HttpContext context = new BasicHttpContext(null);
-        HttpHost host = new HttpHost("somehost", 8080, "http");
-        context.setAttribute(ExecutionContext.HTTP_TARGET_HOST, host);
-        BasicHttpRequest request = new BasicHttpRequest("GET", "/");
+        final HttpContext context = new BasicHttpContext(null);
+        final HttpHost host = new HttpHost("somehost", 8080, "http");
+        context.setAttribute(HttpCoreContext.HTTP_TARGET_HOST, host);
+        final BasicHttpRequest request = new BasicHttpRequest("GET", "/");
         request.addHeader(new BasicHeader(HTTP.TARGET_HOST, "whatever"));
-        RequestTargetHost interceptor = new RequestTargetHost();
+        final RequestTargetHost interceptor = new RequestTargetHost();
         interceptor.process(request, context);
-        Header header = request.getFirstHeader(HTTP.TARGET_HOST);
+        final Header header = request.getFirstHeader(HTTP.TARGET_HOST);
         Assert.assertNotNull(header);
         Assert.assertEquals("whatever", header.getValue());
     }
 
     @Test
     public void testRequestTargetHostMissingHostHTTP10() throws Exception {
-        HttpContext context = new BasicHttpContext(null);
-        BasicHttpRequest request = new BasicHttpRequest(
+        final HttpContext context = new BasicHttpContext(null);
+        final BasicHttpRequest request = new BasicHttpRequest(
                 "GET", "/", HttpVersion.HTTP_1_0);
-        RequestTargetHost interceptor = new RequestTargetHost();
+        final RequestTargetHost interceptor = new RequestTargetHost();
         interceptor.process(request, context);
-        Header header = request.getFirstHeader(HTTP.TARGET_HOST);
+        final Header header = request.getFirstHeader(HTTP.TARGET_HOST);
         Assert.assertNull(header);
     }
 
     @Test
     public void testRequestTargetHostMissingHostHTTP11() throws Exception {
-        HttpContext context = new BasicHttpContext(null);
-        BasicHttpRequest request = new BasicHttpRequest("GET", "/");
-        RequestTargetHost interceptor = new RequestTargetHost();
+        final HttpContext context = new BasicHttpContext(null);
+        final BasicHttpRequest request = new BasicHttpRequest("GET", "/");
+        final RequestTargetHost interceptor = new RequestTargetHost();
         try {
             interceptor.process(request, context);
             Assert.fail("ProtocolException should have been thrown");
-        } catch (ProtocolException ex) {
+        } catch (final ProtocolException ex) {
             // expected
         }
     }
 
     @Test
     public void testRequestTargetHostInvalidInput() throws Exception {
-        RequestTargetHost interceptor = new RequestTargetHost();
+        final RequestTargetHost interceptor = new RequestTargetHost();
         try {
             interceptor.process(null, null);
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
             // expected
         }
         try {
             interceptor.process(new BasicHttpRequest("GET", "/"), null);
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
             // expected
         }
     }
 
     @Test
     public void testRequestTargetHostConnectHttp11() throws Exception {
-        HttpContext context = new BasicHttpContext(null);
-        HttpHost host = new HttpHost("somehost", 8080, "http");
-        context.setAttribute(ExecutionContext.HTTP_TARGET_HOST, host);
-        BasicHttpRequest request = new BasicHttpRequest("CONNECT", "/");
-        RequestTargetHost interceptor = new RequestTargetHost();
+        final HttpContext context = new BasicHttpContext(null);
+        final HttpHost host = new HttpHost("somehost", 8080, "http");
+        context.setAttribute(HttpCoreContext.HTTP_TARGET_HOST, host);
+        final BasicHttpRequest request = new BasicHttpRequest("CONNECT", "/");
+        final RequestTargetHost interceptor = new RequestTargetHost();
         interceptor.process(request, context);
-        Header header = request.getFirstHeader(HTTP.TARGET_HOST);
+        final Header header = request.getFirstHeader(HTTP.TARGET_HOST);
         Assert.assertNotNull(header);
         Assert.assertEquals("somehost:8080", header.getValue());
     }
 
     @Test
     public void testRequestTargetHostConnectHttp10() throws Exception {
-        HttpContext context = new BasicHttpContext(null);
-        HttpHost host = new HttpHost("somehost", 8080, "http");
-        context.setAttribute(ExecutionContext.HTTP_TARGET_HOST, host);
-        BasicHttpRequest request = new BasicHttpRequest("CONNECT", "/", HttpVersion.HTTP_1_0);
-        RequestTargetHost interceptor = new RequestTargetHost();
+        final HttpContext context = new BasicHttpContext(null);
+        final HttpHost host = new HttpHost("somehost", 8080, "http");
+        context.setAttribute(HttpCoreContext.HTTP_TARGET_HOST, host);
+        final BasicHttpRequest request = new BasicHttpRequest("CONNECT", "/", HttpVersion.HTTP_1_0);
+        final RequestTargetHost interceptor = new RequestTargetHost();
         interceptor.process(request, context);
-        Header header = request.getFirstHeader(HTTP.TARGET_HOST);
+        final Header header = request.getFirstHeader(HTTP.TARGET_HOST);
         Assert.assertNull(header);
     }
 
     @Test
     public void testRequestUserAgentGenerated() throws Exception {
-        HttpContext context = new BasicHttpContext(null);
-        BasicHttpRequest request = new BasicHttpRequest("GET", "/");
-        request.getParams().setParameter(CoreProtocolPNames.USER_AGENT, "some agent");
-        RequestUserAgent interceptor = new RequestUserAgent();
+        final HttpContext context = new BasicHttpContext(null);
+        final BasicHttpRequest request = new BasicHttpRequest("GET", "/");
+        final RequestUserAgent interceptor = new RequestUserAgent("some agent");
         interceptor.process(request, context);
-        Header header = request.getFirstHeader(HTTP.USER_AGENT);
+        final Header header = request.getFirstHeader(HTTP.USER_AGENT);
         Assert.assertNotNull(header);
         Assert.assertEquals("some agent", header.getValue());
     }
 
     @Test
     public void testRequestUserAgentNotGenerated() throws Exception {
-        HttpContext context = new BasicHttpContext(null);
-        BasicHttpRequest request = new BasicHttpRequest("GET", "/");
-        request.getParams().setParameter(CoreProtocolPNames.USER_AGENT, "some agent");
+        final HttpContext context = new BasicHttpContext(null);
+        final BasicHttpRequest request = new BasicHttpRequest("GET", "/");
         request.addHeader(new BasicHeader(HTTP.USER_AGENT, "whatever"));
-        RequestUserAgent interceptor = new RequestUserAgent();
+        final RequestUserAgent interceptor = new RequestUserAgent("some agent");
         interceptor.process(request, context);
-        Header header = request.getFirstHeader(HTTP.USER_AGENT);
+        final Header header = request.getFirstHeader(HTTP.USER_AGENT);
         Assert.assertNotNull(header);
         Assert.assertEquals("whatever", header.getValue());
     }
 
     @Test
     public void testRequestUserAgentMissingUserAgent() throws Exception {
-        HttpContext context = new BasicHttpContext(null);
-        BasicHttpRequest request = new BasicHttpRequest("GET", "/");
-        RequestUserAgent interceptor = new RequestUserAgent();
+        final HttpContext context = new BasicHttpContext(null);
+        final BasicHttpRequest request = new BasicHttpRequest("GET", "/");
+        final RequestUserAgent interceptor = new RequestUserAgent();
         interceptor.process(request, context);
-        Header header = request.getFirstHeader(HTTP.USER_AGENT);
+        final Header header = request.getFirstHeader(HTTP.USER_AGENT);
         Assert.assertNull(header);
     }
 
     @Test
     public void testRequestUserAgentInvalidInput() throws Exception {
-        RequestUserAgent interceptor = new RequestUserAgent();
+        final RequestUserAgent interceptor = new RequestUserAgent();
         try {
             interceptor.process(null, null);
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
             // expected
         }
     }
 
     @Test
     public void testResponseConnControlNoEntity() throws Exception {
-        HttpContext context = new BasicHttpContext(null);
-        HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK");
-        ResponseConnControl interceptor = new ResponseConnControl();
+        final HttpContext context = new BasicHttpContext(null);
+        final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK");
+        final ResponseConnControl interceptor = new ResponseConnControl();
         interceptor.process(response, context);
-        Header header = response.getFirstHeader(HTTP.CONN_DIRECTIVE);
+        final Header header = response.getFirstHeader(HTTP.CONN_DIRECTIVE);
         Assert.assertNull(header);
     }
 
     @Test
     public void testResponseConnControlEntityContentLength() throws Exception {
-        HttpContext context = new BasicHttpContext(null);
-        HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK");
-        StringEntity entity = new StringEntity("whatever");
+        final HttpContext context = new BasicHttpContext(null);
+        final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK");
+        final StringEntity entity = new StringEntity("whatever");
         response.setEntity(entity);
-        ResponseConnControl interceptor = new ResponseConnControl();
+        final ResponseConnControl interceptor = new ResponseConnControl();
         interceptor.process(response, context);
-        Header header = response.getFirstHeader(HTTP.CONN_DIRECTIVE);
+        final Header header = response.getFirstHeader(HTTP.CONN_DIRECTIVE);
         Assert.assertNull(header);
     }
 
     @Test
     public void testResponseConnControlEntityUnknownContentLength() throws Exception {
-        HttpContext context = new BasicHttpContext(null);
-        BasicHttpRequest request = new BasicHttpRequest("GET", "/");
+        final HttpContext context = new BasicHttpContext(null);
+        final BasicHttpRequest request = new BasicHttpRequest("GET", "/");
         request.addHeader(new BasicHeader(HTTP.CONN_DIRECTIVE, HTTP.CONN_KEEP_ALIVE));
-        context.setAttribute(ExecutionContext.HTTP_REQUEST, request);
-        HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK");
-        BasicHttpEntity entity = new BasicHttpEntity();
+        context.setAttribute(HttpCoreContext.HTTP_REQUEST, request);
+        final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK");
+        final BasicHttpEntity entity = new BasicHttpEntity();
         response.setEntity(entity);
-        ResponseConnControl interceptor = new ResponseConnControl();
+        final ResponseConnControl interceptor = new ResponseConnControl();
         interceptor.process(response, context);
-        Header header = response.getFirstHeader(HTTP.CONN_DIRECTIVE);
+        final Header header = response.getFirstHeader(HTTP.CONN_DIRECTIVE);
         Assert.assertNotNull(header);
         Assert.assertEquals(HTTP.CONN_CLOSE, header.getValue());
     }
 
     @Test
     public void testResponseConnControlEntityChunked() throws Exception {
-        HttpContext context = new BasicHttpContext(null);
-        HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK");
-        BasicHttpEntity entity = new BasicHttpEntity();
+        final HttpContext context = new BasicHttpContext(null);
+        final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK");
+        final BasicHttpEntity entity = new BasicHttpEntity();
         entity.setChunked(true);
         response.setEntity(entity);
-        ResponseConnControl interceptor = new ResponseConnControl();
+        final ResponseConnControl interceptor = new ResponseConnControl();
         interceptor.process(response, context);
-        Header header = response.getFirstHeader(HTTP.CONN_DIRECTIVE);
+        final Header header = response.getFirstHeader(HTTP.CONN_DIRECTIVE);
         Assert.assertNull(header);
     }
 
     @Test
     public void testResponseConnControlEntityUnknownContentLengthHTTP10() throws Exception {
-        HttpContext context = new BasicHttpContext(null);
-        BasicHttpRequest request = new BasicHttpRequest("GET", "/");
+        final HttpContext context = new BasicHttpContext(null);
+        final BasicHttpRequest request = new BasicHttpRequest("GET", "/");
         request.addHeader(new BasicHeader(HTTP.CONN_DIRECTIVE, HTTP.CONN_KEEP_ALIVE));
-        context.setAttribute(ExecutionContext.HTTP_REQUEST, request);
+        context.setAttribute(HttpCoreContext.HTTP_REQUEST, request);
 
-        BasicHttpResponse response = new BasicHttpResponse(
+        final BasicHttpResponse response = new BasicHttpResponse(
                 HttpVersion.HTTP_1_0, HttpStatus.SC_OK, "OK");
-        BasicHttpEntity entity = new BasicHttpEntity();
+        final BasicHttpEntity entity = new BasicHttpEntity();
         response.setEntity(entity);
-        ResponseConnControl interceptor = new ResponseConnControl();
+        final ResponseConnControl interceptor = new ResponseConnControl();
         interceptor.process(response, context);
-        Header header = response.getFirstHeader(HTTP.CONN_DIRECTIVE);
+        final Header header = response.getFirstHeader(HTTP.CONN_DIRECTIVE);
         Assert.assertNotNull(header);
         Assert.assertEquals(HTTP.CONN_CLOSE, header.getValue());
     }
 
     @Test
     public void testResponseConnControlClientRequest() throws Exception {
-        HttpContext context = new BasicHttpContext(null);
-        BasicHttpRequest request = new BasicHttpRequest("GET", "/");
+        final HttpContext context = new BasicHttpContext(null);
+        final BasicHttpRequest request = new BasicHttpRequest("GET", "/");
         request.addHeader(new BasicHeader(HTTP.CONN_DIRECTIVE, HTTP.CONN_KEEP_ALIVE));
-        context.setAttribute(ExecutionContext.HTTP_REQUEST, request);
+        context.setAttribute(HttpCoreContext.HTTP_REQUEST, request);
 
-        HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK");
-        StringEntity entity = new StringEntity("whatever");
+        final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK");
+        final StringEntity entity = new StringEntity("whatever");
         response.setEntity(entity);
-        ResponseConnControl interceptor = new ResponseConnControl();
+        final ResponseConnControl interceptor = new ResponseConnControl();
         interceptor.process(response, context);
-        Header header = response.getFirstHeader(HTTP.CONN_DIRECTIVE);
+        final Header header = response.getFirstHeader(HTTP.CONN_DIRECTIVE);
         Assert.assertNotNull(header);
         Assert.assertEquals(HTTP.CONN_KEEP_ALIVE, header.getValue());
     }
 
     @Test
     public void testResponseConnControlClientRequest2() throws Exception {
-        HttpContext context = new BasicHttpContext(null);
-        BasicHttpRequest request = new BasicHttpRequest("GET", "/");
-        context.setAttribute(ExecutionContext.HTTP_REQUEST, request);
+        final HttpContext context = new BasicHttpContext(null);
+        final BasicHttpRequest request = new BasicHttpRequest("GET", "/");
+        context.setAttribute(HttpCoreContext.HTTP_REQUEST, request);
 
-        HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK");
-        StringEntity entity = new StringEntity("whatever");
+        final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK");
+        final StringEntity entity = new StringEntity("whatever");
         response.setEntity(entity);
-        ResponseConnControl interceptor = new ResponseConnControl();
+        final ResponseConnControl interceptor = new ResponseConnControl();
         interceptor.process(response, context);
-        Header header = response.getFirstHeader(HTTP.CONN_DIRECTIVE);
+        final Header header = response.getFirstHeader(HTTP.CONN_DIRECTIVE);
         Assert.assertNull(header);
     }
 
     @Test
     public void testResponseConnControl10Client11Response() throws Exception {
-        HttpContext context = new BasicHttpContext(null);
-        BasicHttpRequest request = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_0);
-        context.setAttribute(ExecutionContext.HTTP_REQUEST, request);
+        final HttpContext context = new BasicHttpContext(null);
+        final BasicHttpRequest request = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_0);
+        context.setAttribute(HttpCoreContext.HTTP_REQUEST, request);
 
-        HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK");
-        StringEntity entity = new StringEntity("whatever");
+        final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK");
+        final StringEntity entity = new StringEntity("whatever");
         response.setEntity(entity);
-        ResponseConnControl interceptor = new ResponseConnControl();
+        final ResponseConnControl interceptor = new ResponseConnControl();
         interceptor.process(response, context);
-        Header header = response.getFirstHeader(HTTP.CONN_DIRECTIVE);
+        final Header header = response.getFirstHeader(HTTP.CONN_DIRECTIVE);
         Assert.assertNotNull(header);
         Assert.assertEquals(HTTP.CONN_CLOSE, header.getValue());
     }
 
     @Test
     public void testResponseConnControlStatusCode() throws Exception {
-        HttpContext context = new BasicHttpContext(null);
-        BasicHttpRequest request = new BasicHttpRequest("GET", "/");
+        final HttpContext context = new BasicHttpContext(null);
+        final BasicHttpRequest request = new BasicHttpRequest("GET", "/");
         request.addHeader(new BasicHeader(HTTP.CONN_DIRECTIVE, HTTP.CONN_KEEP_ALIVE));
-        context.setAttribute(ExecutionContext.HTTP_REQUEST, request);
+        context.setAttribute(HttpCoreContext.HTTP_REQUEST, request);
 
-        ResponseConnControl interceptor = new ResponseConnControl();
+        final ResponseConnControl interceptor = new ResponseConnControl();
 
-        int [] statusCodes = new int[] {
+        final int [] statusCodes = new int[] {
                 HttpStatus.SC_BAD_REQUEST,
                 HttpStatus.SC_REQUEST_TIMEOUT,
                 HttpStatus.SC_LENGTH_REQUIRED,
@@ -675,11 +655,11 @@ public class TestStandardInterceptors {
                 HttpStatus.SC_SERVICE_UNAVAILABLE,
                 HttpStatus.SC_NOT_IMPLEMENTED };
 
-        for (int i = 0; i < statusCodes.length; i++) {
-            BasicHttpResponse response = new BasicHttpResponse(
-                    HttpVersion.HTTP_1_1, statusCodes[i], "Unreasonable");
+        for (final int statusCode : statusCodes) {
+            final BasicHttpResponse response = new BasicHttpResponse(
+                    HttpVersion.HTTP_1_1, statusCode, "Unreasonable");
             interceptor.process(response, context);
-            Header header = response.getFirstHeader(HTTP.CONN_DIRECTIVE);
+            final Header header = response.getFirstHeader(HTTP.CONN_DIRECTIVE);
             Assert.assertNotNull(header);
             Assert.assertEquals(HTTP.CONN_CLOSE, header.getValue());
         }
@@ -688,215 +668,215 @@ public class TestStandardInterceptors {
 
     @Test
     public void testResponseConnControlExplicitClose() throws Exception {
-        HttpContext context = new BasicHttpContext(null);
-        BasicHttpRequest request = new BasicHttpRequest("GET", "/");
+        final HttpContext context = new BasicHttpContext(null);
+        final BasicHttpRequest request = new BasicHttpRequest("GET", "/");
         request.addHeader(new BasicHeader(HTTP.CONN_DIRECTIVE, HTTP.CONN_KEEP_ALIVE));
-        context.setAttribute(ExecutionContext.HTTP_REQUEST, request);
+        context.setAttribute(HttpCoreContext.HTTP_REQUEST, request);
 
-        ResponseConnControl interceptor = new ResponseConnControl();
+        final ResponseConnControl interceptor = new ResponseConnControl();
 
-        BasicHttpResponse response = new BasicHttpResponse(
+        final BasicHttpResponse response = new BasicHttpResponse(
                 HttpVersion.HTTP_1_1, 200, "OK");
         response.setHeader(HTTP.CONN_DIRECTIVE, HTTP.CONN_CLOSE);
         interceptor.process(response, context);
-        Header header = response.getFirstHeader(HTTP.CONN_DIRECTIVE);
+        final Header header = response.getFirstHeader(HTTP.CONN_DIRECTIVE);
         Assert.assertNotNull(header);
         Assert.assertEquals(HTTP.CONN_CLOSE, header.getValue());
     }
 
     @Test
     public void testResponseConnControlHostInvalidInput() throws Exception {
-        ResponseConnControl interceptor = new ResponseConnControl();
+        final ResponseConnControl interceptor = new ResponseConnControl();
         try {
             interceptor.process(null, null);
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
             // expected
         }
         try {
-            HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK");
+            final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK");
             interceptor.process(response, null);
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
             // expected
         }
     }
 
     @Test
     public void testResponseContentNoEntity() throws Exception {
-        HttpContext context = new BasicHttpContext(null);
-        HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK");
-        ResponseContent interceptor = new ResponseContent();
+        final HttpContext context = new BasicHttpContext(null);
+        final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK");
+        final ResponseContent interceptor = new ResponseContent();
         interceptor.process(response, context);
-        Header header = response.getFirstHeader(HTTP.CONTENT_LEN);
+        final Header header = response.getFirstHeader(HTTP.CONTENT_LEN);
         Assert.assertNotNull(header);
         Assert.assertEquals("0", header.getValue());
     }
 
     @Test
     public void testResponseContentStatusNoContent() throws Exception {
-        HttpContext context = new BasicHttpContext(null);
-        HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK");
+        final HttpContext context = new BasicHttpContext(null);
+        final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK");
         response.setStatusCode(HttpStatus.SC_NO_CONTENT);
-        ResponseContent interceptor = new ResponseContent();
+        final ResponseContent interceptor = new ResponseContent();
         interceptor.process(response, context);
-        Header header = response.getFirstHeader(HTTP.CONTENT_LEN);
+        final Header header = response.getFirstHeader(HTTP.CONTENT_LEN);
         Assert.assertNull(header);
     }
 
     @Test
     public void testResponseContentStatusResetContent() throws Exception {
-        HttpContext context = new BasicHttpContext(null);
-        HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK");
+        final HttpContext context = new BasicHttpContext(null);
+        final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK");
         response.setStatusCode(HttpStatus.SC_RESET_CONTENT);
-        ResponseContent interceptor = new ResponseContent();
+        final ResponseContent interceptor = new ResponseContent();
         interceptor.process(response, context);
-        Header header = response.getFirstHeader(HTTP.CONTENT_LEN);
+        final Header header = response.getFirstHeader(HTTP.CONTENT_LEN);
         Assert.assertNull(header);
     }
 
     @Test
     public void testResponseContentStatusNotModified() throws Exception {
-        HttpContext context = new BasicHttpContext(null);
-        HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK");
+        final HttpContext context = new BasicHttpContext(null);
+        final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK");
         response.setStatusCode(HttpStatus.SC_NOT_MODIFIED);
-        ResponseContent interceptor = new ResponseContent();
+        final ResponseContent interceptor = new ResponseContent();
         interceptor.process(response, context);
-        Header header = response.getFirstHeader(HTTP.CONTENT_LEN);
+        final Header header = response.getFirstHeader(HTTP.CONTENT_LEN);
         Assert.assertNull(header);
     }
 
     @Test
     public void testResponseContentEntityChunked() throws Exception {
-        HttpContext context = new BasicHttpContext(null);
-        HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK");
-        BasicHttpEntity entity = new BasicHttpEntity();
+        final HttpContext context = new BasicHttpContext(null);
+        final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK");
+        final BasicHttpEntity entity = new BasicHttpEntity();
         entity.setChunked(true);
         response.setEntity(entity);
-        ResponseContent interceptor = new ResponseContent();
+        final ResponseContent interceptor = new ResponseContent();
         interceptor.process(response, context);
-        Header h1 = response.getFirstHeader(HTTP.TRANSFER_ENCODING);
+        final Header h1 = response.getFirstHeader(HTTP.TRANSFER_ENCODING);
         Assert.assertNotNull(h1);
         Assert.assertEquals(HTTP.CHUNK_CODING, h1.getValue());
-        Header h2 = response.getFirstHeader(HTTP.CONTENT_LEN);
+        final Header h2 = response.getFirstHeader(HTTP.CONTENT_LEN);
         Assert.assertNull(h2);
     }
 
     @Test
     public void testResponseContentEntityContentLenghtDelimited() throws Exception {
-        HttpContext context = new BasicHttpContext(null);
-        HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK");
-        BasicHttpEntity entity = new BasicHttpEntity();
+        final HttpContext context = new BasicHttpContext(null);
+        final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK");
+        final BasicHttpEntity entity = new BasicHttpEntity();
         entity.setContentLength (10);
         response.setEntity(entity);
-        ResponseContent interceptor = new ResponseContent();
+        final ResponseContent interceptor = new ResponseContent();
         interceptor.process(response, context);
-        Header h1 = response.getFirstHeader(HTTP.CONTENT_LEN);
+        final Header h1 = response.getFirstHeader(HTTP.CONTENT_LEN);
         Assert.assertNotNull(h1);
         Assert.assertEquals("10", h1.getValue());
-        Header h2 = response.getFirstHeader(HTTP.TRANSFER_ENCODING);
+        final Header h2 = response.getFirstHeader(HTTP.TRANSFER_ENCODING);
         Assert.assertNull(h2);
     }
 
     @Test
     public void testResponseContentEntityUnknownContentLength() throws Exception {
-        HttpContext context = new BasicHttpContext(null);
-        HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK");
-        BasicHttpEntity entity = new BasicHttpEntity();
+        final HttpContext context = new BasicHttpContext(null);
+        final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK");
+        final BasicHttpEntity entity = new BasicHttpEntity();
         response.setEntity(entity);
-        ResponseContent interceptor = new ResponseContent();
+        final ResponseContent interceptor = new ResponseContent();
         interceptor.process(response, context);
-        Header h1 = response.getFirstHeader(HTTP.TRANSFER_ENCODING);
+        final Header h1 = response.getFirstHeader(HTTP.TRANSFER_ENCODING);
         Assert.assertNull(h1);
-        Header h2 = response.getFirstHeader(HTTP.CONTENT_LEN);
+        final Header h2 = response.getFirstHeader(HTTP.CONTENT_LEN);
         Assert.assertNull(h2);
     }
 
     @Test
     public void testResponseContentEntityChunkedHTTP10() throws Exception {
-        HttpContext context = new BasicHttpContext(null);
-        BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_0, HttpStatus.SC_OK, "OK");
-        BasicHttpEntity entity = new BasicHttpEntity();
+        final HttpContext context = new BasicHttpContext(null);
+        final BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_0, HttpStatus.SC_OK, "OK");
+        final BasicHttpEntity entity = new BasicHttpEntity();
         entity.setChunked(true);
         response.setEntity(entity);
-        ResponseContent interceptor = new ResponseContent();
+        final ResponseContent interceptor = new ResponseContent();
         interceptor.process(response, context);
-        Header h1 = response.getFirstHeader(HTTP.TRANSFER_ENCODING);
+        final Header h1 = response.getFirstHeader(HTTP.TRANSFER_ENCODING);
         Assert.assertNull(h1);
-        Header h2 = response.getFirstHeader(HTTP.CONTENT_LEN);
+        final Header h2 = response.getFirstHeader(HTTP.CONTENT_LEN);
         Assert.assertNull(h2);
     }
 
     @Test
     public void testResponseContentEntityNoContentTypeAndEncoding() throws Exception {
-        HttpContext context = new BasicHttpContext(null);
-        HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK");
-        BasicHttpEntity entity = new BasicHttpEntity();
+        final HttpContext context = new BasicHttpContext(null);
+        final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK");
+        final BasicHttpEntity entity = new BasicHttpEntity();
         response.setEntity(entity);
-        ResponseContent interceptor = new ResponseContent();
+        final ResponseContent interceptor = new ResponseContent();
         interceptor.process(response, context);
-        Header h1 = response.getFirstHeader(HTTP.CONTENT_TYPE);
+        final Header h1 = response.getFirstHeader(HTTP.CONTENT_TYPE);
         Assert.assertNull(h1);
-        Header h2 = response.getFirstHeader(HTTP.CONTENT_ENCODING);
+        final Header h2 = response.getFirstHeader(HTTP.CONTENT_ENCODING);
         Assert.assertNull(h2);
     }
 
     @Test
     public void testResponseContentEntityContentTypeAndEncoding() throws Exception {
-        HttpContext context = new BasicHttpContext(null);
-        HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK");
-        BasicHttpEntity entity = new BasicHttpEntity();
+        final HttpContext context = new BasicHttpContext(null);
+        final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK");
+        final BasicHttpEntity entity = new BasicHttpEntity();
         entity.setContentEncoding("whatever");
         entity.setContentType("whatever");
         response.setEntity(entity);
-        ResponseContent interceptor = new ResponseContent();
+        final ResponseContent interceptor = new ResponseContent();
         interceptor.process(response, context);
-        Header h1 = response.getFirstHeader(HTTP.CONTENT_TYPE);
+        final Header h1 = response.getFirstHeader(HTTP.CONTENT_TYPE);
         Assert.assertNotNull(h1);
         Assert.assertEquals("whatever", h1.getValue());
-        Header h2 = response.getFirstHeader(HTTP.CONTENT_ENCODING);
+        final Header h2 = response.getFirstHeader(HTTP.CONTENT_ENCODING);
         Assert.assertNotNull(h2);
         Assert.assertEquals("whatever", h2.getValue());
     }
 
     @Test
     public void testResponseContentInvalidInput() throws Exception {
-        ResponseContent interceptor = new ResponseContent();
+        final ResponseContent interceptor = new ResponseContent();
         try {
             interceptor.process(null, null);
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
             // expected
         }
     }
 
     @Test
     public void testResponseContentInvalidResponseState() throws Exception {
-        ResponseContent interceptor = new ResponseContent();
-        HttpContext context = new BasicHttpContext(null);
+        final ResponseContent interceptor = new ResponseContent();
+        final HttpContext context = new BasicHttpContext(null);
         try {
-            HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK");
+            final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK");
             response.addHeader(new BasicHeader(HTTP.CONTENT_LEN, "10"));
             interceptor.process(response, context);
             Assert.fail("ProtocolException should have been thrown");
-        } catch (ProtocolException ex) {
+        } catch (final ProtocolException ex) {
             // expected
         }
         try {
-            HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK");
+            final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK");
             response.addHeader(new BasicHeader(HTTP.TRANSFER_ENCODING, "stuff"));
             interceptor.process(response, context);
             Assert.fail("ProtocolException should have been thrown");
-        } catch (ProtocolException ex) {
+        } catch (final ProtocolException ex) {
             // expected
         }
     }
 
     @Test
     public void testResponseContentOverwriteHeaders() throws Exception {
-        ResponseContent interceptor = new ResponseContent(true);
-        HttpContext context = new BasicHttpContext(null);
-        HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK");
+        final ResponseContent interceptor = new ResponseContent(true);
+        final HttpContext context = new BasicHttpContext(null);
+        final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK");
         response.addHeader(new BasicHeader(HTTP.CONTENT_LEN, "10"));
         response.addHeader(new BasicHeader(HTTP.TRANSFER_ENCODING, "whatever"));
         interceptor.process(response, context);
@@ -905,9 +885,9 @@ public class TestStandardInterceptors {
 
     @Test
     public void testResponseContentAddHeaders() throws Exception {
-        ResponseContent interceptor = new ResponseContent(true);
-        HttpContext context = new BasicHttpContext(null);
-        HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK");
+        final ResponseContent interceptor = new ResponseContent(true);
+        final HttpContext context = new BasicHttpContext(null);
+        final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK");
         interceptor.process(response, context);
         Assert.assertEquals("0", response.getFirstHeader(HTTP.CONTENT_LEN).getValue());
         Assert.assertNull(response.getFirstHeader(HTTP.TRANSFER_ENCODING));
@@ -915,119 +895,117 @@ public class TestStandardInterceptors {
 
     @Test
     public void testResponseDateGenerated() throws Exception {
-        HttpContext context = new BasicHttpContext(null);
-        HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK");
-        ResponseDate interceptor = new ResponseDate();
+        final HttpContext context = new BasicHttpContext(null);
+        final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK");
+        final ResponseDate interceptor = new ResponseDate();
         interceptor.process(response, context);
-        Header h1 = response.getFirstHeader(HTTP.DATE_HEADER);
+        final Header h1 = response.getFirstHeader(HTTP.DATE_HEADER);
         Assert.assertNotNull(h1);
         interceptor.process(response, context);
-        Header h2 = response.getFirstHeader(HTTP.DATE_HEADER);
+        final Header h2 = response.getFirstHeader(HTTP.DATE_HEADER);
         Assert.assertNotNull(h2);
     }
 
     @Test
     public void testResponseDateNotGenerated() throws Exception {
-        HttpContext context = new BasicHttpContext(null);
-        HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK");
+        final HttpContext context = new BasicHttpContext(null);
+        final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK");
         response.setStatusCode(199);
-        ResponseDate interceptor = new ResponseDate();
+        final ResponseDate interceptor = new ResponseDate();
         interceptor.process(response, context);
-        Header h1 = response.getFirstHeader(HTTP.DATE_HEADER);
+        final Header h1 = response.getFirstHeader(HTTP.DATE_HEADER);
         Assert.assertNull(h1);
     }
 
     @Test
     public void testResponseDateInvalidInput() throws Exception {
-        ResponseDate interceptor = new ResponseDate();
+        final ResponseDate interceptor = new ResponseDate();
         try {
             interceptor.process(null, null);
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
             // expected
         }
     }
 
     @Test
     public void testRequestDateGenerated() throws Exception {
-        HttpContext context = new BasicHttpContext(null);
-        BasicHttpRequest request =
+        final HttpContext context = new BasicHttpContext(null);
+        final BasicHttpRequest request =
             new BasicHttpEntityEnclosingRequest("POST", "/");
         //BasicHttpRequest request = new BasicHttpRequest("GET", "/");
 
-        RequestDate interceptor = new RequestDate();
+        final RequestDate interceptor = new RequestDate();
         interceptor.process(request, context);
-        Header h1 = request.getFirstHeader(HTTP.DATE_HEADER);
+        final Header h1 = request.getFirstHeader(HTTP.DATE_HEADER);
         Assert.assertNotNull(h1);
         interceptor.process(request, context);
-        Header h2 = request.getFirstHeader(HTTP.DATE_HEADER);
+        final Header h2 = request.getFirstHeader(HTTP.DATE_HEADER);
         Assert.assertNotNull(h2);
     }
 
     @Test
     public void testRequestDateNotGenerated() throws Exception {
-        HttpContext context = new BasicHttpContext(null);
-        BasicHttpRequest request = new BasicHttpRequest("GET", "/");
+        final HttpContext context = new BasicHttpContext(null);
+        final BasicHttpRequest request = new BasicHttpRequest("GET", "/");
 
-        RequestDate interceptor = new RequestDate();
+        final RequestDate interceptor = new RequestDate();
         interceptor.process(request, context);
-        Header h1 = request.getFirstHeader(HTTP.DATE_HEADER);
+        final Header h1 = request.getFirstHeader(HTTP.DATE_HEADER);
         Assert.assertNull(h1);
     }
 
     @Test
     public void testRequestDateInvalidInput() throws Exception {
-        RequestDate interceptor = new RequestDate();
+        final RequestDate interceptor = new RequestDate();
         try {
             interceptor.process(null, null);
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
             // expected
         }
     }
 
     @Test
     public void testResponseServerGenerated() throws Exception {
-        HttpContext context = new BasicHttpContext(null);
-        HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK");
-        response.getParams().setParameter(CoreProtocolPNames.ORIGIN_SERVER, "some server");
-        ResponseServer interceptor = new ResponseServer();
+        final HttpContext context = new BasicHttpContext(null);
+        final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK");
+        final ResponseServer interceptor = new ResponseServer("some server");
         interceptor.process(response, context);
-        Header h1 = response.getFirstHeader(HTTP.SERVER_HEADER);
+        final Header h1 = response.getFirstHeader(HTTP.SERVER_HEADER);
         Assert.assertNotNull(h1);
         Assert.assertEquals("some server", h1.getValue());
     }
 
     @Test
     public void testResponseServerNotGenerated() throws Exception {
-        HttpContext context = new BasicHttpContext(null);
-        HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK");
-        response.getParams().setParameter(CoreProtocolPNames.ORIGIN_SERVER, "some server");
+        final HttpContext context = new BasicHttpContext(null);
+        final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK");
         response.addHeader(new BasicHeader(HTTP.SERVER_HEADER, "whatever"));
-        ResponseServer interceptor = new ResponseServer();
+        final ResponseServer interceptor = new ResponseServer("some server");
         interceptor.process(response, context);
-        Header h1 = response.getFirstHeader(HTTP.SERVER_HEADER);
+        final Header h1 = response.getFirstHeader(HTTP.SERVER_HEADER);
         Assert.assertNotNull(h1);
         Assert.assertEquals("whatever", h1.getValue());
     }
 
     @Test
     public void testResponseServerMissing() throws Exception {
-        HttpContext context = new BasicHttpContext(null);
-        HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK");
-        ResponseServer interceptor = new ResponseServer();
+        final HttpContext context = new BasicHttpContext(null);
+        final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK");
+        final ResponseServer interceptor = new ResponseServer();
         interceptor.process(response, context);
-        Header h1 = response.getFirstHeader(HTTP.SERVER_HEADER);
+        final Header h1 = response.getFirstHeader(HTTP.SERVER_HEADER);
         Assert.assertNull(h1);
     }
 
     @Test
     public void testResponseServerInvalidInput() throws Exception {
-        ResponseServer interceptor = new ResponseServer();
+        final ResponseServer interceptor = new ResponseServer();
         try {
             interceptor.process(null, null);
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
             // expected
         }
     }
diff --git a/httpcore/src/test/java/org/apache/http/protocol/TestUriHttpRequestHandlerMapper.java b/httpcore/src/test/java/org/apache/http/protocol/TestUriHttpRequestHandlerMapper.java
new file mode 100644
index 0000000..822d3eb
--- /dev/null
+++ b/httpcore/src/test/java/org/apache/http/protocol/TestUriHttpRequestHandlerMapper.java
@@ -0,0 +1,103 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+
+package org.apache.http.protocol;
+
+import org.apache.http.HttpRequest;
+import org.apache.http.message.BasicHttpRequest;
+import org.junit.Assert;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+public class TestUriHttpRequestHandlerMapper {
+
+    @Test
+    public void testRegisterUnregister() throws Exception {
+        final HttpRequestHandler h = Mockito.mock(HttpRequestHandler.class);
+
+        final UriPatternMatcher<HttpRequestHandler> matcher = Mockito.spy(new UriPatternMatcher<HttpRequestHandler>());
+        final UriHttpRequestHandlerMapper registry = new UriHttpRequestHandlerMapper(matcher);
+
+        registry.register("/h1", h);
+        registry.unregister("/h1");
+
+        Mockito.verify(matcher).register("/h1", h);
+        Mockito.verify(matcher).unregister("/h1");
+    }
+
+    @Test
+    public void testLookup() throws Exception {
+        final UriPatternMatcher<HttpRequestHandler> matcher = Mockito.spy(new UriPatternMatcher<HttpRequestHandler>());
+        final UriHttpRequestHandlerMapper registry = new UriHttpRequestHandlerMapper(matcher);
+
+        final HttpRequest request = new BasicHttpRequest("GET", "/");
+        registry.lookup(request);
+        registry.unregister("/h1");
+
+        Mockito.verify(matcher).lookup("/");
+    }
+
+    @Test(expected=IllegalArgumentException.class)
+    public void testRegisterNull() throws Exception {
+        final UriHttpRequestHandlerMapper registry = new UriHttpRequestHandlerMapper();
+        registry.register(null, null);
+    }
+
+    @Test(expected=IllegalArgumentException.class)
+    public void testLookupNull() throws Exception {
+        final UriHttpRequestHandlerMapper registry = new UriHttpRequestHandlerMapper();
+        registry.register(null, null);
+    }
+
+    @Test
+    public void testWildCardMatchingWithQuery() throws Exception {
+        final HttpRequestHandler h1 = Mockito.mock(HttpRequestHandler.class);
+        final HttpRequestHandler h2 = Mockito.mock(HttpRequestHandler.class);
+        final HttpRequestHandler def = Mockito.mock(HttpRequestHandler.class);
+
+        final UriPatternMatcher<HttpRequestHandler> matcher = Mockito.spy(new UriPatternMatcher<HttpRequestHandler>());
+        final UriHttpRequestHandlerMapper registry = new UriHttpRequestHandlerMapper(matcher);
+        registry.register("*", def);
+        registry.register("*.view", h1);
+        registry.register("*.form", h2);
+
+        HttpRequestHandler h;
+
+        h = registry.lookup(new BasicHttpRequest("GET", "/that.view?param=value"));
+        Assert.assertNotNull(h);
+        Assert.assertTrue(h1 == h);
+
+        h = registry.lookup(new BasicHttpRequest("GET", "/that.form?whatever"));
+        Assert.assertNotNull(h);
+        Assert.assertTrue(h2 == h);
+
+        h = registry.lookup(new BasicHttpRequest("GET", "/whatever"));
+        Assert.assertNotNull(h);
+        Assert.assertTrue(def == h);
+    }
+
+}
diff --git a/httpcore/src/test/java/org/apache/http/protocol/TestUriPatternMatcher.java b/httpcore/src/test/java/org/apache/http/protocol/TestUriPatternMatcher.java
new file mode 100644
index 0000000..edff195
--- /dev/null
+++ b/httpcore/src/test/java/org/apache/http/protocol/TestUriPatternMatcher.java
@@ -0,0 +1,155 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+
+package org.apache.http.protocol;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+public class TestUriPatternMatcher {
+
+    @Test
+    public void testRegisterUnregister() throws Exception {
+        final Object h1 = new Object();
+        final Object h2 = new Object();
+        final Object h3 = new Object();
+
+        final UriPatternMatcher<Object> matcher = new UriPatternMatcher<Object>();
+        matcher.register("/h1", h1);
+        matcher.register("/h2", h2);
+        matcher.register("/h3", h3);
+
+        Object h;
+
+        h = matcher.lookup("/h1");
+        Assert.assertNotNull(h);
+        Assert.assertTrue(h1 == h);
+        h = matcher.lookup("/h2");
+        Assert.assertNotNull(h);
+        Assert.assertTrue(h2 == h);
+        h = matcher.lookup("/h3");
+        Assert.assertNotNull(h);
+        Assert.assertTrue(h3 == h);
+
+        matcher.unregister("/h1");
+        h = matcher.lookup("/h1");
+        Assert.assertNull(h);
+    }
+
+    @Test(expected=IllegalArgumentException.class)
+    public void testRegisterNull() throws Exception {
+        final UriPatternMatcher<Object> matcher = new UriPatternMatcher<Object>();
+        matcher.register(null, null);
+    }
+
+    @Test
+    public void testWildCardMatching1() throws Exception {
+        final Object h1 = new Object();
+        final Object h2 = new Object();
+        final Object h3 = new Object();
+        final Object def = new Object();
+
+        final UriPatternMatcher<Object> matcher = new UriPatternMatcher<Object>();
+        matcher.register("*", def);
+        matcher.register("/one/*", h1);
+        matcher.register("/one/two/*", h2);
+        matcher.register("/one/two/three/*", h3);
+
+        Object h;
+
+        h = matcher.lookup("/one/request");
+        Assert.assertNotNull(h);
+        Assert.assertTrue(h1 == h);
+
+        h = matcher.lookup("/one/two/request");
+        Assert.assertNotNull(h);
+        Assert.assertTrue(h2 == h);
+
+        h = matcher.lookup("/one/two/three/request");
+        Assert.assertNotNull(h);
+        Assert.assertTrue(h3 == h);
+
+        h = matcher.lookup("default/request");
+        Assert.assertNotNull(h);
+        Assert.assertTrue(def == h);
+    }
+
+    @Test
+    public void testWildCardMatching2() throws Exception {
+        final Object h1 = new Object();
+        final Object h2 = new Object();
+        final Object def = new Object();
+
+        final UriPatternMatcher<Object> matcher = new UriPatternMatcher<Object>();
+        matcher.register("*", def);
+        matcher.register("*.view", h1);
+        matcher.register("*.form", h2);
+
+        Object h;
+
+        h = matcher.lookup("/that.view");
+        Assert.assertNotNull(h);
+        Assert.assertTrue(h1 == h);
+
+        h = matcher.lookup("/that.form");
+        Assert.assertNotNull(h);
+        Assert.assertTrue(h2 == h);
+
+        h = matcher.lookup("/whatever");
+        Assert.assertNotNull(h);
+        Assert.assertTrue(def == h);
+    }
+
+    @Test
+    public void testSuffixPatternOverPrefixPatternMatch() throws Exception {
+        final Object h1 = new Object();
+        final Object h2 = new Object();
+
+        final UriPatternMatcher<Object> matcher = new UriPatternMatcher<Object>();
+        matcher.register("/ma*", h1);
+        matcher.register("*tch", h2);
+
+        Object h;
+
+        h = matcher.lookup("/match");
+        Assert.assertNotNull(h);
+        Assert.assertTrue(h1 == h);
+    }
+
+    @Test(expected=IllegalArgumentException.class)
+    public void testRegisterInvalidInput() throws Exception {
+        final UriPatternMatcher<Object> matcher = new UriPatternMatcher<Object>();
+        matcher.register(null, null);
+    }
+
+    @Test(expected=IllegalArgumentException.class)
+    public void testLookupInvalidInput() throws Exception {
+        final UriPatternMatcher<Object> matcher = new UriPatternMatcher<Object>();
+        matcher.lookup(null);
+    }
+
+}
diff --git a/httpcore/src/test/java/org/apache/http/testserver/HttpClient.java b/httpcore/src/test/java/org/apache/http/testserver/HttpClient.java
index 3aaf796..0397db3 100644
--- a/httpcore/src/test/java/org/apache/http/testserver/HttpClient.java
+++ b/httpcore/src/test/java/org/apache/http/testserver/HttpClient.java
@@ -28,6 +28,8 @@
 package org.apache.http.testserver;
 
 import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.net.Socket;
 
 import org.apache.http.ConnectionReuseStrategy;
 import org.apache.http.HttpClientConnection;
@@ -36,16 +38,10 @@ import org.apache.http.HttpHost;
 import org.apache.http.HttpRequest;
 import org.apache.http.HttpRequestInterceptor;
 import org.apache.http.HttpResponse;
-import org.apache.http.HttpVersion;
+import org.apache.http.impl.DefaultBHttpClientConnection;
 import org.apache.http.impl.DefaultConnectionReuseStrategy;
-import org.apache.http.params.CoreConnectionPNames;
-import org.apache.http.params.HttpParams;
-import org.apache.http.params.CoreProtocolPNames;
-import org.apache.http.params.DefaultedHttpParams;
-import org.apache.http.params.SyncBasicHttpParams;
 import org.apache.http.protocol.HttpContext;
-import org.apache.http.protocol.BasicHttpContext;
-import org.apache.http.protocol.ExecutionContext;
+import org.apache.http.protocol.HttpCoreContext;
 import org.apache.http.protocol.HttpProcessor;
 import org.apache.http.protocol.HttpRequestExecutor;
 import org.apache.http.protocol.ImmutableHttpProcessor;
@@ -57,24 +53,19 @@ import org.apache.http.protocol.RequestUserAgent;
 
 public class HttpClient {
 
-    private final HttpParams params;
     private final HttpProcessor httpproc;
     private final HttpRequestExecutor httpexecutor;
     private final ConnectionReuseStrategy connStrategy;
-    private final HttpContext context;
+    private final HttpCoreContext context;
+
+    private volatile int timeout;
 
     public HttpClient(final HttpProcessor httpproc) {
         super();
         this.httpproc = httpproc;
-        this.connStrategy = new DefaultConnectionReuseStrategy();
-        this.params = new SyncBasicHttpParams();
-        this.params
-            .setIntParameter(CoreConnectionPNames.SO_TIMEOUT, 5000)
-            .setBooleanParameter(CoreConnectionPNames.STALE_CONNECTION_CHECK, false)
-            .setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1)
-            .setParameter(CoreProtocolPNames.USER_AGENT, "TEST-CLIENT/1.1");
+        this.connStrategy = DefaultConnectionReuseStrategy.INSTANCE;
         this.httpexecutor = new HttpRequestExecutor();
-        this.context = new BasicHttpContext();
+        this.context = new HttpCoreContext();
     }
 
     public HttpClient() {
@@ -83,27 +74,41 @@ public class HttpClient {
                         new RequestContent(),
                         new RequestTargetHost(),
                         new RequestConnControl(),
-                        new RequestUserAgent(),
-                        new RequestExpectContinue()
+                        new RequestUserAgent("TEST-CLIENT/1.1"),
+                        new RequestExpectContinue(true)
                 }));
     }
 
-    public HttpParams getParams() {
-        return this.params;
+    public HttpContext getContext() {
+        return this.context;
+    }
+
+    public int getTimeout() {
+        return this.timeout;
+    }
+
+    public void setTimeout(final int timeout) {
+        this.timeout = timeout;
+    }
+
+    public DefaultBHttpClientConnection createConnection() {
+        return new LoggingBHttpClientConnection(8 * 1024);
+    }
+
+    public void connect(final HttpHost host, final DefaultBHttpClientConnection conn) throws IOException {
+        final Socket socket = new Socket();
+        socket.connect(new InetSocketAddress(host.getHostName(), host.getPort()), this.timeout);
+        conn.bind(socket);
+        conn.setSocketTimeout(this.timeout);
     }
 
     public HttpResponse execute(
             final HttpRequest request,
             final HttpHost targetHost,
             final HttpClientConnection conn) throws HttpException, IOException {
-        this.context.setAttribute(ExecutionContext.HTTP_REQUEST, request);
-        this.context.setAttribute(ExecutionContext.HTTP_TARGET_HOST, targetHost);
-        this.context.setAttribute(ExecutionContext.HTTP_CONNECTION, conn);
-
-        request.setParams(new DefaultedHttpParams(request.getParams(), this.params));
+        this.context.setTargetHost(targetHost);
         this.httpexecutor.preProcess(request, this.httpproc, this.context);
-        HttpResponse response = this.httpexecutor.execute(request, conn, this.context);
-        response.setParams(new DefaultedHttpParams(response.getParams(), this.params));
+        final HttpResponse response = this.httpexecutor.execute(request, conn, this.context);
         this.httpexecutor.postProcess(response, this.httpproc, this.context);
         return response;
     }
diff --git a/httpcore/src/test/java/org/apache/http/testserver/HttpServer.java b/httpcore/src/test/java/org/apache/http/testserver/HttpServer.java
index e5f1e31..937c550 100644
--- a/httpcore/src/test/java/org/apache/http/testserver/HttpServer.java
+++ b/httpcore/src/test/java/org/apache/http/testserver/HttpServer.java
@@ -41,60 +41,56 @@ import org.apache.http.HttpResponseInterceptor;
 import org.apache.http.HttpServerConnection;
 import org.apache.http.impl.DefaultConnectionReuseStrategy;
 import org.apache.http.impl.DefaultHttpResponseFactory;
-import org.apache.http.impl.DefaultHttpServerConnection;
-import org.apache.http.params.CoreConnectionPNames;
-import org.apache.http.params.HttpParams;
-import org.apache.http.params.CoreProtocolPNames;
-import org.apache.http.params.SyncBasicHttpParams;
-import org.apache.http.protocol.HttpContext;
 import org.apache.http.protocol.BasicHttpContext;
+import org.apache.http.protocol.HttpContext;
 import org.apache.http.protocol.HttpExpectationVerifier;
 import org.apache.http.protocol.HttpProcessor;
 import org.apache.http.protocol.HttpRequestHandler;
-import org.apache.http.protocol.HttpRequestHandlerRegistry;
 import org.apache.http.protocol.HttpService;
 import org.apache.http.protocol.ImmutableHttpProcessor;
 import org.apache.http.protocol.ResponseConnControl;
 import org.apache.http.protocol.ResponseContent;
 import org.apache.http.protocol.ResponseDate;
 import org.apache.http.protocol.ResponseServer;
+import org.apache.http.protocol.UriHttpRequestHandlerMapper;
+import org.apache.http.util.Asserts;
 
 public class HttpServer {
 
-    private final HttpParams params;
     private final HttpProcessor httpproc;
     private final ConnectionReuseStrategy connStrategy;
     private final HttpResponseFactory responseFactory;
-    private final HttpRequestHandlerRegistry reqistry;
+    private final UriHttpRequestHandlerMapper reqistry;
     private final ServerSocket serversocket;
 
-    private HttpExpectationVerifier expectationVerifier;
-
-    private Thread listener;
+    private volatile HttpExpectationVerifier expectationVerifier;
+    private volatile Thread listener;
     private volatile boolean shutdown;
+    private volatile int timeout;
 
     public HttpServer() throws IOException {
         super();
-        this.params = new SyncBasicHttpParams();
-        this.params
-            .setIntParameter(CoreConnectionPNames.SO_TIMEOUT, 5000)
-            .setIntParameter(CoreConnectionPNames.SOCKET_BUFFER_SIZE, 8 * 1024)
-            .setBooleanParameter(CoreConnectionPNames.STALE_CONNECTION_CHECK, false)
-            .setBooleanParameter(CoreConnectionPNames.TCP_NODELAY, true)
-            .setParameter(CoreProtocolPNames.ORIGIN_SERVER, "TEST-SERVER/1.1");
         this.httpproc = new ImmutableHttpProcessor(
                 new HttpResponseInterceptor[] {
                         new ResponseDate(),
-                        new ResponseServer(),
+                        new ResponseServer("TEST-SERVER/1.1"),
                         new ResponseContent(),
                         new ResponseConnControl()
                 });
-        this.connStrategy = new DefaultConnectionReuseStrategy();
-        this.responseFactory = new DefaultHttpResponseFactory();
-        this.reqistry = new HttpRequestHandlerRegistry();
+        this.connStrategy = DefaultConnectionReuseStrategy.INSTANCE;
+        this.responseFactory = DefaultHttpResponseFactory.INSTANCE;
+        this.reqistry = new UriHttpRequestHandlerMapper();
         this.serversocket = new ServerSocket(0);
     }
 
+    public int getTimeout() {
+        return this.timeout;
+    }
+
+    public void setTimeout(final int timeout) {
+        this.timeout = timeout;
+    }
+
     public void registerHandler(
             final String pattern,
             final HttpRequestHandler handler) {
@@ -106,9 +102,10 @@ public class HttpServer {
     }
 
     private HttpServerConnection acceptConnection() throws IOException {
-        Socket socket = this.serversocket.accept();
-        DefaultHttpServerConnection conn = new DefaultHttpServerConnection();
-        conn.bind(socket, this.params);
+        final Socket socket = this.serversocket.accept();
+        final LoggingBHttpServerConnection conn = new LoggingBHttpServerConnection(8 * 1024);
+        conn.bind(socket);
+        conn.setSocketTimeout(this.timeout);
         return conn;
     }
 
@@ -121,31 +118,28 @@ public class HttpServer {
     }
 
     public void start() {
-        if (this.listener != null) {
-            throw new IllegalStateException("Listener already running");
-        }
+        Asserts.check(this.listener == null, "Listener already running");
         this.listener = new Thread(new Runnable() {
 
             public void run() {
                 while (!shutdown && !Thread.interrupted()) {
                     try {
                         // Set up HTTP connection
-                        HttpServerConnection conn = acceptConnection();
+                        final HttpServerConnection conn = acceptConnection();
                         // Set up the HTTP service
-                        HttpService httpService = new HttpService(
+                        final HttpService httpService = new HttpService(
                                 httpproc,
                                 connStrategy,
                                 responseFactory,
                                 reqistry,
-                                expectationVerifier,
-                                params);
+                                expectationVerifier);
                         // Start worker thread
-                        Thread t = new WorkerThread(httpService, conn);
+                        final Thread t = new WorkerThread(httpService, conn);
                         t.setDaemon(true);
                         t.start();
-                    } catch (InterruptedIOException ex) {
+                    } catch (final InterruptedIOException ex) {
                         break;
-                    } catch (IOException e) {
+                    } catch (final IOException e) {
                         break;
                     }
                 }
@@ -162,11 +156,11 @@ public class HttpServer {
         this.shutdown = true;
         try {
             this.serversocket.close();
-        } catch (IOException ignore) {}
+        } catch (final IOException ignore) {}
         this.listener.interrupt();
         try {
             this.listener.join(1000);
-        } catch (InterruptedException ignore) {}
+        } catch (final InterruptedException ignore) {}
     }
 
     static class WorkerThread extends Thread {
@@ -184,20 +178,20 @@ public class HttpServer {
 
         @Override
         public void run() {
-            HttpContext context = new BasicHttpContext(null);
+            final HttpContext context = new BasicHttpContext(null);
             try {
                 while (!Thread.interrupted() && this.conn.isOpen()) {
                     this.httpservice.handleRequest(this.conn, context);
                 }
-            } catch (ConnectionClosedException ex) {
-            } catch (IOException ex) {
+            } catch (final ConnectionClosedException ex) {
+            } catch (final IOException ex) {
                 System.err.println("I/O error: " + ex.getMessage());
-            } catch (HttpException ex) {
+            } catch (final HttpException ex) {
                 System.err.println("Unrecoverable HTTP protocol violation: " + ex.getMessage());
             } finally {
                 try {
                     this.conn.shutdown();
-                } catch (IOException ignore) {}
+                } catch (final IOException ignore) {}
             }
         }
 
diff --git a/httpcore-contrib/src/main/java/org/apache/http/contrib/logging/LoggingNHttpClientConnection.java b/httpcore/src/test/java/org/apache/http/testserver/LoggingBHttpClientConnection.java
similarity index 53%
rename from httpcore-contrib/src/main/java/org/apache/http/contrib/logging/LoggingNHttpClientConnection.java
rename to httpcore/src/test/java/org/apache/http/testserver/LoggingBHttpClientConnection.java
index 444dc84..c6bfb83 100644
--- a/httpcore-contrib/src/main/java/org/apache/http/contrib/logging/LoggingNHttpClientConnection.java
+++ b/httpcore/src/test/java/org/apache/http/testserver/LoggingBHttpClientConnection.java
@@ -25,48 +25,57 @@
  *
  */
 
-package org.apache.http.contrib.logging;
+package org.apache.http.testserver;
 
 import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.Socket;
+import java.nio.charset.CharsetDecoder;
+import java.nio.charset.CharsetEncoder;
 import java.util.concurrent.atomic.AtomicLong;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.http.Header;
-import org.apache.http.HttpException;
 import org.apache.http.HttpRequest;
 import org.apache.http.HttpResponse;
-import org.apache.http.HttpResponseFactory;
-import org.apache.http.impl.nio.DefaultNHttpClientConnection;
-import org.apache.http.nio.NHttpClientEventHandler;
-import org.apache.http.nio.reactor.IOSession;
-import org.apache.http.nio.util.ByteBufferAllocator;
-import org.apache.http.params.HttpParams;
+import org.apache.http.config.MessageConstraints;
+import org.apache.http.entity.ContentLengthStrategy;
+import org.apache.http.impl.DefaultBHttpClientConnection;
+import org.apache.http.io.HttpMessageParserFactory;
+import org.apache.http.io.HttpMessageWriterFactory;
 
-public class LoggingNHttpClientConnection extends DefaultNHttpClientConnection {
+public class LoggingBHttpClientConnection extends DefaultBHttpClientConnection {
 
     private static final AtomicLong COUNT = new AtomicLong();
 
+    private final String id;
     private final Log log;
-    private final Log iolog;
     private final Log headerlog;
-    private final Log wirelog;
-    private final String id;
-
-    public LoggingNHttpClientConnection(
-            final IOSession session,
-            final HttpResponseFactory responseFactory,
-            final ByteBufferAllocator allocator,
-            final HttpParams params) {
-        super(session, responseFactory, allocator, params);
+    private final Wire wire;
+
+    public LoggingBHttpClientConnection(
+            final int buffersize,
+            final int fragmentSizeHint,
+            final CharsetDecoder chardecoder,
+            final CharsetEncoder charencoder,
+            final MessageConstraints constraints,
+            final ContentLengthStrategy incomingContentStrategy,
+            final ContentLengthStrategy outgoingContentStrategy,
+            final HttpMessageWriterFactory<HttpRequest> requestWriterFactory,
+            final HttpMessageParserFactory<HttpResponse> responseParserFactory) {
+        super(buffersize, fragmentSizeHint, chardecoder, charencoder,
+                constraints, incomingContentStrategy, outgoingContentStrategy,
+                requestWriterFactory, responseParserFactory);
+        this.id = "http-outgoing-" + COUNT.incrementAndGet();
         this.log = LogFactory.getLog(getClass());
-        this.iolog = LogFactory.getLog(session.getClass());
         this.headerlog = LogFactory.getLog("org.apache.http.headers");
-        this.wirelog = LogFactory.getLog("org.apache.http.wire");
-        this.id = "http-outgoing-" + COUNT.incrementAndGet();
-        if (this.iolog.isDebugEnabled() || this.wirelog.isDebugEnabled()) {
-            this.session = new LoggingIOSession(session, this.id, this.iolog, this.wirelog);
-        }
+        this.wire = new Wire(LogFactory.getLog("org.apache.http.wire"), this.id);
+    }
+
+    public LoggingBHttpClientConnection(final int buffersize) {
+        this(buffersize, buffersize, null, null, null, null, null, null, null);
     }
 
     @Override
@@ -86,36 +95,30 @@ public class LoggingNHttpClientConnection extends DefaultNHttpClientConnection {
     }
 
     @Override
-    public void submitRequest(final HttpRequest request) throws IOException, HttpException {
-        if (this.log.isDebugEnabled()) {
-            this.log.debug(this.id + ": "  + request.getRequestLine().toString());
-        }
-        super.submitRequest(request);
-    }
-
-    @Override
-    public void consumeInput(final NHttpClientEventHandler handler) {
-        if (this.log.isDebugEnabled()) {
-            this.log.debug(this.id + ": Consume input");
+    protected InputStream getSocketInputStream(final Socket socket) throws IOException {
+        InputStream in = super.getSocketInputStream(socket);
+        if (wire.isEnabled()) {
+            in = new LoggingInputStream(in, wire);
         }
-        super.consumeInput(handler);
+        return in;
     }
 
     @Override
-    public void produceOutput(final NHttpClientEventHandler handler) {
-        if (this.log.isDebugEnabled()) {
-            this.log.debug(this.id + ": Produce output");
+    protected OutputStream getSocketOutputStream(final Socket socket) throws IOException {
+        OutputStream out = super.getSocketOutputStream(socket);
+        if (wire.isEnabled()) {
+            out = new LoggingOutputStream(out, wire);
         }
-        super.produceOutput(handler);
+        return out;
     }
 
     @Override
     protected void onResponseReceived(final HttpResponse response) {
         if (response != null && this.headerlog.isDebugEnabled()) {
             this.headerlog.debug(this.id + " << " + response.getStatusLine().toString());
-            Header[] headers = response.getAllHeaders();
-            for (int i = 0; i < headers.length; i++) {
-                this.headerlog.debug(this.id + " << " + headers[i].toString());
+            final Header[] headers = response.getAllHeaders();
+            for (final Header header : headers) {
+                this.headerlog.debug(this.id + " << " + header.toString());
             }
         }
     }
@@ -124,16 +127,11 @@ public class LoggingNHttpClientConnection extends DefaultNHttpClientConnection {
     protected void onRequestSubmitted(final HttpRequest request) {
         if (request != null && this.headerlog.isDebugEnabled()) {
             this.headerlog.debug(id + " >> " + request.getRequestLine().toString());
-            Header[] headers = request.getAllHeaders();
-            for (int i = 0; i < headers.length; i++) {
-                this.headerlog.debug(this.id + " >> " + headers[i].toString());
+            final Header[] headers = request.getAllHeaders();
+            for (final Header header : headers) {
+                this.headerlog.debug(this.id + " >> " + header.toString());
             }
         }
     }
 
-    @Override
-    public String toString() {
-        return this.id;
-    }
-
 }
diff --git a/httpcore-contrib/src/main/java/org/apache/http/contrib/logging/LoggingNHttpServerConnection.java b/httpcore/src/test/java/org/apache/http/testserver/LoggingBHttpServerConnection.java
similarity index 53%
rename from httpcore-contrib/src/main/java/org/apache/http/contrib/logging/LoggingNHttpServerConnection.java
rename to httpcore/src/test/java/org/apache/http/testserver/LoggingBHttpServerConnection.java
index 0d2431b..7ae4050 100644
--- a/httpcore-contrib/src/main/java/org/apache/http/contrib/logging/LoggingNHttpServerConnection.java
+++ b/httpcore/src/test/java/org/apache/http/testserver/LoggingBHttpServerConnection.java
@@ -25,48 +25,57 @@
  *
  */
 
-package org.apache.http.contrib.logging;
+package org.apache.http.testserver;
 
 import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.Socket;
+import java.nio.charset.CharsetDecoder;
+import java.nio.charset.CharsetEncoder;
 import java.util.concurrent.atomic.AtomicLong;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.http.Header;
-import org.apache.http.HttpException;
 import org.apache.http.HttpRequest;
-import org.apache.http.HttpRequestFactory;
 import org.apache.http.HttpResponse;
-import org.apache.http.impl.nio.DefaultNHttpServerConnection;
-import org.apache.http.nio.NHttpServerEventHandler;
-import org.apache.http.nio.reactor.IOSession;
-import org.apache.http.nio.util.ByteBufferAllocator;
-import org.apache.http.params.HttpParams;
+import org.apache.http.config.MessageConstraints;
+import org.apache.http.entity.ContentLengthStrategy;
+import org.apache.http.impl.DefaultBHttpServerConnection;
+import org.apache.http.io.HttpMessageParserFactory;
+import org.apache.http.io.HttpMessageWriterFactory;
 
-public class LoggingNHttpServerConnection extends DefaultNHttpServerConnection {
+public class LoggingBHttpServerConnection extends DefaultBHttpServerConnection {
 
     private static final AtomicLong COUNT = new AtomicLong();
 
+    private final String id;
     private final Log log;
-    private final Log iolog;
     private final Log headerlog;
-    private final Log wirelog;
-    private final String id;
-
-    public LoggingNHttpServerConnection(
-            final IOSession session,
-            final HttpRequestFactory requestFactory,
-            final ByteBufferAllocator allocator,
-            final HttpParams params) {
-        super(session, requestFactory, allocator, params);
+    private final Wire wire;
+
+    public LoggingBHttpServerConnection(
+            final int buffersize,
+            final int fragmentSizeHint,
+            final CharsetDecoder chardecoder,
+            final CharsetEncoder charencoder,
+            final MessageConstraints constraints,
+            final ContentLengthStrategy incomingContentStrategy,
+            final ContentLengthStrategy outgoingContentStrategy,
+            final HttpMessageParserFactory<HttpRequest> requestParserFactory,
+            final HttpMessageWriterFactory<HttpResponse> responseWriterFactory) {
+        super(buffersize, fragmentSizeHint, chardecoder, charencoder, constraints,
+                incomingContentStrategy, outgoingContentStrategy,
+                requestParserFactory, responseWriterFactory);
+        this.id = "http-incoming-" + COUNT.incrementAndGet();
         this.log = LogFactory.getLog(getClass());
-        this.iolog = LogFactory.getLog(session.getClass());
         this.headerlog = LogFactory.getLog("org.apache.http.headers");
-        this.wirelog = LogFactory.getLog("org.apache.http.wire");
-        this.id = "http-incoming-" + COUNT.incrementAndGet();
-        if (this.iolog.isDebugEnabled() || this.wirelog.isDebugEnabled()) {
-            this.session = new LoggingIOSession(session, this.id, this.iolog, this.wirelog);
-        }
+        this.wire = new Wire(LogFactory.getLog("org.apache.http.wire"), this.id);
+    }
+
+    public LoggingBHttpServerConnection(final int buffersize) {
+        this(buffersize, buffersize, null, null, null, null, null, null, null);
     }
 
     @Override
@@ -86,36 +95,30 @@ public class LoggingNHttpServerConnection extends DefaultNHttpServerConnection {
     }
 
     @Override
-    public void submitResponse(final HttpResponse response) throws IOException, HttpException {
-        if (this.log.isDebugEnabled()) {
-            this.log.debug(this.id + ": "  + response.getStatusLine().toString());
-        }
-        super.submitResponse(response);
-    }
-
-    @Override
-    public void consumeInput(final NHttpServerEventHandler handler) {
-        if (this.log.isDebugEnabled()) {
-            this.log.debug(this.id + ": Consume input");
+    protected InputStream getSocketInputStream(final Socket socket) throws IOException {
+        InputStream in = super.getSocketInputStream(socket);
+        if (wire.isEnabled()) {
+            in = new LoggingInputStream(in, wire);
         }
-        super.consumeInput(handler);
+        return in;
     }
 
     @Override
-    public void produceOutput(final NHttpServerEventHandler handler) {
-        if (this.log.isDebugEnabled()) {
-            this.log.debug(this.id + ": Produce output");
+    protected OutputStream getSocketOutputStream(final Socket socket) throws IOException {
+        OutputStream out = super.getSocketOutputStream(socket);
+        if (wire.isEnabled()) {
+            out = new LoggingOutputStream(out, wire);
         }
-        super.produceOutput(handler);
+        return out;
     }
 
     @Override
     protected void onRequestReceived(final HttpRequest request) {
         if (request != null && this.headerlog.isDebugEnabled()) {
             this.headerlog.debug(this.id + " >> " + request.getRequestLine().toString());
-            Header[] headers = request.getAllHeaders();
-            for (int i = 0; i < headers.length; i++) {
-                this.headerlog.debug(this.id + " >> " + headers[i].toString());
+            final Header[] headers = request.getAllHeaders();
+            for (final Header header : headers) {
+                this.headerlog.debug(this.id + " >> " + header.toString());
             }
         }
     }
@@ -124,16 +127,11 @@ public class LoggingNHttpServerConnection extends DefaultNHttpServerConnection {
     protected void onResponseSubmitted(final HttpResponse response) {
         if (response != null && this.headerlog.isDebugEnabled()) {
             this.headerlog.debug(this.id + " << " + response.getStatusLine().toString());
-            Header[] headers = response.getAllHeaders();
-            for (int i = 0; i < headers.length; i++) {
-                this.headerlog.debug(this.id + " << " + headers[i].toString());
+            final Header[] headers = response.getAllHeaders();
+            for (final Header header : headers) {
+                this.headerlog.debug(this.id + " << " + header.toString());
             }
         }
     }
 
-    @Override
-    public String toString() {
-        return this.id;
-    }
-
 }
diff --git a/httpcore-nio/src/main/java/org/apache/http/nio/entity/ContentInputStream.java b/httpcore/src/test/java/org/apache/http/testserver/LoggingInputStream.java
similarity index 57%
copy from httpcore-nio/src/main/java/org/apache/http/nio/entity/ContentInputStream.java
copy to httpcore/src/test/java/org/apache/http/testserver/LoggingInputStream.java
index 1cb063b..307e07a 100644
--- a/httpcore-nio/src/main/java/org/apache/http/nio/entity/ContentInputStream.java
+++ b/httpcore/src/test/java/org/apache/http/testserver/LoggingInputStream.java
@@ -25,67 +25,77 @@
  *
  */
 
-package org.apache.http.nio.entity;
+package org.apache.http.testserver;
 
 import java.io.IOException;
 import java.io.InputStream;
 
-import org.apache.http.annotation.NotThreadSafe;
-import org.apache.http.io.BufferInfo;
-import org.apache.http.nio.util.ContentInputBuffer;
+class LoggingInputStream extends InputStream {
 
-/**
- * {@link InputStream} adaptor for {@link ContentInputBuffer}.
- *
- * @since 4.0
- */
- at NotThreadSafe
-public class ContentInputStream extends InputStream {
-
-    private final ContentInputBuffer buffer;
+    private final InputStream in;
+    private final Wire wire;
 
-    public ContentInputStream(final ContentInputBuffer buffer) {
+    public LoggingInputStream(final InputStream in, final Wire wire) {
         super();
-        if (buffer == null) {
-            throw new IllegalArgumentException("Input buffer may not be null");
-        }
-        this.buffer = buffer;
+        this.in = in;
+        this.wire = wire;
     }
 
     @Override
-    public int available() throws IOException {
-        if (this.buffer instanceof BufferInfo) {
-            return ((BufferInfo) this.buffer).length();
-        } else {
-            return super.available();
+    public int read() throws IOException {
+        final int b = in.read();
+        if (b != -1) {
+            wire.input(b);
         }
+        return b;
     }
 
     @Override
-    public int read(final byte[] b, int off, int len) throws IOException {
-        return this.buffer.read(b, off, len);
+    public int read(final byte[] b) throws IOException {
+        final int bytesRead = in.read(b);
+        if (bytesRead != -1) {
+            wire.input(b, 0, bytesRead);
+        }
+        return bytesRead;
     }
 
     @Override
-    public int read(final byte[] b) throws IOException {
-        if (b == null) {
-            return 0;
+    public int read(final byte[] b, final int off, final int len) throws IOException {
+        final int bytesRead = in.read(b, off, len);
+        if (bytesRead != -1) {
+            wire.input(b, off, bytesRead);
         }
-        return this.buffer.read(b, 0, b.length);
+        return bytesRead;
     }
 
     @Override
-    public int read() throws IOException {
-        return this.buffer.read();
+    public long skip(final long n) throws IOException {
+        return super.skip(n);
+    }
+
+    @Override
+    public int available() throws IOException {
+        return in.available();
+    }
+
+    @Override
+    public synchronized void mark(final int readlimit) {
+        super.mark(readlimit);
+    }
+
+    @Override
+    public synchronized void reset() throws IOException {
+        super.reset();
+    }
+
+    @Override
+    public boolean markSupported() {
+        return false;
     }
 
     @Override
     public void close() throws IOException {
-        // read and discard the remainder of the message
-        byte tmp[] = new byte[1024];
-        while (this.buffer.read(tmp, 0, tmp.length) >= 0) {
-        }
-        super.close();
+        in.close();
     }
 
 }
diff --git a/httpcore-nio/src/test/java/org/apache/http/testserver/SimpleEventListener.java b/httpcore/src/test/java/org/apache/http/testserver/LoggingOutputStream.java
similarity index 61%
rename from httpcore-nio/src/test/java/org/apache/http/testserver/SimpleEventListener.java
rename to httpcore/src/test/java/org/apache/http/testserver/LoggingOutputStream.java
index 85bd885..5fe1398 100644
--- a/httpcore-nio/src/test/java/org/apache/http/testserver/SimpleEventListener.java
+++ b/httpcore/src/test/java/org/apache/http/testserver/LoggingOutputStream.java
@@ -28,34 +28,44 @@
 package org.apache.http.testserver;
 
 import java.io.IOException;
+import java.io.OutputStream;
 
-import org.apache.http.HttpException;
-import org.apache.http.nio.NHttpConnection;
-import org.apache.http.nio.protocol.EventListener;
+class LoggingOutputStream extends OutputStream {
 
- at Deprecated
-public class SimpleEventListener implements EventListener {
+    private final OutputStream out;
+    private final Wire wire;
 
-    public SimpleEventListener() {
+    public LoggingOutputStream(final OutputStream out, final Wire wire) {
         super();
+        this.out = out;
+        this.wire = wire;
     }
 
-    public void connectionOpen(final NHttpConnection conn) {
+    @Override
+    public void write(final int b) throws IOException {
+        wire.output(b);
     }
 
-    public void connectionTimeout(final NHttpConnection conn) {
-        System.out.println("Connection timed out");
+    @Override
+    public void write(final byte[] b) throws IOException {
+        wire.output(b);
+        out.write(b);
     }
 
-    public void connectionClosed(final NHttpConnection conn) {
+    @Override
+    public void write(final byte[] b, final int off, final int len) throws IOException {
+        wire.output(b, off, len);
+        out.write(b, off, len);
     }
 
-    public void fatalIOException(final IOException ex, final NHttpConnection conn) {
-        ex.printStackTrace(System.out);
+    @Override
+    public void flush() throws IOException {
+        out.flush();
     }
 
-    public void fatalProtocolException(final HttpException ex, final NHttpConnection conn) {
-        ex.printStackTrace(System.out);
+    @Override
+    public void close() throws IOException {
+        out.close();
     }
 
 }
diff --git a/httpcore-contrib/src/main/java/org/apache/http/contrib/logging/Wire.java b/httpcore/src/test/java/org/apache/http/testserver/Wire.java
similarity index 71%
rename from httpcore-contrib/src/main/java/org/apache/http/contrib/logging/Wire.java
rename to httpcore/src/test/java/org/apache/http/testserver/Wire.java
index 5b6413f..d0b5dce 100644
--- a/httpcore-contrib/src/main/java/org/apache/http/contrib/logging/Wire.java
+++ b/httpcore/src/test/java/org/apache/http/testserver/Wire.java
@@ -24,9 +24,8 @@
  * <http://www.apache.org/>.
  *
  */
-package org.apache.http.contrib.logging;
 
-import java.nio.ByteBuffer;
+package org.apache.http.testserver;
 
 import org.apache.commons.logging.Log;
 
@@ -41,10 +40,10 @@ class Wire {
         this.id = id;
     }
 
-    private void wire(final String header, final byte[] b, int pos, int off) {
-        StringBuilder buffer = new StringBuilder();
+    private void wire(final String header, final byte[] b, final int pos, final int off) {
+        final StringBuilder buffer = new StringBuilder();
         for (int i = 0; i < off; i++) {
-            int ch = b[pos + i];
+            final int ch = b[pos + i];
             if (ch == 13) {
                 buffer.append("[\\r]");
             } else if (ch == 10) {
@@ -74,48 +73,28 @@ class Wire {
         return this.log.isDebugEnabled();
     }
 
-    public void output(final byte[] b, int pos, int off) {
+    public void output(final byte[] b, final int pos, final int off) {
         wire("<< ", b, pos, off);
     }
 
-    public void input(final byte[] b, int pos, int off) {
+    public void input(final byte[] b, final int pos, final int off) {
         wire(">> ", b, pos, off);
     }
 
-    public void output(byte[] b) {
+    public void output(final byte[] b) {
         output(b, 0, b.length);
     }
 
-    public void input(byte[] b) {
+    public void input(final byte[] b) {
         input(b, 0, b.length);
     }
 
-    public void output(int b) {
+    public void output(final int b) {
         output(new byte[] {(byte) b});
     }
 
-    public void input(int b) {
+    public void input(final int b) {
         input(new byte[] {(byte) b});
     }
 
-    public void output(final ByteBuffer b) {
-        if (b.hasArray()) {
-            output(b.array(), b.arrayOffset() + b.position(), b.remaining());
-        } else {
-            byte[] tmp = new byte[b.remaining()];
-            b.get(tmp);
-            output(tmp);
-        }
-    }
-
-    public void input(final ByteBuffer b) {
-        if (b.hasArray()) {
-            input(b.array(), b.arrayOffset() + b.position(), b.remaining());
-        } else {
-            byte[] tmp = new byte[b.remaining()];
-            b.get(tmp);
-            input(tmp);
-        }
-    }
-
 }
diff --git a/httpcore/src/test/java/org/apache/http/util/TestArgs.java b/httpcore/src/test/java/org/apache/http/util/TestArgs.java
new file mode 100644
index 0000000..c3d6468
--- /dev/null
+++ b/httpcore/src/test/java/org/apache/http/util/TestArgs.java
@@ -0,0 +1,170 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+
+package org.apache.http.util;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * Unit tests for {@link Args}.
+ */
+public class TestArgs {
+
+    @Test
+    public void testArgCheckPass() {
+        Args.check(true, "All is well");
+    }
+
+    @Test(expected=IllegalArgumentException.class)
+    public void testArgCheckFail() {
+        Args.check(false, "Oopsie");
+    }
+
+    @Test
+    public void testArgNotNullPass() {
+        final String stuff = "stuff";
+        Assert.assertSame(stuff, Args.notNull(stuff, "Stuff"));
+    }
+
+    @Test(expected=IllegalArgumentException.class)
+    public void testArgNotNullFail() {
+        Args.notNull(null, "Stuff");
+    }
+
+    @Test
+    public void testArgNotEmptyPass() {
+        final String stuff = "stuff";
+        Assert.assertSame(stuff, Args.notEmpty(stuff, "Stuff"));
+    }
+
+    @Test(expected=IllegalArgumentException.class)
+    public void testArgNotEmptyFail1() {
+        Args.notEmpty((String) null, "Stuff");
+    }
+
+    @Test(expected=IllegalArgumentException.class)
+    public void testArgNotEmptyFail2() {
+        Args.notEmpty("", "Stuff");
+    }
+
+    @Test(expected=IllegalArgumentException.class)
+    public void testArgNotBlankFail1() {
+        Args.notBlank((String) null, "Stuff");
+    }
+
+    @Test(expected=IllegalArgumentException.class)
+    public void testArgNotBlankFail2() {
+        Args.notBlank("", "Stuff");
+    }
+
+    @Test(expected=IllegalArgumentException.class)
+    public void testArgNotBlankFail3() {
+        Args.notBlank(" \t \n\r", "Stuff");
+    }
+
+    @Test
+    public void testArgCollectionNotEmptyPass() {
+        final List<String> list = Arrays.asList("stuff");
+        Assert.assertSame(list, Args.notEmpty(list, "List"));
+    }
+
+    @Test(expected=IllegalArgumentException.class)
+    public void testArgCollectionNotEmptyFail1() {
+        Args.notEmpty((List<?>) null, "List");
+    }
+
+    @Test(expected=IllegalArgumentException.class)
+    public void testArgCollectionNotEmptyFail2() {
+        Args.notEmpty(Collections.emptyList(), "List");
+    }
+
+    @Test
+    public void testPositiveIntPass() {
+        Assert.assertEquals(1, Args.positive(1, "Number"));
+    }
+
+    @Test(expected=IllegalArgumentException.class)
+    public void testPositiveIntFail1() {
+        Args.positive(-1, "Number");
+    }
+
+    @Test(expected=IllegalArgumentException.class)
+    public void testPositiveIntFail2() {
+        Args.positive(0, "Number");
+    }
+
+    @Test
+    public void testPositiveLongPass() {
+        Assert.assertEquals(1L, Args.positive(1L, "Number"));
+    }
+
+    @Test(expected=IllegalArgumentException.class)
+    public void testPositiveLongFail1() {
+        Args.positive(-1L, "Number");
+    }
+
+    @Test(expected=IllegalArgumentException.class)
+    public void testPositiveLongFail2() {
+        Args.positive(0L, "Number");
+    }
+
+    @Test
+    public void testNotNegativeIntPass1() {
+        Assert.assertEquals(1, Args.notNegative(1, "Number"));
+    }
+
+    @Test
+    public void testNotNegativeIntPass2() {
+        Assert.assertEquals(0, Args.notNegative(0, "Number"));
+    }
+
+    @Test(expected=IllegalArgumentException.class)
+    public void testNotNegativeIntFail1() {
+        Args.notNegative(-1, "Number");
+    }
+
+    @Test
+    public void testNotNegativeLongPass1() {
+        Assert.assertEquals(1L, Args.notNegative(1L, "Number"));
+    }
+
+    @Test
+    public void testNotNegativeLongPass2() {
+        Assert.assertEquals(0L, Args.notNegative(0L, "Number"));
+    }
+
+    @Test(expected=IllegalArgumentException.class)
+    public void testNotNegativeLongFail1() {
+        Args.notNegative(-1L, "Number");
+    }
+
+}
diff --git a/httpcore/src/test/java/org/apache/http/impl/TestNoConnectionReuseStrategy.java b/httpcore/src/test/java/org/apache/http/util/TestAsserts.java
similarity index 52%
copy from httpcore/src/test/java/org/apache/http/impl/TestNoConnectionReuseStrategy.java
copy to httpcore/src/test/java/org/apache/http/util/TestAsserts.java
index 1994af1..52e5f80 100644
--- a/httpcore/src/test/java/org/apache/http/impl/TestNoConnectionReuseStrategy.java
+++ b/httpcore/src/test/java/org/apache/http/util/TestAsserts.java
@@ -25,41 +25,53 @@
  *
  */
 
-package org.apache.http.impl;
+package org.apache.http.util;
 
-import junit.framework.Assert;
-
-import org.apache.http.HttpResponse;
-import org.apache.http.protocol.HttpContext;
-import org.junit.Before;
 import org.junit.Test;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
 
-public class TestNoConnectionReuseStrategy {
+/**
+ * Unit tests for {@link Asserts}.
+ */
+public class TestAsserts {
 
-    private NoConnectionReuseStrategy strat = new NoConnectionReuseStrategy();
-    @Mock private HttpResponse response;
-    @Mock private HttpContext context;
+    @Test
+    public void testExpressionCheckPass() {
+        Asserts.check(true, "All is well");
+    }
 
-    @Before
-    public void setUp() throws Exception {
-        MockitoAnnotations.initMocks(this);
+    @Test(expected=IllegalStateException.class)
+    public void testExpressionCheckFail() {
+        Asserts.check(false, "Oopsie");
     }
 
-    @Test(expected=IllegalArgumentException.class)
-    public void testNullResponse() throws Exception {
-        strat.keepAlive(null, context);
+    @Test(expected=IllegalStateException.class)
+    public void testExpressionNotNullFail() {
+        Asserts.notNull(null, "Stuff");
     }
 
-    @Test(expected=IllegalArgumentException.class)
-    public void testNullContext() throws Exception {
-        strat.keepAlive(response, null);
+    @Test(expected=IllegalStateException.class)
+    public void testExpressionNotEmptyFail1() {
+        Asserts.notEmpty((String) null, "Stuff");
     }
 
-    @Test
-    public void testGoodcall() throws Exception {
-        Assert.assertFalse(strat.keepAlive(response, context));
+    @Test(expected=IllegalStateException.class)
+    public void testExpressionNotEmptyFail2() {
+        Asserts.notEmpty("", "Stuff");
+    }
+
+    @Test(expected=IllegalStateException.class)
+    public void testExpressionNotEmptyBlank1() {
+        Asserts.notBlank((String) null, "Stuff");
+    }
+
+    @Test(expected=IllegalStateException.class)
+    public void testExpressionNotEmptyBlank2() {
+        Asserts.notBlank("", "Stuff");
+    }
+
+    @Test(expected=IllegalStateException.class)
+    public void testExpressionNotBlankFail3() {
+        Asserts.notBlank(" \t \n\r", "Stuff");
     }
 
 }
diff --git a/httpcore/src/test/java/org/apache/http/util/TestByteArrayBuffer.java b/httpcore/src/test/java/org/apache/http/util/TestByteArrayBuffer.java
index c26c21e..84e1e3a 100644
--- a/httpcore/src/test/java/org/apache/http/util/TestByteArrayBuffer.java
+++ b/httpcore/src/test/java/org/apache/http/util/TestByteArrayBuffer.java
@@ -43,7 +43,7 @@ public class TestByteArrayBuffer {
 
     @Test
     public void testConstructor() throws Exception {
-        ByteArrayBuffer buffer = new ByteArrayBuffer(16);
+        final ByteArrayBuffer buffer = new ByteArrayBuffer(16);
         Assert.assertEquals(16, buffer.capacity());
         Assert.assertEquals(0, buffer.length());
         Assert.assertNotNull(buffer.buffer());
@@ -51,30 +51,30 @@ public class TestByteArrayBuffer {
         try {
             new ByteArrayBuffer(-1);
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
             // expected
         }
     }
 
     @Test
     public void testSimpleAppend() throws Exception {
-        ByteArrayBuffer buffer = new ByteArrayBuffer(16);
+        final ByteArrayBuffer buffer = new ByteArrayBuffer(16);
         Assert.assertEquals(16, buffer.capacity());
         Assert.assertEquals(0, buffer.length());
-        byte[] b1 = buffer.toByteArray();
+        final byte[] b1 = buffer.toByteArray();
         Assert.assertNotNull(b1);
         Assert.assertEquals(0, b1.length);
         Assert.assertTrue(buffer.isEmpty());
         Assert.assertFalse(buffer.isFull());
 
-        byte[] tmp = new byte[] { 1, 2, 3, 4};
+        final byte[] tmp = new byte[] { 1, 2, 3, 4};
         buffer.append(tmp, 0, tmp.length);
         Assert.assertEquals(16, buffer.capacity());
         Assert.assertEquals(4, buffer.length());
         Assert.assertFalse(buffer.isEmpty());
         Assert.assertFalse(buffer.isFull());
 
-        byte[] b2 = buffer.toByteArray();
+        final byte[] b2 = buffer.toByteArray();
         Assert.assertNotNull(b2);
         Assert.assertEquals(4, b2.length);
         for (int i = 0; i < tmp.length; i++) {
@@ -90,10 +90,10 @@ public class TestByteArrayBuffer {
 
     @Test
     public void testExpandAppend() throws Exception {
-        ByteArrayBuffer buffer = new ByteArrayBuffer(4);
+        final ByteArrayBuffer buffer = new ByteArrayBuffer(4);
         Assert.assertEquals(4, buffer.capacity());
 
-        byte[] tmp = new byte[] { 1, 2, 3, 4};
+        final byte[] tmp = new byte[] { 1, 2, 3, 4};
         buffer.append(tmp, 0, 2);
         buffer.append(tmp, 0, 4);
         buffer.append(tmp, 0, 0);
@@ -109,50 +109,50 @@ public class TestByteArrayBuffer {
 
     @Test
     public void testInvalidAppend() throws Exception {
-        ByteArrayBuffer buffer = new ByteArrayBuffer(4);
+        final ByteArrayBuffer buffer = new ByteArrayBuffer(4);
         buffer.append((byte[])null, 0, 0);
 
-        byte[] tmp = new byte[] { 1, 2, 3, 4};
+        final byte[] tmp = new byte[] { 1, 2, 3, 4};
         try {
             buffer.append(tmp, -1, 0);
             Assert.fail("IndexOutOfBoundsException should have been thrown");
-        } catch (IndexOutOfBoundsException ex) {
+        } catch (final IndexOutOfBoundsException ex) {
             // expected
         }
         try {
             buffer.append(tmp, 0, -1);
             Assert.fail("IndexOutOfBoundsException should have been thrown");
-        } catch (IndexOutOfBoundsException ex) {
+        } catch (final IndexOutOfBoundsException ex) {
             // expected
         }
         try {
             buffer.append(tmp, 0, 8);
             Assert.fail("IndexOutOfBoundsException should have been thrown");
-        } catch (IndexOutOfBoundsException ex) {
+        } catch (final IndexOutOfBoundsException ex) {
             // expected
         }
         try {
             buffer.append(tmp, 10, Integer.MAX_VALUE);
             Assert.fail("IndexOutOfBoundsException should have been thrown");
-        } catch (IndexOutOfBoundsException ex) {
+        } catch (final IndexOutOfBoundsException ex) {
             // expected
         }
         try {
             buffer.append(tmp, 2, 4);
             Assert.fail("IndexOutOfBoundsException should have been thrown");
-        } catch (IndexOutOfBoundsException ex) {
+        } catch (final IndexOutOfBoundsException ex) {
             // expected
         }
     }
 
     @Test
     public void testAppendOneByte() throws Exception {
-        ByteArrayBuffer buffer = new ByteArrayBuffer(4);
+        final ByteArrayBuffer buffer = new ByteArrayBuffer(4);
         Assert.assertEquals(4, buffer.capacity());
 
-        byte[] tmp = new byte[] { 1, 127, -1, -128, 1, -2};
-        for (int i = 0; i < tmp.length; i++) {
-            buffer.append(tmp[i]);
+        final byte[] tmp = new byte[] { 1, 127, -1, -128, 1, -2};
+        for (final byte element : tmp) {
+            buffer.append(element);
         }
         Assert.assertEquals(8, buffer.capacity());
         Assert.assertEquals(6, buffer.length());
@@ -164,31 +164,31 @@ public class TestByteArrayBuffer {
 
     @Test
     public void testSetLength() throws Exception {
-        ByteArrayBuffer buffer = new ByteArrayBuffer(4);
+        final ByteArrayBuffer buffer = new ByteArrayBuffer(4);
         buffer.setLength(2);
         Assert.assertEquals(2, buffer.length());
     }
 
     @Test
     public void testSetInvalidLength() throws Exception {
-        ByteArrayBuffer buffer = new ByteArrayBuffer(4);
+        final ByteArrayBuffer buffer = new ByteArrayBuffer(4);
         try {
             buffer.setLength(-2);
             Assert.fail("IndexOutOfBoundsException should have been thrown");
-        } catch (IndexOutOfBoundsException ex) {
+        } catch (final IndexOutOfBoundsException ex) {
             // expected
         }
         try {
             buffer.setLength(200);
             Assert.fail("IndexOutOfBoundsException should have been thrown");
-        } catch (IndexOutOfBoundsException ex) {
+        } catch (final IndexOutOfBoundsException ex) {
             // expected
         }
     }
 
     @Test
     public void testEnsureCapacity() throws Exception {
-        ByteArrayBuffer buffer = new ByteArrayBuffer(4);
+        final ByteArrayBuffer buffer = new ByteArrayBuffer(4);
         buffer.ensureCapacity(2);
         Assert.assertEquals(4, buffer.capacity());
         buffer.ensureCapacity(8);
@@ -199,11 +199,11 @@ public class TestByteArrayBuffer {
     public void testIndexOf() throws Exception {
         final byte COLON = (byte) ':';
         final byte COMMA = (byte) ',';
-        byte[] bytes = "name1: value1; name2: value2".getBytes("US-ASCII");
-        int index1 = 5;
-        int index2 = 20;
+        final byte[] bytes = "name1: value1; name2: value2".getBytes("US-ASCII");
+        final int index1 = 5;
+        final int index2 = 20;
 
-        ByteArrayBuffer buffer = new ByteArrayBuffer(16);
+        final ByteArrayBuffer buffer = new ByteArrayBuffer(16);
         buffer.append(bytes, 0, bytes.length);
 
         Assert.assertEquals(index1, buffer.indexOf(COLON));
@@ -216,12 +216,12 @@ public class TestByteArrayBuffer {
 
     @Test
     public void testAppendCharArrayAsAscii() throws Exception {
-        String s1 = "stuff";
-        String s2 = " and more stuff";
-        char[] b1 = s1.toCharArray();
-        char[] b2 = s2.toCharArray();
+        final String s1 = "stuff";
+        final String s2 = " and more stuff";
+        final char[] b1 = s1.toCharArray();
+        final char[] b2 = s2.toCharArray();
 
-        ByteArrayBuffer buffer = new ByteArrayBuffer(8);
+        final ByteArrayBuffer buffer = new ByteArrayBuffer(8);
         buffer.append(b1, 0, b1.length);
         buffer.append(b2, 0, b2.length);
 
@@ -230,80 +230,80 @@ public class TestByteArrayBuffer {
 
     @Test
     public void testAppendNullCharArray() throws Exception {
-        ByteArrayBuffer buffer = new ByteArrayBuffer(8);
+        final ByteArrayBuffer buffer = new ByteArrayBuffer(8);
         buffer.append((char[])null, 0, 0);
         Assert.assertEquals(0, buffer.length());
     }
 
     @Test
     public void testAppendEmptyCharArray() throws Exception {
-        ByteArrayBuffer buffer = new ByteArrayBuffer(8);
+        final ByteArrayBuffer buffer = new ByteArrayBuffer(8);
         buffer.append(new char[] {}, 0, 0);
         Assert.assertEquals(0, buffer.length());
     }
 
     @Test
     public void testAppendNullCharArrayBuffer() throws Exception {
-        ByteArrayBuffer buffer = new ByteArrayBuffer(8);
+        final ByteArrayBuffer buffer = new ByteArrayBuffer(8);
         buffer.append((CharArrayBuffer)null, 0, 0);
         Assert.assertEquals(0, buffer.length());
     }
 
     @Test
     public void testInvalidAppendCharArrayAsAscii() throws Exception {
-        ByteArrayBuffer buffer = new ByteArrayBuffer(4);
+        final ByteArrayBuffer buffer = new ByteArrayBuffer(4);
         buffer.append((char[])null, 0, 0);
 
-        char[] tmp = new char[] { '1', '2', '3', '4'};
+        final char[] tmp = new char[] { '1', '2', '3', '4'};
         try {
             buffer.append(tmp, -1, 0);
             Assert.fail("IndexOutOfBoundsException should have been thrown");
-        } catch (IndexOutOfBoundsException ex) {
+        } catch (final IndexOutOfBoundsException ex) {
             // expected
         }
         try {
             buffer.append(tmp, 0, -1);
             Assert.fail("IndexOutOfBoundsException should have been thrown");
-        } catch (IndexOutOfBoundsException ex) {
+        } catch (final IndexOutOfBoundsException ex) {
             // expected
         }
         try {
             buffer.append(tmp, 0, 8);
             Assert.fail("IndexOutOfBoundsException should have been thrown");
-        } catch (IndexOutOfBoundsException ex) {
+        } catch (final IndexOutOfBoundsException ex) {
             // expected
         }
         try {
             buffer.append(tmp, 10, Integer.MAX_VALUE);
             Assert.fail("IndexOutOfBoundsException should have been thrown");
-        } catch (IndexOutOfBoundsException ex) {
+        } catch (final IndexOutOfBoundsException ex) {
             // expected
         }
         try {
             buffer.append(tmp, 2, 4);
             Assert.fail("IndexOutOfBoundsException should have been thrown");
-        } catch (IndexOutOfBoundsException ex) {
+        } catch (final IndexOutOfBoundsException ex) {
             // expected
         }
     }
 
     @Test
     public void testSerialization() throws Exception {
-        ByteArrayBuffer orig = new ByteArrayBuffer(32);
+        final ByteArrayBuffer orig = new ByteArrayBuffer(32);
         orig.append(1);
         orig.append(2);
         orig.append(3);
-        ByteArrayOutputStream outbuffer = new ByteArrayOutputStream();
-        ObjectOutputStream outstream = new ObjectOutputStream(outbuffer);
+        final ByteArrayOutputStream outbuffer = new ByteArrayOutputStream();
+        final ObjectOutputStream outstream = new ObjectOutputStream(outbuffer);
         outstream.writeObject(orig);
         outstream.close();
-        byte[] raw = outbuffer.toByteArray();
-        ByteArrayInputStream inbuffer = new ByteArrayInputStream(raw);
-        ObjectInputStream instream = new ObjectInputStream(inbuffer);
-        ByteArrayBuffer clone = (ByteArrayBuffer) instream.readObject();
+        final byte[] raw = outbuffer.toByteArray();
+        final ByteArrayInputStream inbuffer = new ByteArrayInputStream(raw);
+        final ObjectInputStream instream = new ObjectInputStream(inbuffer);
+        final ByteArrayBuffer clone = (ByteArrayBuffer) instream.readObject();
         Assert.assertEquals(orig.capacity(), clone.capacity());
         Assert.assertEquals(orig.length(), clone.length());
-        byte[] data = clone.toByteArray();
+        final byte[] data = clone.toByteArray();
         Assert.assertNotNull(data);
         Assert.assertEquals(3, data.length);
         Assert.assertEquals(1, data[0]);
diff --git a/httpcore/src/test/java/org/apache/http/util/TestCharArrayBuffer.java b/httpcore/src/test/java/org/apache/http/util/TestCharArrayBuffer.java
index 034159b..4341a7e 100644
--- a/httpcore/src/test/java/org/apache/http/util/TestCharArrayBuffer.java
+++ b/httpcore/src/test/java/org/apache/http/util/TestCharArrayBuffer.java
@@ -43,7 +43,7 @@ public class TestCharArrayBuffer {
 
     @Test
     public void testConstructor() throws Exception {
-        CharArrayBuffer buffer = new CharArrayBuffer(16);
+        final CharArrayBuffer buffer = new CharArrayBuffer(16);
         Assert.assertEquals(16, buffer.capacity());
         Assert.assertEquals(0, buffer.length());
         Assert.assertNotNull(buffer.buffer());
@@ -51,30 +51,30 @@ public class TestCharArrayBuffer {
         try {
             new CharArrayBuffer(-1);
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
             // expected
         }
     }
 
     @Test
     public void testSimpleAppend() throws Exception {
-        CharArrayBuffer buffer = new CharArrayBuffer(16);
+        final CharArrayBuffer buffer = new CharArrayBuffer(16);
         Assert.assertEquals(16, buffer.capacity());
         Assert.assertEquals(0, buffer.length());
-        char[] b1 = buffer.toCharArray();
+        final char[] b1 = buffer.toCharArray();
         Assert.assertNotNull(b1);
         Assert.assertEquals(0, b1.length);
         Assert.assertTrue(buffer.isEmpty());
         Assert.assertFalse(buffer.isFull());
 
-        char[] tmp = new char[] { '1', '2', '3', '4'};
+        final char[] tmp = new char[] { '1', '2', '3', '4'};
         buffer.append(tmp, 0, tmp.length);
         Assert.assertEquals(16, buffer.capacity());
         Assert.assertEquals(4, buffer.length());
         Assert.assertFalse(buffer.isEmpty());
         Assert.assertFalse(buffer.isFull());
 
-        char[] b2 = buffer.toCharArray();
+        final char[] b2 = buffer.toCharArray();
         Assert.assertNotNull(b2);
         Assert.assertEquals(4, b2.length);
         for (int i = 0; i < tmp.length; i++) {
@@ -92,10 +92,10 @@ public class TestCharArrayBuffer {
 
     @Test
     public void testExpandAppend() throws Exception {
-        CharArrayBuffer buffer = new CharArrayBuffer(4);
+        final CharArrayBuffer buffer = new CharArrayBuffer(4);
         Assert.assertEquals(4, buffer.capacity());
 
-        char[] tmp = new char[] { '1', '2', '3', '4'};
+        final char[] tmp = new char[] { '1', '2', '3', '4'};
         buffer.append(tmp, 0, 2);
         buffer.append(tmp, 0, 4);
         buffer.append(tmp, 0, 0);
@@ -113,7 +113,7 @@ public class TestCharArrayBuffer {
 
     @Test
     public void testAppendString() throws Exception {
-        CharArrayBuffer buffer = new CharArrayBuffer(8);
+        final CharArrayBuffer buffer = new CharArrayBuffer(8);
         buffer.append("stuff");
         buffer.append(" and more stuff");
         Assert.assertEquals("stuff and more stuff", buffer.toString());
@@ -121,16 +121,16 @@ public class TestCharArrayBuffer {
 
     @Test
     public void testAppendNullString() throws Exception {
-        CharArrayBuffer buffer = new CharArrayBuffer(8);
+        final CharArrayBuffer buffer = new CharArrayBuffer(8);
         buffer.append((String)null);
         Assert.assertEquals("null", buffer.toString());
     }
 
     @Test
     public void testAppendCharArrayBuffer() throws Exception {
-        CharArrayBuffer buffer1 = new CharArrayBuffer(8);
+        final CharArrayBuffer buffer1 = new CharArrayBuffer(8);
         buffer1.append(" and more stuff");
-        CharArrayBuffer buffer2 = new CharArrayBuffer(8);
+        final CharArrayBuffer buffer2 = new CharArrayBuffer(8);
         buffer2.append("stuff");
         buffer2.append(buffer1);
         Assert.assertEquals("stuff and more stuff", buffer2.toString());
@@ -138,7 +138,7 @@ public class TestCharArrayBuffer {
 
     @Test
     public void testAppendNullCharArrayBuffer() throws Exception {
-        CharArrayBuffer buffer = new CharArrayBuffer(8);
+        final CharArrayBuffer buffer = new CharArrayBuffer(8);
         buffer.append((CharArrayBuffer)null);
         buffer.append((CharArrayBuffer)null, 0, 0);
         Assert.assertEquals("", buffer.toString());
@@ -146,7 +146,7 @@ public class TestCharArrayBuffer {
 
     @Test
     public void testAppendSingleChar() throws Exception {
-        CharArrayBuffer buffer = new CharArrayBuffer(4);
+        final CharArrayBuffer buffer = new CharArrayBuffer(4);
         buffer.append('1');
         buffer.append('2');
         buffer.append('3');
@@ -158,69 +158,69 @@ public class TestCharArrayBuffer {
 
     @Test
     public void testInvalidCharArrayAppend() throws Exception {
-        CharArrayBuffer buffer = new CharArrayBuffer(4);
+        final CharArrayBuffer buffer = new CharArrayBuffer(4);
         buffer.append((char[])null, 0, 0);
 
-        char[] tmp = new char[] { '1', '2', '3', '4'};
+        final char[] tmp = new char[] { '1', '2', '3', '4'};
         try {
             buffer.append(tmp, -1, 0);
             Assert.fail("IndexOutOfBoundsException should have been thrown");
-        } catch (IndexOutOfBoundsException ex) {
+        } catch (final IndexOutOfBoundsException ex) {
             // expected
         }
         try {
             buffer.append(tmp, 0, -1);
             Assert.fail("IndexOutOfBoundsException should have been thrown");
-        } catch (IndexOutOfBoundsException ex) {
+        } catch (final IndexOutOfBoundsException ex) {
             // expected
         }
         try {
             buffer.append(tmp, 0, 8);
             Assert.fail("IndexOutOfBoundsException should have been thrown");
-        } catch (IndexOutOfBoundsException ex) {
+        } catch (final IndexOutOfBoundsException ex) {
             // expected
         }
         try {
             buffer.append(tmp, 10, Integer.MAX_VALUE);
             Assert.fail("IndexOutOfBoundsException should have been thrown");
-        } catch (IndexOutOfBoundsException ex) {
+        } catch (final IndexOutOfBoundsException ex) {
             // expected
         }
         try {
             buffer.append(tmp, 2, 4);
             Assert.fail("IndexOutOfBoundsException should have been thrown");
-        } catch (IndexOutOfBoundsException ex) {
+        } catch (final IndexOutOfBoundsException ex) {
             // expected
         }
     }
 
     @Test
     public void testSetLength() throws Exception {
-        CharArrayBuffer buffer = new CharArrayBuffer(4);
+        final CharArrayBuffer buffer = new CharArrayBuffer(4);
         buffer.setLength(2);
         Assert.assertEquals(2, buffer.length());
     }
 
     @Test
     public void testSetInvalidLength() throws Exception {
-        CharArrayBuffer buffer = new CharArrayBuffer(4);
+        final CharArrayBuffer buffer = new CharArrayBuffer(4);
         try {
             buffer.setLength(-2);
             Assert.fail("IndexOutOfBoundsException should have been thrown");
-        } catch (IndexOutOfBoundsException ex) {
+        } catch (final IndexOutOfBoundsException ex) {
             // expected
         }
         try {
             buffer.setLength(200);
             Assert.fail("IndexOutOfBoundsException should have been thrown");
-        } catch (IndexOutOfBoundsException ex) {
+        } catch (final IndexOutOfBoundsException ex) {
             // expected
         }
     }
 
     @Test
     public void testEnsureCapacity() throws Exception {
-        CharArrayBuffer buffer = new CharArrayBuffer(4);
+        final CharArrayBuffer buffer = new CharArrayBuffer(4);
         buffer.ensureCapacity(2);
         Assert.assertEquals(4, buffer.capacity());
         buffer.ensureCapacity(8);
@@ -229,7 +229,7 @@ public class TestCharArrayBuffer {
 
     @Test
     public void testIndexOf() {
-        CharArrayBuffer buffer = new CharArrayBuffer(16);
+        final CharArrayBuffer buffer = new CharArrayBuffer(16);
         buffer.append("name: value");
         Assert.assertEquals(4, buffer.indexOf(':'));
         Assert.assertEquals(-1, buffer.indexOf(','));
@@ -240,7 +240,7 @@ public class TestCharArrayBuffer {
 
     @Test
     public void testSubstring() {
-        CharArrayBuffer buffer = new CharArrayBuffer(16);
+        final CharArrayBuffer buffer = new CharArrayBuffer(16);
         buffer.append(" name:  value    ");
         Assert.assertEquals(5, buffer.indexOf(':'));
         Assert.assertEquals(" name", buffer.substring(0, 5));
@@ -252,54 +252,54 @@ public class TestCharArrayBuffer {
 
     @Test
     public void testSubstringIndexOfOutBound() {
-        CharArrayBuffer buffer = new CharArrayBuffer(16);
+        final CharArrayBuffer buffer = new CharArrayBuffer(16);
         buffer.append("stuff");
         try {
             buffer.substring(-2, 10);
             Assert.fail("IndexOutOfBoundsException should have been thrown");
-        } catch (IndexOutOfBoundsException ex) {
+        } catch (final IndexOutOfBoundsException ex) {
             // expected
         }
         try {
             buffer.substringTrimmed(-2, 10);
             Assert.fail("IndexOutOfBoundsException should have been thrown");
-        } catch (IndexOutOfBoundsException ex) {
+        } catch (final IndexOutOfBoundsException ex) {
             // expected
         }
         try {
             buffer.substring(12, 10);
             Assert.fail("IndexOutOfBoundsException should have been thrown");
-        } catch (IndexOutOfBoundsException ex) {
+        } catch (final IndexOutOfBoundsException ex) {
             // expected
         }
         try {
             buffer.substringTrimmed(12, 10);
             Assert.fail("IndexOutOfBoundsException should have been thrown");
-        } catch (IndexOutOfBoundsException ex) {
+        } catch (final IndexOutOfBoundsException ex) {
             // expected
         }
         try {
             buffer.substring(2, 1);
             Assert.fail("IndexOutOfBoundsException should have been thrown");
-        } catch (IndexOutOfBoundsException ex) {
+        } catch (final IndexOutOfBoundsException ex) {
             // expected
         }
         try {
             buffer.substringTrimmed(2, 1);
             Assert.fail("IndexOutOfBoundsException should have been thrown");
-        } catch (IndexOutOfBoundsException ex) {
+        } catch (final IndexOutOfBoundsException ex) {
             // expected
         }
     }
 
     @Test
     public void testAppendAsciiByteArray() throws Exception {
-        String s1 = "stuff";
-        String s2 = " and more stuff";
-        byte[] b1 = s1.getBytes("US-ASCII");
-        byte[] b2 = s2.getBytes("US-ASCII");
+        final String s1 = "stuff";
+        final String s2 = " and more stuff";
+        final byte[] b1 = s1.getBytes("US-ASCII");
+        final byte[] b2 = s2.getBytes("US-ASCII");
 
-        CharArrayBuffer buffer = new CharArrayBuffer(8);
+        final CharArrayBuffer buffer = new CharArrayBuffer(8);
         buffer.append(b1, 0, b1.length);
         buffer.append(b2, 0, b2.length);
 
@@ -308,11 +308,11 @@ public class TestCharArrayBuffer {
 
     @Test
     public void testAppendISOByteArray() throws Exception {
-        byte[] b = new byte[] {0x00, 0x20, 0x7F, -0x80, -0x01};
+        final byte[] b = new byte[] {0x00, 0x20, 0x7F, -0x80, -0x01};
 
-        CharArrayBuffer buffer = new CharArrayBuffer(8);
+        final CharArrayBuffer buffer = new CharArrayBuffer(8);
         buffer.append(b, 0, b.length);
-        char[] ch = buffer.toCharArray();
+        final char[] ch = buffer.toCharArray();
         Assert.assertNotNull(ch);
         Assert.assertEquals(5, ch.length);
         Assert.assertEquals(0x00, ch[0]);
@@ -324,73 +324,73 @@ public class TestCharArrayBuffer {
 
     @Test
     public void testAppendNullByteArray() throws Exception {
-        CharArrayBuffer buffer = new CharArrayBuffer(8);
+        final CharArrayBuffer buffer = new CharArrayBuffer(8);
         buffer.append((byte[])null, 0, 0);
         Assert.assertEquals("", buffer.toString());
     }
 
     @Test
     public void testAppendNullByteArrayBuffer() throws Exception {
-        CharArrayBuffer buffer = new CharArrayBuffer(8);
+        final CharArrayBuffer buffer = new CharArrayBuffer(8);
         buffer.append((ByteArrayBuffer)null, 0, 0);
         Assert.assertEquals("", buffer.toString());
     }
 
     @Test
     public void testInvalidAppendAsciiByteArray() throws Exception {
-        CharArrayBuffer buffer = new CharArrayBuffer(4);
+        final CharArrayBuffer buffer = new CharArrayBuffer(4);
         buffer.append((byte[])null, 0, 0);
 
-        byte[] tmp = new byte[] { '1', '2', '3', '4'};
+        final byte[] tmp = new byte[] { '1', '2', '3', '4'};
         try {
             buffer.append(tmp, -1, 0);
             Assert.fail("IndexOutOfBoundsException should have been thrown");
-        } catch (IndexOutOfBoundsException ex) {
+        } catch (final IndexOutOfBoundsException ex) {
             // expected
         }
         try {
             buffer.append(tmp, 0, -1);
             Assert.fail("IndexOutOfBoundsException should have been thrown");
-        } catch (IndexOutOfBoundsException ex) {
+        } catch (final IndexOutOfBoundsException ex) {
             // expected
         }
         try {
             buffer.append(tmp, 0, 8);
             Assert.fail("IndexOutOfBoundsException should have been thrown");
-        } catch (IndexOutOfBoundsException ex) {
+        } catch (final IndexOutOfBoundsException ex) {
             // expected
         }
         try {
             buffer.append(tmp, 10, Integer.MAX_VALUE);
             Assert.fail("IndexOutOfBoundsException should have been thrown");
-        } catch (IndexOutOfBoundsException ex) {
+        } catch (final IndexOutOfBoundsException ex) {
             // expected
         }
         try {
             buffer.append(tmp, 2, 4);
             Assert.fail("IndexOutOfBoundsException should have been thrown");
-        } catch (IndexOutOfBoundsException ex) {
+        } catch (final IndexOutOfBoundsException ex) {
             // expected
         }
     }
 
     @Test
     public void testSerialization() throws Exception {
-        CharArrayBuffer orig = new CharArrayBuffer(32);
+        final CharArrayBuffer orig = new CharArrayBuffer(32);
         orig.append('a');
         orig.append('b');
         orig.append('c');
-        ByteArrayOutputStream outbuffer = new ByteArrayOutputStream();
-        ObjectOutputStream outstream = new ObjectOutputStream(outbuffer);
+        final ByteArrayOutputStream outbuffer = new ByteArrayOutputStream();
+        final ObjectOutputStream outstream = new ObjectOutputStream(outbuffer);
         outstream.writeObject(orig);
         outstream.close();
-        byte[] raw = outbuffer.toByteArray();
-        ByteArrayInputStream inbuffer = new ByteArrayInputStream(raw);
-        ObjectInputStream instream = new ObjectInputStream(inbuffer);
-        CharArrayBuffer clone = (CharArrayBuffer) instream.readObject();
+        final byte[] raw = outbuffer.toByteArray();
+        final ByteArrayInputStream inbuffer = new ByteArrayInputStream(raw);
+        final ObjectInputStream instream = new ObjectInputStream(inbuffer);
+        final CharArrayBuffer clone = (CharArrayBuffer) instream.readObject();
         Assert.assertEquals(orig.capacity(), clone.capacity());
         Assert.assertEquals(orig.length(), clone.length());
-        char[] data = clone.toCharArray();
+        final char[] data = clone.toCharArray();
         Assert.assertNotNull(data);
         Assert.assertEquals(3, data.length);
         Assert.assertEquals('a', data[0]);
diff --git a/httpcore/src/test/java/org/apache/http/util/TestEncodingUtils.java b/httpcore/src/test/java/org/apache/http/util/TestEncodingUtils.java
index 1a5b691..960bf5b 100644
--- a/httpcore/src/test/java/org/apache/http/util/TestEncodingUtils.java
+++ b/httpcore/src/test/java/org/apache/http/util/TestEncodingUtils.java
@@ -36,11 +36,11 @@ import org.junit.Test;
  */
 public class TestEncodingUtils {
 
-    private static String constructString(int [] unicodeChars) {
-        StringBuilder buffer = new StringBuilder();
+    private static String constructString(final int [] unicodeChars) {
+        final StringBuilder buffer = new StringBuilder();
         if (unicodeChars != null) {
-            for (int i = 0; i < unicodeChars.length; i++) {
-                buffer.append((char)unicodeChars[i]);
+            for (final int unicodeChar : unicodeChars) {
+                buffer.append((char)unicodeChar);
             }
         }
         return buffer.toString();
@@ -52,12 +52,12 @@ public class TestEncodingUtils {
 
     @Test
     public void testBytesToString() throws Exception {
-        String s = constructString(SWISS_GERMAN_HELLO);
-        byte[] utf = s.getBytes("UTF-8");
-        byte[] latin1 = s.getBytes("ISO-8859-1");
+        final String s = constructString(SWISS_GERMAN_HELLO);
+        final byte[] utf = s.getBytes("UTF-8");
+        final byte[] latin1 = s.getBytes("ISO-8859-1");
 
-        String s1 = EncodingUtils.getString(utf, "UTF-8");
-        String s2 = EncodingUtils.getString(latin1, "ISO-8859-1");
+        final String s1 = EncodingUtils.getString(utf, "UTF-8");
+        final String s2 = EncodingUtils.getString(latin1, "ISO-8859-1");
 
         Assert.assertEquals(s, s1);
         Assert.assertEquals(s, s2);
@@ -65,37 +65,37 @@ public class TestEncodingUtils {
         try {
             EncodingUtils.getString(null, 0, 0, "UTF-8");
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
             // expected
         }
         try {
             EncodingUtils.getString(null, "UTF-8");
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
             // expected
         }
         try {
             EncodingUtils.getString(new byte[] {}, null);
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
             // expected
         }
         try {
             EncodingUtils.getString(new byte[] {}, "");
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
             // expected
         }
     }
 
     @Test
     public void testStringToBytesToString() throws Exception {
-        String s = constructString(SWISS_GERMAN_HELLO);
-        byte[] utf = s.getBytes("UTF-8");
-        byte[] latin1 = s.getBytes("ISO-8859-1");
+        final String s = constructString(SWISS_GERMAN_HELLO);
+        final byte[] utf = s.getBytes("UTF-8");
+        final byte[] latin1 = s.getBytes("ISO-8859-1");
 
-        byte[] data1 = EncodingUtils.getBytes(s, "UTF-8");
-        byte[] data2 = EncodingUtils.getBytes(s, "ISO-8859-1");
+        final byte[] data1 = EncodingUtils.getBytes(s, "UTF-8");
+        final byte[] data2 = EncodingUtils.getBytes(s, "ISO-8859-1");
 
         Assert.assertNotNull(data1);
         Assert.assertEquals(utf.length, data1.length);
@@ -111,46 +111,46 @@ public class TestEncodingUtils {
         try {
             EncodingUtils.getBytes(null, "UTF-8");
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
             // expected
         }
         try {
             EncodingUtils.getBytes("what not", null);
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
             // expected
         }
         try {
             EncodingUtils.getBytes("what not", "");
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
             // expected
         }
     }
 
     @Test
     public void testAsciiBytesToString() throws Exception {
-        String s = "ascii only, I mean it!";
+        final String s = "ascii only, I mean it!";
         Assert.assertEquals(s, EncodingUtils.getAsciiString(s.getBytes("US-ASCII")));
         try {
             EncodingUtils.getAsciiString(null);
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
             // expected
         }
         try {
             EncodingUtils.getAsciiString(null, 0, 0);
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
             // expected
         }
     }
 
     @Test
     public void testAsciiStringToBytes() throws Exception {
-        String s = "ascii only, I mean it!";
-        byte[] ascii = s.getBytes("US-ASCII");
-        byte[] data = EncodingUtils.getAsciiBytes(s);
+        final String s = "ascii only, I mean it!";
+        final byte[] ascii = s.getBytes("US-ASCII");
+        final byte[] data = EncodingUtils.getAsciiBytes(s);
 
         Assert.assertNotNull(data);
         Assert.assertEquals(ascii.length, data.length);
@@ -160,22 +160,22 @@ public class TestEncodingUtils {
         try {
             EncodingUtils.getAsciiBytes(null);
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
             // expected
         }
     }
 
     @Test
     public void testUnsupportedEncoding() {
-        String s = constructString(SWISS_GERMAN_HELLO);
-        byte[] b1 = s.getBytes();
-        byte[] b2 = EncodingUtils.getBytes(s, "ThisJustAintRight");
+        final String s = constructString(SWISS_GERMAN_HELLO);
+        final byte[] b1 = s.getBytes();
+        final byte[] b2 = EncodingUtils.getBytes(s, "ThisJustAintRight");
         Assert.assertEquals(b1.length, b2.length);
         for (int i = 0; i < b1.length; i++) {
             Assert.assertEquals(b1[i], b2[i]);
         }
-        String s1 = new String(b1);
-        String s2 = EncodingUtils.getString(b1, "ThisJustAintRight");
+        final String s1 = new String(b1);
+        final String s2 = EncodingUtils.getString(b1, "ThisJustAintRight");
         Assert.assertEquals(s1, s2);
     }
 
diff --git a/httpcore/src/test/java/org/apache/http/util/TestEntityUtils.java b/httpcore/src/test/java/org/apache/http/util/TestEntityUtils.java
index 07b649b..3768ef3 100644
--- a/httpcore/src/test/java/org/apache/http/util/TestEntityUtils.java
+++ b/httpcore/src/test/java/org/apache/http/util/TestEntityUtils.java
@@ -46,39 +46,39 @@ public class TestEntityUtils {
         try {
             EntityUtils.toByteArray(null);
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
             // expected
         }
     }
 
     @Test
     public void testEmptyContentToByteArray() throws Exception {
-        NullHttpEntity httpentity = new NullHttpEntity();
-        byte[] bytes = EntityUtils.toByteArray(httpentity);
+        final NullHttpEntity httpentity = new NullHttpEntity();
+        final byte[] bytes = EntityUtils.toByteArray(httpentity);
         Assert.assertNull(bytes);
     }
 
     @Test
     public void testMaxIntContentToByteArray() throws Exception {
-        byte[] content = "Message content".getBytes("ISO-8859-1");
-        BasicHttpEntity httpentity = new BasicHttpEntity();
+        final byte[] content = "Message content".getBytes("ISO-8859-1");
+        final BasicHttpEntity httpentity = new BasicHttpEntity();
         httpentity.setContent(new ByteArrayInputStream(content));
         httpentity.setContentLength(Integer.MAX_VALUE + 100L);
         try {
             EntityUtils.toByteArray(httpentity);
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
             // expected
         }
     }
 
     @Test
     public void testUnknownLengthContentToByteArray() throws Exception {
-        byte[] bytes = "Message content".getBytes("ISO-8859-1");
-        BasicHttpEntity httpentity = new BasicHttpEntity();
+        final byte[] bytes = "Message content".getBytes("ISO-8859-1");
+        final BasicHttpEntity httpentity = new BasicHttpEntity();
         httpentity.setContent(new ByteArrayInputStream(bytes));
         httpentity.setContentLength(-1L);
-        byte[] bytes2 = EntityUtils.toByteArray(httpentity);
+        final byte[] bytes2 = EntityUtils.toByteArray(httpentity);
         Assert.assertNotNull(bytes2);
         Assert.assertEquals(bytes.length, bytes2.length);
         for (int i = 0; i < bytes.length; i++) {
@@ -88,11 +88,11 @@ public class TestEntityUtils {
 
     @Test
     public void testKnownLengthContentToByteArray() throws Exception {
-        byte[] bytes = "Message content".getBytes("ISO-8859-1");
-        BasicHttpEntity httpentity = new BasicHttpEntity();
+        final byte[] bytes = "Message content".getBytes("ISO-8859-1");
+        final BasicHttpEntity httpentity = new BasicHttpEntity();
         httpentity.setContent(new ByteArrayInputStream(bytes));
         httpentity.setContentLength(bytes.length);
-        byte[] bytes2 = EntityUtils.toByteArray(httpentity);
+        final byte[] bytes2 = EntityUtils.toByteArray(httpentity);
         Assert.assertNotNull(bytes2);
         Assert.assertEquals(bytes.length, bytes2.length);
         for (int i = 0; i < bytes.length; i++) {
@@ -105,49 +105,49 @@ public class TestEntityUtils {
         try {
             EntityUtils.toString(null);
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
             // expected
         }
     }
 
     @Test
     public void testEmptyContentToString() throws Exception {
-        NullHttpEntity httpentity = new NullHttpEntity();
-        String s = EntityUtils.toString(httpentity);
+        final NullHttpEntity httpentity = new NullHttpEntity();
+        final String s = EntityUtils.toString(httpentity);
         Assert.assertNull(s);
     }
 
     @Test
     public void testMaxIntContentToString() throws Exception {
-        byte[] content = "Message content".getBytes("ISO-8859-1");
-        BasicHttpEntity httpentity = new BasicHttpEntity();
+        final byte[] content = "Message content".getBytes("ISO-8859-1");
+        final BasicHttpEntity httpentity = new BasicHttpEntity();
         httpentity.setContent(new ByteArrayInputStream(content));
         httpentity.setContentLength(Integer.MAX_VALUE + 100L);
         try {
             EntityUtils.toString(httpentity);
             Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
             // expected
         }
     }
 
     @Test
     public void testUnknownLengthContentToString() throws Exception {
-        byte[] bytes = "Message content".getBytes("ISO-8859-1");
-        BasicHttpEntity httpentity = new BasicHttpEntity();
+        final byte[] bytes = "Message content".getBytes("ISO-8859-1");
+        final BasicHttpEntity httpentity = new BasicHttpEntity();
         httpentity.setContent(new ByteArrayInputStream(bytes));
         httpentity.setContentLength(-1L);
-        String s = EntityUtils.toString(httpentity, "ISO-8859-1");
+        final String s = EntityUtils.toString(httpentity, "ISO-8859-1");
         Assert.assertEquals("Message content", s);
     }
 
     @Test
     public void testKnownLengthContentToString() throws Exception {
-        byte[] bytes = "Message content".getBytes("ISO-8859-1");
-        BasicHttpEntity httpentity = new BasicHttpEntity();
+        final byte[] bytes = "Message content".getBytes("ISO-8859-1");
+        final BasicHttpEntity httpentity = new BasicHttpEntity();
         httpentity.setContent(new ByteArrayInputStream(bytes));
         httpentity.setContentLength(bytes.length);
-        String s = EntityUtils.toString(httpentity, "ISO-8859-1");
+        final String s = EntityUtils.toString(httpentity, "ISO-8859-1");
         Assert.assertEquals("Message content", s);
     }
 
@@ -160,11 +160,11 @@ public class TestEntityUtils {
         0x432, 0x435, 0x442
     };
 
-    private static String constructString(int [] unicodeChars) {
-        StringBuilder buffer = new StringBuilder();
+    private static String constructString(final int [] unicodeChars) {
+        final StringBuilder buffer = new StringBuilder();
         if (unicodeChars != null) {
-            for (int i = 0; i < unicodeChars.length; i++) {
-                buffer.append((char)unicodeChars[i]);
+            for (final int unicodeChar : unicodeChars) {
+                buffer.append((char)unicodeChar);
             }
         }
         return buffer.toString();
@@ -172,34 +172,34 @@ public class TestEntityUtils {
 
     @Test
     public void testNoCharsetContentToString() throws Exception {
-        String content = constructString(SWISS_GERMAN_HELLO);
-        byte[] bytes = content.getBytes("ISO-8859-1");
-        BasicHttpEntity httpentity = new BasicHttpEntity();
+        final String content = constructString(SWISS_GERMAN_HELLO);
+        final byte[] bytes = content.getBytes("ISO-8859-1");
+        final BasicHttpEntity httpentity = new BasicHttpEntity();
         httpentity.setContent(new ByteArrayInputStream(bytes));
         httpentity.setContentType(new BasicHeader("Content-Type", "text/plain"));
-        String s = EntityUtils.toString(httpentity);
+        final String s = EntityUtils.toString(httpentity);
         Assert.assertEquals(content, s);
     }
 
     @Test
     public void testDefaultCharsetContentToString() throws Exception {
-        String content = constructString(RUSSIAN_HELLO);
-        byte[] bytes = content.getBytes("KOI8-R");
-        BasicHttpEntity httpentity = new BasicHttpEntity();
+        final String content = constructString(RUSSIAN_HELLO);
+        final byte[] bytes = content.getBytes("KOI8-R");
+        final BasicHttpEntity httpentity = new BasicHttpEntity();
         httpentity.setContent(new ByteArrayInputStream(bytes));
         httpentity.setContentType(new BasicHeader("Content-Type", "text/plain"));
-        String s = EntityUtils.toString(httpentity, "KOI8-R");
+        final String s = EntityUtils.toString(httpentity, "KOI8-R");
         Assert.assertEquals(content, s);
     }
 
     @Test
     public void testContentWithContentTypeToString() throws Exception {
-        String content = constructString(RUSSIAN_HELLO);
-        byte[] bytes = content.getBytes("UTF-8");
-        BasicHttpEntity httpentity = new BasicHttpEntity();
+        final String content = constructString(RUSSIAN_HELLO);
+        final byte[] bytes = content.getBytes("UTF-8");
+        final BasicHttpEntity httpentity = new BasicHttpEntity();
         httpentity.setContent(new ByteArrayInputStream(bytes));
         httpentity.setContentType(new BasicHeader("Content-Type", "text/plain; charset=UTF-8"));
-        String s = EntityUtils.toString(httpentity, "ISO-8859-1");
+        final String s = EntityUtils.toString(httpentity, "ISO-8859-1");
         Assert.assertEquals(content, s);
     }
 
diff --git a/httpcore/src/test/java/org/apache/http/util/TestLangUtils.java b/httpcore/src/test/java/org/apache/http/util/TestLangUtils.java
index 6a339c4..bc678d1 100644
--- a/httpcore/src/test/java/org/apache/http/util/TestLangUtils.java
+++ b/httpcore/src/test/java/org/apache/http/util/TestLangUtils.java
@@ -38,25 +38,25 @@ public class TestLangUtils {
 
     @Test
     public void testBasicHash() {
-        Integer i = new Integer(1234);
-        int h1 = LangUtils.hashCode(LangUtils.HASH_SEED, i.hashCode());
-        int h2 = LangUtils.hashCode(LangUtils.HASH_SEED, i);
+        final Integer i = new Integer(1234);
+        final int h1 = LangUtils.hashCode(LangUtils.HASH_SEED, i.hashCode());
+        final int h2 = LangUtils.hashCode(LangUtils.HASH_SEED, i);
         Assert.assertTrue(h1 == h2);
     }
 
     @Test
     public void testNullObjectHash() {
-        int h1 = LangUtils.hashCode(LangUtils.HASH_SEED, null);
-        int h2 = LangUtils.hashCode(LangUtils.HASH_SEED, 0);
+        final int h1 = LangUtils.hashCode(LangUtils.HASH_SEED, null);
+        final int h2 = LangUtils.hashCode(LangUtils.HASH_SEED, 0);
         Assert.assertTrue(h1 == h2);
     }
 
     @Test
     public void testBooleanHash() {
-        int h1 = LangUtils.hashCode(LangUtils.HASH_SEED, true);
-        int h2 = LangUtils.hashCode(LangUtils.HASH_SEED, false);
-        int h3 = LangUtils.hashCode(LangUtils.HASH_SEED, true);
-        int h4 = LangUtils.hashCode(LangUtils.HASH_SEED, false);
+        final int h1 = LangUtils.hashCode(LangUtils.HASH_SEED, true);
+        final int h2 = LangUtils.hashCode(LangUtils.HASH_SEED, false);
+        final int h3 = LangUtils.hashCode(LangUtils.HASH_SEED, true);
+        final int h4 = LangUtils.hashCode(LangUtils.HASH_SEED, false);
         Assert.assertTrue(h1 != h2);
         Assert.assertTrue(h1 == h3);
         Assert.assertTrue(h2 == h4);
diff --git a/pom.xml b/pom.xml
index 590b859..5885a04 100644
--- a/pom.xml
+++ b/pom.xml
@@ -28,13 +28,13 @@
   <parent>
     <artifactId>project</artifactId>
     <groupId>org.apache.httpcomponents</groupId>
-    <version>6</version>
+    <version>7</version>
     <relativePath>../project/pom.xml</relativePath>
   </parent>
   <modelVersion>4.0.0</modelVersion>
   <artifactId>httpcomponents-core</artifactId>
-  <name>HttpComponents Core</name>
-  <version>4.2.4</version>
+  <name>Apache HttpComponents Core</name>
+  <version>4.3</version>
   <description>Core components to build HTTP enabled services</description>
   <url>http://hc.apache.org/httpcomponents-core</url>
   <inceptionYear>2005</inceptionYear>
@@ -59,9 +59,9 @@
   </issueManagement>
 
   <scm>
-    <connection>scm:svn:http://svn.apache.org/repos/asf/httpcomponents/httpcore/tags/4.2.4</connection>
-    <developerConnection>scm:svn:https://svn.apache.org/repos/asf/httpcomponents/httpcore/tags/4.2.4</developerConnection>
-    <url>http://svn.apache.org/repos/asf/httpcomponents/httpcore/tags/4.2.4</url>
+    <connection>scm:svn:http://svn.apache.org/repos/asf/httpcomponents/httpcore/tags/4.3</connection>
+    <developerConnection>scm:svn:https://svn.apache.org/repos/asf/httpcomponents/httpcore/tags/4.3</developerConnection>
+    <url>http://svn.apache.org/repos/asf/httpcomponents/httpcore/tags/4.3</url>
   </scm>
 
   <modules>
@@ -72,12 +72,13 @@
   </modules>
 
   <properties>
-    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
-    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
+    <!-- Override parent 7 setting for deprecation (only - other settings stand)-->
+    <maven.compiler.showDeprecation>false</maven.compiler.showDeprecation>
     <junit.version>4.9</junit.version>
     <mockito.version>1.8.5</mockito.version>
-    <commons-logging.version>1.1.1</commons-logging.version>
+    <commons-logging.version>1.1.3</commons-logging.version>
     <api.comparison.version>4.2</api.comparison.version>
+    <hc.stylecheck.version>1</hc.stylecheck.version>
   </properties>
 
   <dependencyManagement>
@@ -106,21 +107,6 @@
   <build>
     <plugins>
       <plugin>
-        <artifactId>maven-notice-plugin</artifactId>
-        <groupId>org.apache.httpcomponents</groupId>
-        <executions>
-          <execution>
-            <id>attach-notice-license</id>
-            <goals>
-              <goal>generate</goal>
-            </goals>
-          </execution>
-        </executions>
-        <configuration>
-          <projectTitle>Apache HttpComponents</projectTitle>
-        </configuration>
-      </plugin>
-      <plugin>
         <artifactId>maven-jar-plugin</artifactId>
         <configuration>
           <archive>
@@ -152,13 +138,6 @@
         <artifactId>maven-javadoc-plugin</artifactId>
         <executions>
           <execution>
-            <id>javadoc-aggregate</id>
-            <goals>
-              <goal>aggregate</goal>
-            </goals>
-            <phase>pre-site</phase>
-          </execution>
-          <execution>
             <id>attach-javadocs</id>
             <goals>
               <goal>jar</goal>
@@ -168,7 +147,7 @@
         <configuration>
           <!-- reduce console output. Can override with -Dquiet=false -->
           <quiet>true</quiet>
-          <source>1.5</source>
+          <source>${maven.compiler.source}</source>
           <links>
             <link>http://download.oracle.com/javase/1.5.0/docs/api/</link>
           </links>
@@ -178,37 +157,6 @@
         <artifactId>maven-site-plugin</artifactId>
       </plugin>
       <plugin>
-        <artifactId>maven-assembly-plugin</artifactId>
-        <configuration>
-          <descriptors>
-            <descriptor>src/main/assembly/bin.xml</descriptor>
-            <descriptor>src/main/assembly/osgi-bin.xml</descriptor>
-            <descriptor>src/main/assembly/src.xml</descriptor>
-          </descriptors>
-          <tarLongFileMode>gnu</tarLongFileMode>
-        </configuration>
-      </plugin>
-      <plugin>
-        <artifactId>maven-antrun-plugin</artifactId>
-        <inherited>false</inherited>
-        <configuration>
-          <tasks>
-            <ant antfile="src/main/assembly/build.xml">
-              <property name="target" value="${project.build.directory}" />
-              <property name="package.name" value="${project.artifactId}-${project.version}-bin" />
-            </ant>
-            <ant antfile="src/main/assembly/build.xml">
-              <property name="target" value="${project.build.directory}" />
-              <property name="package.name" value="${project.artifactId}-${project.version}-src" />
-            </ant>
-            <ant antfile="src/main/assembly/build.xml">
-              <property name="target" value="${project.build.directory}" />
-              <property name="package.name" value="${project.artifactId}-${project.version}-osgi-bin" />
-            </ant>
-          </tasks>
-        </configuration>
-      </plugin>
-      <plugin>
         <groupId>com.agilejava.docbkx</groupId>
         <artifactId>docbkx-maven-plugin</artifactId>
         <dependencies>
@@ -228,7 +176,7 @@
             </goals>
             <phase>pre-site</phase>
           </execution>
-        </executions>        
+        </executions>
         <configuration>
           <includes>index.xml</includes>
           <chunkedOutput>true</chunkedOutput>
@@ -283,9 +231,72 @@
       </plugin>
       <plugin>
         <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-release-plugin</artifactId>
+        <artifactId>maven-checkstyle-plugin</artifactId>
+        <version>2.9.1</version>
+        <dependencies>
+          <dependency>
+            <groupId>org.apache.httpcomponents</groupId>
+            <artifactId>hc-stylecheck</artifactId>
+            <version>${hc.stylecheck.version}</version>
+          </dependency>
+        </dependencies>
         <configuration>
-          <autoVersionSubmodules>true</autoVersionSubmodules>
+          <encoding>UTF-8</encoding>
+        </configuration>
+        <executions>
+          <execution>
+            <id>validate-main</id>
+            <phase>validate</phase>
+            <configuration>
+              <configLocation>hc-stylecheck/default.xml</configLocation>
+              <headerLocation>hc-stylecheck/asl2.header</headerLocation>
+              <consoleOutput>true</consoleOutput>
+              <failsOnError>true</failsOnError>
+              <linkXRef>false</linkXRef>
+              <sourceDirectory>${basedir}/src/main</sourceDirectory>
+            </configuration>
+            <goals>
+              <goal>checkstyle</goal>
+            </goals>
+          </execution>
+          <execution>
+            <id>validate-test</id>
+            <phase>validate</phase>
+            <configuration>
+              <configLocation>hc-stylecheck/default.xml</configLocation>
+              <headerLocation>hc-stylecheck/asl2.header</headerLocation>
+              <consoleOutput>true</consoleOutput>
+              <failsOnError>true</failsOnError>
+              <linkXRef>false</linkXRef>
+              <sourceDirectory>${basedir}/src/test</sourceDirectory>
+            </configuration>
+            <goals>
+              <goal>checkstyle</goal>
+            </goals>
+          </execution>
+          <execution>
+            <id>validate-examples</id>
+            <phase>validate</phase>
+            <configuration>
+              <configLocation>hc-stylecheck/minimal.xml</configLocation>
+              <headerLocation>hc-stylecheck/asl2.header</headerLocation>
+              <consoleOutput>true</consoleOutput>
+              <failsOnError>true</failsOnError>
+              <linkXRef>false</linkXRef>
+              <sourceDirectory>${basedir}/src/examples</sourceDirectory>
+            </configuration>
+            <goals>
+              <goal>checkstyle</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <groupId>org.codehaus.mojo</groupId>
+        <artifactId>clirr-maven-plugin</artifactId>
+        <version>${hc.clirr.version}</version>
+        <configuration>
+          <comparisonVersion>${api.comparison.version}</comparisonVersion>
         </configuration>
       </plugin>
     </plugins>
diff --git a/src/docbkx/advanced.xml b/src/docbkx/advanced.xml
index c800baa..76c38ba 100644
--- a/src/docbkx/advanced.xml
+++ b/src/docbkx/advanced.xml
@@ -89,12 +89,12 @@ CharArrayBuffer buf = new CharArrayBuffer(64);
 buf.append("HTTP/1.1 200");
 ParserCursor cursor = new ParserCursor(0, buf.length());
 
-LineParser parser = new BasicLineParser();
+LineParser parser = BasicLineParser.INSTANCE;
 ProtocolVersion ver = parser.parseProtocolVersion(buf, cursor);
 System.out.println(ver);
 System.out.println(buf.substringTrimmed(
-    cursor.getPos(),
-    cursor.getUpperBound()));
+        cursor.getPos(),
+        cursor.getUpperBound()));
 ]]></programlisting>
             <para>stdout ></para>
             <programlisting><![CDATA[
@@ -202,14 +202,13 @@ name1="value1"; param1="p1", name2="value2", name3="value3"
             reading and writing <literal>CR-LF</literal> delimited lines.
             </para>
             <programlisting><![CDATA[
-Socket socket1;
-Socket socket2;
-HttpParams params = new BasicHttpParams();
-SessionInputBuffer inbuffer = new SocketInputBuffer(
-    socket1, 4096, params);
-SessionOutputBuffer outbuffer = new SocketOutputBuffer(
-    socket2, 4096, params);
-
+Socket socket1 = <...>
+Socket socket2 = <...>
+HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
+SessionInputBufferImpl inbuffer = new SessionInputBufferImpl(metrics, 8 * 1024);
+inbuffer.bind(socket1.getInputStream());
+SessionOutputBufferImpl outbuffer = new SessionOutputBufferImpl(metrics, 8 * 1024);
+outbuffer.bind(socket2.getOutputStream());
 CharArrayBuffer linebuf = new CharArrayBuffer(1024);
 inbuffer.readLine(linebuf);
 outbuffer.writeLine(linebuf);
@@ -220,14 +219,11 @@ outbuffer.writeLine(linebuf);
             with <literal>CR-LF</literal> delimited lines in a non-blocking I/O mode.
             </para>
             <programlisting><![CDATA[
-ReadableByteChannel channel1;
-WritableByteChannel channel2;
+ReadableByteChannel channel1 = <...>
+WritableByteChannel channel2 = <...>
 
-HttpParams params = new BasicHttpParams();
-SessionInputBuffer inbuffer = new SessionInputBufferImpl(
-    4096, 1024, params);
-SessionOutputBuffer outbuffer = new SessionOutputBufferImpl(
-    4096, 1024, params);
+SessionInputBuffer inbuffer = new SessionInputBufferImpl(8 * 1024);
+SessionOutputBuffer outbuffer = new SessionOutputBufferImpl(8 * 1024);
 
 CharArrayBuffer linebuf = new CharArrayBuffer(1024);
 boolean endOfStream = false;
@@ -256,99 +252,122 @@ if (outbuffer.hasData()) {
             Example of HTTP request parsing / writing for blocking HTTP connections:
             </para>
             <programlisting><![CDATA[
-SessionInputBuffer inbuffer;
-SessionOutputBuffer outbuffer;
-
-HttpParams params = new BasicHttpParams();
-
-HttpMessageParser requestParser = new HttpRequestParser(
-        inbuffer,
-        new BasicLineParser(),
-        new DefaultHttpRequestFactory(),
-        params);
-
-HttpRequest request = (HttpRequest) requestParser.parse();
-
-HttpMessageWriter requestWriter = new HttpRequestWriter(
-        outbuffer,
-        new BasicLineFormatter(),
-        params);
-
+SessionInputBuffer inbuffer = <...>
+SessionOutputBuffer outbuffer = <...>
+
+HttpMessageParser<HttpRequest> requestParser = new DefaultHttpRequestParser(
+    inbuffer);
+HttpRequest request = requestParser.parse();
+HttpMessageWriter<HttpRequest> requestWriter = new DefaultHttpRequestWriter(
+    outbuffer);
 requestWriter.write(request);
 ]]></programlisting>
             <para>
             Example of HTTP response parsing / writing for blocking HTTP connections:
             </para>
             <programlisting><![CDATA[
-SessionInputBuffer inbuffer;
-SessionOutputBuffer outbuffer;
-
-HttpParams params = new BasicHttpParams();
-
-HttpMessageParser responseParser = new HttpResponseParser(
-        inbuffer,
-        new BasicLineParser(),
-        new DefaultHttpResponseFactory(),
-        params);
-
-HttpResponse response = (HttpResponse) responseParser.parse();
-
-HttpMessageWriter responseWriter = new HttpResponseWriter(
-        outbuffer,
-        new BasicLineFormatter(),
-        params);
-
+SessionInputBuffer inbuffer = <...>
+SessionOutputBuffer outbuffer = <...>
+
+HttpMessageParser<HttpResponse> responseParser = new DefaultHttpResponseParser(
+        inbuffer);
+HttpResponse response = responseParser.parse();
+HttpMessageWriter<HttpResponse> responseWriter = new DefaultHttpResponseWriter(
+        outbuffer);
 responseWriter.write(response);
 ]]></programlisting>
             <para>
+            Custom message parsers and writers can be plugged into the message processing pipeline
+            through a custom connection factory:
+            </para>
+            <programlisting><![CDATA[
+HttpMessageWriterFactory<HttpResponse> responseWriterFactory =
+                                new HttpMessageWriterFactory<HttpResponse>() {
+    @Override
+    public HttpMessageWriter<HttpResponse> create(
+            SessionOutputBuffer buffer) {
+        HttpMessageWriter<HttpResponse> customWriter = <...>
+        return customWriter;
+    }
+};
+HttpMessageParserFactory<HttpRequest> requestParserFactory =
+                                new HttpMessageParserFactory<HttpRequest>() {
+    @Override
+    public HttpMessageParser<HttpRequest> create(
+            SessionInputBuffer buffer,
+            MessageConstraints constraints) {
+        HttpMessageParser<HttpRequest> customParser = <...>
+        return customParser;
+    }
+};
+HttpConnectionFactory<DefaultBHttpServerConnection> cf =
+                                new DefaultBHttpServerConnectionFactory(
+        ConnectionConfig.DEFAULT,
+        requestParserFactory,
+        responseWriterFactory);
+Socket socket = <...>
+DefaultBHttpServerConnection conn = cf.createConnection(socket);
+]]></programlisting>
+            <para>
             Example of HTTP request parsing / writing for non-blocking HTTP connections:
             </para>
             <programlisting><![CDATA[
-SessionInputBuffer inbuffer;
-SessionOutputBuffer outbuffer;
-
-HttpParams params = new BasicHttpParams();
-
-NHttpMessageParser requestParser = new DefaultHttpRequestParser(
-        inbuffer,
-        new BasicLineParser(),
-        new DefaultHttpRequestFactory(),
-        params);
-
-HttpRequest request = (HttpRequest) requestParser.parse();
-
-NHttpMessageWriter requestWriter = new DefaultHttpRequestWriter(
-        outbuffer,
-        new BasicLineFormatter(),
-        params);
-
+SessionInputBuffer inbuffer = <...>
+SessionOutputBuffer outbuffer  = <...>
+
+NHttpMessageParser<HttpRequest> requestParser = new DefaultHttpRequestParser(
+        inbuffer);
+HttpRequest request = requestParser.parse();
+NHttpMessageWriter<HttpRequest> requestWriter = new DefaultHttpRequestWriter(
+        outbuffer);
 requestWriter.write(request);
 ]]></programlisting>
             <para>
             Example of HTTP response parsing / writing for non-blocking HTTP connections:
             </para>
             <programlisting><![CDATA[
-SessionInputBuffer inbuffer;
-SessionOutputBuffer outbuffer;
-
-HttpParams params = new BasicHttpParams();
-
-NHttpMessageParser responseParser = new DefaultHttpResponseParser(
-        inbuffer,
-        new BasicLineParser(),
-        new DefaultHttpResponseFactory(),
-        params);
-
-HttpResponse response = (HttpResponse) responseParser.parse();
+SessionInputBuffer inbuffer = <...>
+SessionOutputBuffer outbuffer  = <...>
 
+NHttpMessageParser<HttpResponse> responseParser = new DefaultHttpResponseParser(
+        inbuffer);
+HttpResponse response = responseParser.parse();
 NHttpMessageWriter responseWriter = new DefaultHttpResponseWriter(
-        outbuffer,
-        new BasicLineFormatter(),
-        params);
-
+        outbuffer);
 responseWriter.write(response);
 ]]></programlisting>
         </section>
+        <para>
+        Custom non-blocking message parsers and writers can be plugged into the message processing
+        pipeline through a custom connection factory:
+        </para>
+        <programlisting><![CDATA[
+NHttpMessageWriterFactory<HttpResponse> responseWriterFactory =
+                        new NHttpMessageWriterFactory<HttpResponse>() {
+    @Override
+    public NHttpMessageWriter<HttpResponse> create(SessionOutputBuffer buffer) {
+        NHttpMessageWriter<HttpResponse> customWriter = <...>
+        return customWriter;
+    }
+};
+NHttpMessageParserFactory<HttpRequest> requestParserFactory =
+                        new NHttpMessageParserFactory<HttpRequest>() {
+    @Override
+    public NHttpMessageParser<HttpRequest> create(
+            SessionInputBuffer buffer, MessageConstraints constraints) {
+        NHttpMessageParser<HttpRequest> customParser = <...>
+        return customParser;
+    }
+};
+NHttpConnectionFactory<DefaultNHttpServerConnection> cf =
+                        new DefaultNHttpServerConnectionFactory(
+        null,
+        requestParserFactory,
+        responseWriterFactory,
+        ConnectionConfig.DEFAULT);
+IOSession iosession = <...>
+DefaultNHttpServerConnection conn = cf.createConnection(iosession);
+]]></programlisting>
         <section>
             <title>HTTP header parsing on demand</title>
             <para>
@@ -360,6 +379,7 @@ responseWriter.write(response);
             optional <interfacename>FormattedHeader</interfacename> interface.
             </para>
             <programlisting><![CDATA[
+HttpResponse response = <...>
 Header h1 = response.getFirstHeader("Content-Type");
 if (h1 instanceof FormattedHeader) {
     CharArrayBuffer buf = ((FormattedHeader) h1).getBuffer();
@@ -368,91 +388,4 @@ if (h1 instanceof FormattedHeader) {
 ]]></programlisting>
         </section>
     </section>
-    <section>
-        <title>Customizing HTTP connections</title>
-        <para>
-        One can customize the way HTTP connections parse and format HTTP messages by extending the
-        default implementations and overriding factory methods and replacing the default parser or
-        formatter implementations with a custom one.
-        </para>
-        <para>
-        For blocking HTTP connections one also can provide custom implementation of session
-        input/output buffers.
-        </para>
-        <programlisting><![CDATA[
-class MyDefaultHttpClientConnection
-                        extends DefaultHttpClientConnection {
-
-    @Override
-    protected SessionInputBuffer createSessionInputBuffer(
-            Socket socket,
-            int buffersize,
-            HttpParams params) throws IOException {
-        return new MySocketInputBuffer(socket, buffersize, params);
-    }
-
-    @Override
-    protected SessionOutputBuffer createSessionOutputBuffer(
-            Socket socket,
-            int buffersize,
-            HttpParams params) throws IOException {
-        return new MySocketOutputBuffer(socket, buffersize, params);
-    }
-
-    @Override
-    protected HttpMessageWriter createRequestWriter(
-            SessionOutputBuffer buffer,
-            HttpParams params) {
-        return new MyHttpRequestWriter(
-            buffer, new BasicLineFormatter(), params);
-    }
-
-    @Override
-    protected HttpMessageParser createResponseParser(
-            SessionInputBuffer buffer,
-            HttpResponseFactory responseFactory,
-            HttpParams params) {
-        return new MyHttpResponseParser(
-        buffer, new BasicLineParser(), responseFactory, params);
-    }
-
-};
-]]></programlisting>
-        <para>
-        For non-blocking HTTP connection implementation one can replace the default HTTP message
-        parser and formatter implementations. The session input/output buffer implementations can
-        be overridden at the I/O reactor level.
-        </para>
-        <programlisting><![CDATA[
-class MyDefaultNHttpClientConnection
-                        extends DefaultNHttpClientConnection {
-
-    public MyDefaultNHttpClientConnection(
-            IOSession session,
-            HttpResponseFactory responseFactory,
-            ByteBufferAllocator allocator,
-            HttpParams params) {
-        super(session, responseFactory, allocator, params);
-    }
-
-    @Override
-    protected NHttpMessageWriter createRequestWriter(
-            SessionOutputBuffer buffer,
-            HttpParams params) {
-        return new HttpRequestWriter(
-            buffer, new BasicLineFormatter(), params);
-    }
-
-    @Override
-    protected NHttpMessageParser createResponseParser(
-            SessionInputBuffer buffer,
-            HttpResponseFactory responseFactory,
-            HttpParams params) {
-        return new HttpResponseParser(
-            buffer, new BasicLineParser(), responseFactory, params);
-    }
-
-};
-]]></programlisting>
-    </section>
 </chapter>
diff --git a/src/docbkx/fundamentals.xml b/src/docbkx/fundamentals.xml
index 8ca5422..42d202c 100644
--- a/src/docbkx/fundamentals.xml
+++ b/src/docbkx/fundamentals.xml
@@ -23,7 +23,7 @@
 
 -->
 <chapter id="fundamentals">
-    <title>Fundamentals</title>
+    <title>HTTP message fundamentals and classic synchronous I/O</title>
     <section>
         <title>HTTP messages</title>
         <section>
@@ -36,7 +36,7 @@
             enclose a content body.
             </para>
             <para>
-            HttpCore defines the HTTP message object model to closely follow this definition and
+            HttpCore defines the HTTP message object model to follow closely this definition and
             provides extensive support for serialization (formatting) and deserialization
             (parsing) of HTTP message elements.
             </para>
@@ -47,7 +47,7 @@
                 <title>HTTP request message</title>
                 <para>
                 HTTP request is a message sent from the client to the server. The first line of
-                that message includes the method to be applied to the resource, the identifier of
+                that message includes the method to apply to the resource, the identifier of
                 the resource, and the protocol version in use.
                 </para>
                 <programlisting><![CDATA[
@@ -96,8 +96,8 @@ HTTP/1.1 200 OK
                 <title>HTTP message common properties and methods</title>
                 <para>
                 An HTTP message can contain a number of headers describing properties of the
-                message such as the content length, content type and so on. HttpCore provides
-                methods to retrieve, add, remove and enumerate such headers.
+                message such as the content length, content type, and so on. HttpCore provides
+                methods to retrieve, add, remove, and enumerate such headers.
                 </para>
                 <programlisting><![CDATA[
 HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1,
@@ -177,9 +177,9 @@ c3 = c
  domain=localhost
 ]]></programlisting>
                 <para>
-                HTTP headers get tokenized into individual header elements only on demand. HTTP
+                HTTP headers are tokenized into individual header elements only on demand. HTTP
                 headers received over an HTTP connection are stored internally as an array of
-                characters and parsed lazily only when their properties are accessed.
+                characters and parsed lazily only when you access their properties.
                 </para>
             </section>
         </section>
@@ -188,8 +188,8 @@ c3 = c
             <para>
             HTTP messages can carry a content entity associated with the request or response.
             Entities can be found in some requests and in some responses, as they are optional.
-            Requests that use entities are referred to as entity enclosing requests. The HTTP
-            specification defines two entity enclosing methods: POST and PUT. Responses are
+            Requests that use entities are referred to as entity-enclosing requests. The HTTP
+            specification defines two entity-enclosing methods: POST and PUT. Responses are
             usually expected to enclose a content entity. There are exceptions to this rule such
             as responses to HEAD method and 204 No Content, 304 Not Modified, 205 Reset Content
             responses.
@@ -229,16 +229,16 @@ c3 = c
             </itemizedlist>
             <para>
             This distinction is important for connection management with incoming entities. For
-            entities that are created by an application and only sent using the HttpCore framework,
+            an application that creates entities and only sends them using the HttpCore framework,
             the difference between streamed and self-contained is of little importance. In that
-            case, it is suggested to consider non-repeatable entities as streamed, and those that
+            case, we suggest you consider non-repeatable entities as streamed, and those that
             are repeatable as self-contained.
             </para>
             <section>
                 <title>Repeatable entities</title>
                 <para>
-                An entity can be repeatable, meaning its content can be read more than once. This
-                is only possible with self contained entities (like
+                An entity can be repeatable, meaning you can read its content more than once. This
+                is only possible with self-contained entities (like
                 <classname>ByteArrayEntity</classname> or <classname>StringEntity</classname>).
                 </para>
             </section>
@@ -246,7 +246,7 @@ c3 = c
                 <title>Using HTTP entities</title>
                 <para>
                 Since an entity can represent both binary and character content, it has support
-                for character encodings (to support the latter, ie. character content).
+                for character encodings (to support the latter, i.e. character content).
                 </para>
                 <para>
                 The entity is created when executing a request with enclosed content or when the
@@ -261,10 +261,10 @@ c3 = c
                 return once all content has been written to the given stream.
                 </para>
                 <para>
-                The <classname>EntityUtils</classname> class exposes several static methods to
-                more easily read the content or information from an entity. Instead of reading
-                the <classname>java.io.InputStream</classname> directly, one can retrieve the whole
-                content body in a string / byte array by using the methods from this class.
+                The <classname>EntityUtils</classname> class exposes several static methods to read
+                more easily the content or information from an entity. Instead of reading
+                the <classname>java.io.InputStream</classname> directly, one can retrieve the complete
+                content body in a string or byte array by using the methods from this class.
                 </para>
                 <para>
                 When the entity has been received with an incoming message, the methods
@@ -286,11 +286,10 @@ c3 = c
                 </para>
                 <programlisting><![CDATA[
 StringEntity myEntity = new StringEntity("important message",
-    "UTF-8");
+    Consts.UTF_8);
 
 System.out.println(myEntity.getContentType());
 System.out.println(myEntity.getContentLength());
-System.out.println(EntityUtils.getContentCharSet(myEntity));
 System.out.println(EntityUtils.toString(myEntity));
 System.out.println(EntityUtils.toByteArray(myEntity).length);
 ]]></programlisting>
@@ -298,7 +297,6 @@ System.out.println(EntityUtils.toByteArray(myEntity).length);
                 <programlisting><![CDATA[
 Content-Type: text/plain; charset=UTF-8
 17
-UTF-8
 important message
 17
 ]]></programlisting>
@@ -340,8 +338,7 @@ if (entity != null) {
         <section>
             <title>Creating entities</title>
             <para>
-            There are a few ways to create entities. The following implementations are provided
-            by HttpCore:
+            There are a few ways to create entities. HttpCore provides the following implementations:
             </para>
             <itemizedlist>
                 <listitem>
@@ -404,11 +401,11 @@ if (entity != null) {
             <section id="basic-entity">
                 <title><classname>BasicHttpEntity</classname></title>
                 <para>
-                This is exactly as the name implies, a basic entity that represents an underlying
-                stream. This is generally used for the entities received from HTTP messages.
+                Exactly as the name implies, this basic entity represents an underlying stream.
+                In general, use this class for entities received from HTTP messages.
                 </para>
                 <para>
-                This entity has an empty constructor. After construction it represents no content,
+                This entity has an empty constructor. After construction, it represents no content,
                 and has a negative content length.
                 </para>
                 <para>
@@ -426,19 +423,19 @@ myEntity.setContentLength(340); // sets the length to 340
             <section id="byte-array-entity">
                 <title><classname>ByteArrayEntity</classname></title>
                 <para>
-                <classname>ByteArrayEntity</classname> is a self contained, repeatable entity
-                that obtains its content from a given byte array. This byte array is supplied
-                to the constructor.
+                <classname>ByteArrayEntity</classname> is a self-contained, repeatable entity
+                that obtains its content from a given byte array. Supply the byte array to the
+                constructor.
                 </para>
                 <programlisting><![CDATA[
-String myData = "Hello world on the other side!!";
-ByteArrayEntity myEntity = new ByteArrayEntity(myData.getBytes());
+ByteArrayEntity myEntity = new ByteArrayEntity(new byte[] {1,2,3},
+        ContentType.APPLICATION_OCTET_STREAM);
 ]]></programlisting>
             </section>
             <section id="string-entity">
                 <title><classname>StringEntity</classname></title>
                 <para>
-                <classname>StringEntity</classname> is a self contained, repeatable entity that
+                <classname>StringEntity</classname> is a self-contained, repeatable entity that
                 obtains its content from a <classname>java.lang.String</classname> object. It has
                 three constructors, one simply constructs with a given <classname>java.lang.String
                 </classname> object; the second also takes a character encoding for the data in the
@@ -447,32 +444,34 @@ ByteArrayEntity myEntity = new ByteArrayEntity(myData.getBytes());
                 <programlisting><![CDATA[
 StringBuilder sb = new StringBuilder();
 Map<String, String> env = System.getenv();
-for (Entry<String, String> envEntry : env.entrySet()) {
-    sb.append(envEntry.getKey()).append(": ")
-    .append(envEntry.getValue()).append("\n");
+for (Map.Entry<String, String> envEntry : env.entrySet()) {
+    sb.append(envEntry.getKey())
+            .append(": ").append(envEntry.getValue())
+            .append("\r\n");
 }
 
 // construct without a character encoding (defaults to ISO-8859-1)
 HttpEntity myEntity1 = new StringEntity(sb.toString());
 
 // alternatively construct with an encoding (mime type defaults to "text/plain")
-HttpEntity myEntity2 = new StringEntity(sb.toString(), "UTF-8");
+HttpEntity myEntity2 = new StringEntity(sb.toString(), Consts.UTF_8);
 
 // alternatively construct with an encoding and a mime type
-HttpEntity myEntity3 = new StringEntity(sb.toString(), "text/html", "UTF-8");
+HttpEntity myEntity3 = new StringEntity(sb.toString(),
+        ContentType.create("text/plain", Consts.UTF_8));
 ]]></programlisting>
             </section>
             <section id="input-stream-entity">
                 <title><classname>InputStreamEntity</classname></title>
                 <para>
                 <classname>InputStreamEntity</classname> is a streamed, non-repeatable entity that
-                obtains its content from an input stream. It is constructed by supplying the input
-                stream and the content length. The content length is used to limit the amount of
-                data read from the <classname>java.io.InputStream</classname>. If the length matches
+                obtains its content from an input stream. Construct it by supplying the input
+                stream and the content length. Use the content length to limit the amount of data
+                read from the <classname>java.io.InputStream</classname>. If the length matches
                 the content length available on the input stream, then all data will be sent.
-                Alternatively a negative content length will read all data from the input stream,
-                which is the same as supplying the exact content length, so the length is most
-                often used to limit the length.
+                Alternatively, a negative content length will read all data from the input stream,
+                which is the same as supplying the exact content length, so use the length to limit
+                the amount of data to read.
                 </para>
                 <programlisting><![CDATA[
 InputStream instream = getSomeInputStream();
@@ -482,15 +481,15 @@ InputStreamEntity myEntity = new InputStreamEntity(instream, 16);
             <section id="file-entity">
                 <title><classname>FileEntity</classname></title>
                 <para>
-                <classname>FileEntity</classname> is a self contained, repeatable entity that
-                obtains its content from a file. Since this is mostly used to stream large files
-                of different types, one needs to supply the content type of the file, for
+                <classname>FileEntity</classname> is a self-contained, repeatable entity that
+                obtains its content from a file. Use this mostly to stream large files of different
+                types, where you need to supply the content type of the file, for
                 instance, sending a zip file would require the content type <literal>
                 application/zip</literal>, for XML <literal>application/xml</literal>.
                 </para>
                 <programlisting><![CDATA[
 HttpEntity entity = new FileEntity(staticFile,
-    "application/java-archive");
+        ContentType.create("application/java-archive"));
 ]]></programlisting>
             </section>
             <section id="entity-wrapper">
@@ -506,13 +505,13 @@ HttpEntity entity = new FileEntity(staticFile,
                 <title><classname>BufferedHttpEntity</classname></title>
                 <para>
                 <classname>BufferedHttpEntity</classname> is a subclass of <classname>
-                HttpEntityWrapper</classname>. It is constructed by supplying another entity. It
+                HttpEntityWrapper</classname>. Construct it by supplying another entity. It
                 reads the content from the supplied entity, and buffers it in memory.
                 </para>
                 <para>
                 This makes it possible to make a repeatable entity, from a non-repeatable entity.
-                If the supplied entity is already repeatable, calls are simply passed through to the
-                underlying entity.
+                If the supplied entity is already repeatable, it simply passes calls through to
+                the underlying entity.
                 </para>
                 <programlisting><![CDATA[
 myNonRepeatableEntity.setContent(someInputStream);
@@ -533,8 +532,8 @@ BufferedHttpEntity myBufferedEntity = new BufferedHttpEntity(
         addresses.
         </para>
         <para>
-        It is important to bear in mind that HTTP connections are not thread-safe. It is strongly
-        recommended to limit all interactions with HTTP connection objects to one thread. The only
+        It is important to bear in mind that HTTP connections are not thread-safe. We strongly
+        recommend limiting all interactions with HTTP connection objects to one thread. The only
         method of <interfacename>HttpConnection</interfacename> interface and its sub-interfaces
         which is safe to invoke from another thread is <methodname> HttpConnection#shutdown()
         </methodname>.
@@ -548,36 +547,34 @@ BufferedHttpEntity myBufferedEntity = new BufferedHttpEntity(
             HTTP connections can be bound to any arbitrary network socket.
             </para>
             <programlisting><![CDATA[
-Socket socket = new Socket();
-// Initialize socket
-BasicHttpParams params = new BasicHttpParams();
-DefaultHttpClientConnection conn = new DefaultHttpClientConnection();
-conn.bind(socket, params);
-conn.isOpen();
+Socket socket = <...>
+
+DefaultBHttpClientConnection conn = new DefaultBHttpClientConnection(8 * 1024);
+conn.bind(socket);
+System.out.println(conn.isOpen());
 HttpConnectionMetrics metrics = conn.getMetrics();
-metrics.getRequestCount();
-metrics.getResponseCount();
-metrics.getReceivedBytesCount();
-metrics.getSentBytesCount();
+System.out.println(metrics.getRequestCount());
+System.out.println(metrics.getResponseCount());
+System.out.println(metrics.getReceivedBytesCount());
+System.out.println(metrics.getSentBytesCount());
 ]]></programlisting>
             <para>
             HTTP connection interfaces, both client and server, send and receive messages in two
             stages. The message head is transmitted first. Depending on properties of the message
-            head it may be followed by a message body. Please note it is very important to always
+            head, a message body may follow it. Please note it is very important to always
             close the underlying content stream in order to signal that the processing of
             the message is complete. HTTP entities that stream out their content directly from the
-            input stream of the underlying connection must ensure the content of the message body
-            is fully consumed for that connection to be potentially re-usable.
+            input stream of the underlying connection must ensure they fully consume the content
+            of the message body for that connection to be potentially re-usable.
             </para>
             <para>
-            Over-simplified process of client side request execution may look like this:
+            Over-simplified process of request execution on the client side may look like this:
             </para>
             <programlisting><![CDATA[
-Socket socket = new Socket();
-// Initialize socket
-HttpParams params = new BasicHttpParams();
-DefaultHttpClientConnection conn = new DefaultHttpClientConnection();
-conn.bind(socket, params);
+Socket socket = <...>
+
+DefaultBHttpClientConnection conn = new DefaultBHttpClientConnection(8 * 1024);
+conn.bind(socket);
 HttpRequest request = new BasicHttpRequest("GET", "/");
 conn.sendRequestHeader(request);
 HttpResponse response = conn.receiveResponseHeader();
@@ -591,19 +588,18 @@ if (entity != null) {
 }
 ]]></programlisting>
             <para>
-            Over-simplified process of server side request handling may look like this:
+            Over-simplified process of request handling on the server side may look like this:
             </para>
             <programlisting><![CDATA[
-Socket socket = new Socket();
-// Initialize socket
-HttpParams params = new BasicHttpParams();
-DefaultHttpServerConnection conn = new DefaultHttpServerConnection();
-conn.bind(socket, params);
+Socket socket = <...>
+
+DefaultBHttpServerConnection conn = new DefaultBHttpServerConnection(8 * 1024);
+conn.bind(socket);
 HttpRequest request = conn.receiveRequestHeader();
 if (request instanceof HttpEntityEnclosingRequest) {
     conn.receiveRequestEntity((HttpEntityEnclosingRequest) request);
     HttpEntity entity = ((HttpEntityEnclosingRequest) request)
-        .getEntity();
+            .getEntity();
     if (entity != null) {
         // Do something useful with the entity and, when done, ensure all
         // content has been consumed, so that the underlying connection
@@ -612,8 +608,8 @@ if (request instanceof HttpEntityEnclosingRequest) {
     }
 }
 HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1,
-    200, "OK");
-response.setEntity(new StringEntity("Got it"));
+        200, "OK") ;
+response.setEntity(new StringEntity("Got it") );
 conn.sendResponseHeader(response);
 conn.sendResponseEntity(response);
 ]]></programlisting>
@@ -633,10 +629,10 @@ conn.sendResponseEntity(response);
             incoming data. They merely inject an appropriate content codec based on the properties
             of the incoming message. The content can be retrieved by reading from the content input
             stream of the enclosed entity using <methodname>HttpEntity#getContent()</methodname>.
-            The incoming data will be decoded automatically, and completely transparently to the data
+            The incoming data will be decoded automatically and completely transparently to the data
             consumer. Likewise, HTTP connections rely on <methodname>
             HttpEntity#writeTo(OutputStream)</methodname> method to generate the content of an
-            outgoing message. If an outgoing messages encloses an entity, the content will be
+            outgoing message. If an outgoing message encloses an entity, the content will be
             encoded automatically based on the properties of the message.
             </para>
         </section>
@@ -663,7 +659,7 @@ conn.sendResponseEntity(response);
                     <para>
                     The end of the content entity is demarcated by closing the underlying
                     connection (end of stream condition). For obvious reasons the identity encoding
-                    can only be used on the server side. Max entity length: unlimited.
+                    can only be used on the server side. Maximum entity length: unlimited.
                     </para>
                     </formalpara>
                 </listitem>
@@ -671,7 +667,7 @@ conn.sendResponseEntity(response);
                     <formalpara>
                     <title>Chunk coding:</title>
                     <para>
-                    The content is sent in small chunks. Max entity length: unlimited.
+                    The content is sent in small chunks. Maximum entity length: unlimited.
                     </para>
                     </formalpara>
                 </listitem>
@@ -769,7 +765,7 @@ conn.sendResponseEntity(response);
             <section>
                 <title><classname>RequestConnControl</classname></title>
                 <para>
-                <classname>RequestConnControl</classname> is responsible for adding the 
+                <classname>RequestConnControl</classname> is responsible for adding the
                 <literal>Connection</literal> header to the outgoing requests, which is essential
                 for managing persistence of <literal>HTTP/1.0</literal> connections. This
                 interceptor is recommended for client side protocol processors.
@@ -811,7 +807,7 @@ conn.sendResponseEntity(response);
             <section>
                 <title><classname>RequestTargetHost</classname></title>
                 <para>
-                <classname>RequestTargetHost</classname> is responsible for adding the 
+                <classname>RequestTargetHost</classname> is responsible for adding the
                 <literal>Host</literal> header. This interceptor is required for client side
                 protocol processors.
                 </para>
@@ -819,7 +815,7 @@ conn.sendResponseEntity(response);
             <section>
                 <title><classname>RequestUserAgent</classname></title>
                 <para>
-                <classname>RequestUserAgent</classname> is responsible for adding the 
+                <classname>RequestUserAgent</classname> is responsible for adding the
                 <literal>User-Agent</literal> header. This interceptor is recommended for client
                 side protocol processors.
                 </para>
@@ -827,7 +823,7 @@ conn.sendResponseEntity(response);
             <section>
                 <title><classname>ResponseServer</classname></title>
                 <para>
-                <classname>ResponseServer</classname> is responsible for adding the 
+                <classname>ResponseServer</classname> is responsible for adding the
                 <literal>Server</literal> header. This interceptor is recommended for server side
                 protocol processors.
                 </para>
@@ -840,25 +836,26 @@ conn.sendResponseEntity(response);
             executing application specific processing logic and to post-process outgoing messages.
             </para>
             <programlisting><![CDATA[
-BasicHttpProcessor httpproc = new BasicHttpProcessor();
-// Required protocol interceptors
-httpproc.addInterceptor(new RequestContent());
-httpproc.addInterceptor(new RequestTargetHost());
-// Recommended protocol interceptors
-httpproc.addInterceptor(new RequestConnControl());
-httpproc.addInterceptor(new RequestUserAgent());
-httpproc.addInterceptor(new RequestExpectContinue());
-
-HttpContext context = new BasicHttpContext();
+HttpProcessor httpproc = HttpProcessorBuilder.create()
+        // Required protocol interceptors
+        .add(new RequestContent())
+        .add(new RequestTargetHost())
+        // Recommended protocol interceptors
+        .add(new RequestConnControl())
+        .add(new RequestUserAgent("MyAgent-HTTP/1.1"))
+        // Optional protocol interceptors
+        .add(new RequestExpectContinue(true))
+        .build();
 
+HttpCoreContext context = HttpCoreContext.create();
 HttpRequest request = new BasicHttpRequest("GET", "/");
 httpproc.process(request, context);
-HttpResponse response = null;
 ]]></programlisting>
             <para>
             Send the request to the target host and get a response.
             </para>
             <programlisting><![CDATA[
+HttpResponse = <...>
 httpproc.process(response, context);
 ]]></programlisting>
             <para>
@@ -880,160 +877,23 @@ httpproc.process(response, context);
             messages.
             </para>
             <programlisting><![CDATA[
-BasicHttpProcessor httpproc = new BasicHttpProcessor();
-httpproc.addInterceptor(new HttpRequestInterceptor() {
-
-    public void process(
-            HttpRequest request,
-            HttpContext context) throws HttpException, IOException {
-        String id = (String) context.getAttribute("session-id");
-        if (id != null) {
-            request.addHeader("Session-ID", id);
-        }
-    }
+HttpProcessor httpproc = HttpProcessorBuilder.create()
+        .add(new HttpRequestInterceptor() {
+            public void process(
+                    HttpRequest request,
+                    HttpContext context) throws HttpException, IOException {
+                String id = (String) context.getAttribute("session-id");
+                if (id != null) {
+                    request.addHeader("Session-ID", id);
+                }
+            }
+        })
+        .build();
 
-
-});
+HttpCoreContext context = HttpCoreContext.create();
 HttpRequest request = new BasicHttpRequest("GET", "/");
 httpproc.process(request, context);
 ]]></programlisting>
-            <para>
-            <interfacename>HttpContext</interfacename> instances can be linked together to form a
-            hierarchy. In the simplest form one context can use content of another context to
-            obtain default values of attributes not present in the local context.
-            </para>
-            <programlisting><![CDATA[
-HttpContext parentContext = new BasicHttpContext();
-parentContext.setAttribute("param1", Integer.valueOf(1));
-parentContext.setAttribute("param2", Integer.valueOf(2));
-
-HttpContext localContext = new BasicHttpContext();
-localContext.setAttribute("param2", Integer.valueOf(0));
-localContext.setAttribute("param3", Integer.valueOf(3));
-HttpContext stack = new DefaultedHttpContext(localContext,
-    parentContext);
-
-System.out.println(stack.getAttribute("param1"));
-System.out.println(stack.getAttribute("param2"));
-System.out.println(stack.getAttribute("param3"));
-System.out.println(stack.getAttribute("param4"));
-]]></programlisting>
-                <para>stdout ></para>
-                <programlisting><![CDATA[
-1
-0
-3
-null
-]]></programlisting>
-        </section>
-    </section>
-    <section>
-        <title>HTTP parameters</title>
-        <para>
-        <interfacename>HttpParams</interfacename> interface represents a collection of immutable
-        values that define a runtime behavior of a component. In many ways <interfacename>HttpParams
-        </interfacename> is similar to <interfacename>HttpContext</interfacename>. The main
-        distinction between the two lies in their use at runtime. Both interfaces represent a
-        collection of objects that are organized as a map of textual names to object values, but
-        serve distinct purposes:
-        </para>
-        <itemizedlist>
-            <listitem>
-                <para>
-                <interfacename>HttpParams</interfacename> is intended to contain simple objects:
-                integers, doubles, strings, collections and objects that remain immutable at
-                runtime. <interfacename>HttpParams</interfacename> is expected to be used in the
-                'write once - read many' mode. <interfacename>HttpContext</interfacename> is
-                intended to contain complex objects that are very likely to mutate in the course of
-                HTTP message processing.
-                </para>
-            </listitem>
-            <listitem>
-                <para>
-                The purpose of <interfacename>HttpParams</interfacename> is to define a behavior of
-                other components. Usually each complex component has its own <interfacename>
-                HttpParams</interfacename> object. The purpose of <interfacename>HttpContext
-                </interfacename> is to represent an execution state of an HTTP process. Usually
-                the same execution context is shared among many collaborating objects.
-                </para>
-            </listitem>
-        </itemizedlist>
-        <para>
-        <interfacename>HttpParams</interfacename>, like <interfacename>HttpContext</interfacename>
-        can be linked together to form a hierarchy. In the simplest form one set of parameters can
-        use content of another one to obtain default values of parameters not present in the local
-        set.
-        </para>
-        <programlisting><![CDATA[
-HttpParams parentParams = new BasicHttpParams();
-parentParams.setParameter(CoreProtocolPNames.PROTOCOL_VERSION,
-    HttpVersion.HTTP_1_0);
-parentParams.setParameter(CoreProtocolPNames.HTTP_CONTENT_CHARSET,
-    "UTF-8");
-
-HttpParams localParams = new BasicHttpParams();
-localParams.setParameter(CoreProtocolPNames.PROTOCOL_VERSION,
-    HttpVersion.HTTP_1_1);
-localParams.setParameter(CoreProtocolPNames.USE_EXPECT_CONTINUE,
-    Boolean.FALSE);
-HttpParams stack = new DefaultedHttpParams(localParams,
-    parentParams);
-
-System.out.println(stack.getParameter(
-    CoreProtocolPNames.PROTOCOL_VERSION));
-System.out.println(stack.getParameter(
-    CoreProtocolPNames.HTTP_CONTENT_CHARSET));
-System.out.println(stack.getParameter(
-    CoreProtocolPNames.USE_EXPECT_CONTINUE));
-System.out.println(stack.getParameter(
-    CoreProtocolPNames.USER_AGENT));
-]]></programlisting>
-        <para>stdout ></para>
-        <programlisting><![CDATA[
-HTTP/1.1
-UTF-8
-false
-null
-]]></programlisting>
-        <para>
-        Please note the <classname>BasicHttpParams</classname> class does not synchronize access to
-        its internal structures and therefore may not be thread-safe.
-        </para>
-        <section>
-            <title>HTTP parameter beans</title>
-            <para>
-            <interfacename>HttpParams</interfacename> interface allows for a great deal of
-            flexibility in handling configuration of components. Most importantly, new parameters
-            can be introduced without affecting binary compatibility with older versions. However,
-            <interfacename>HttpParams</interfacename> also has a certain disadvantage compared to
-            regular Java beans: <interfacename>HttpParams</interfacename> cannot be assembled using
-            a DI framework. To mitigate the limitation, HttpCore includes a number of bean classes
-            that can be used in order to initialize <interfacename>HttpParams</interfacename> objects
-            using standard Java bean conventions.
-            </para>
-            <programlisting><![CDATA[
-HttpParams params = new BasicHttpParams();
-HttpProtocolParamBean paramsBean = new HttpProtocolParamBean(params);
-paramsBean.setVersion(HttpVersion.HTTP_1_1);
-paramsBean.setContentCharset("UTF-8");
-paramsBean.setUseExpectContinue(true);
-
-System.out.println(params.getParameter(
-    CoreProtocolPNames.PROTOCOL_VERSION));
-System.out.println(params.getParameter(
-    CoreProtocolPNames.HTTP_CONTENT_CHARSET));
-System.out.println(params.getParameter(
-    CoreProtocolPNames.USE_EXPECT_CONTINUE));
-System.out.println(params.getParameter(
-    CoreProtocolPNames.USER_AGENT));
-]]></programlisting>
-        <para>stdout ></para>
-        <programlisting><![CDATA[
-HTTP/1.1
-UTF-8
-false
-null
-]]></programlisting>
         </section>
     </section>
     <section>
@@ -1053,16 +913,13 @@ null
             application specific content generation and processing.
             </para>
             <programlisting><![CDATA[
-HttpParams params;
-// Initialize HTTP parameters
-HttpProcessor httpproc;
-// Initialize HTTP processor
-
-HttpService httpService = new HttpService(
-        httpproc,
-        new DefaultConnectionReuseStrategy(),
-        new DefaultHttpResponseFactory());
-httpService.setParams(params);
+HttpProcessor httpproc = HttpProcessorBuilder.create()
+        .add(new ResponseDate())
+        .add(new ResponseServer("MyServer-HTTP/1.1"))
+        .add(new ResponseContent())
+        .add(new ResponseConnControl())
+        .build();
+HttpService httpService = new HttpService(httpproc, null);
 ]]></programlisting>
             <section>
                 <title>HTTP request handlers</title>
@@ -1083,9 +940,9 @@ HttpRequestHandler myRequestHandler = new HttpRequestHandler() {
             HttpResponse response,
             HttpContext context) throws HttpException, IOException {
         response.setStatusCode(HttpStatus.SC_OK);
-        response.addHeader("Content-Type", "text/plain");
         response.setEntity(
-            new StringEntity("some important message"));
+                new StringEntity("some important message",
+                        ContentType.TEXT_PLAIN));
     }
 
 };
@@ -1103,17 +960,17 @@ HttpRequestHandler myRequestHandler = new HttpRequestHandler() {
                 <literal>*<uri></literal>.
                 </para>
                 <programlisting><![CDATA[
-HttpService httpService;
-// Initialize HTTP service
+HttpProcessor httpproc = <...>
 
-HttpRequestHandlerRegistry handlerResolver =
-    new HttpRequestHandlerRegistry();
-handlerReqistry.register("/service/*", myRequestHandler1);
-handlerReqistry.register("*.do", myRequestHandler2);
-handlerReqistry.register("*", myRequestHandler3);
+HttpRequestHandler myRequestHandler1 = <...>
+HttpRequestHandler myRequestHandler2 = <...>
+HttpRequestHandler myRequestHandler3 = <...>
 
-// Inject handler resolver
-httpService.setHandlerResolver(handlerResolver);
+UriHttpRequestHandlerMapper handlerMapper = new UriHttpRequestHandlerMapper();
+handlerMapper.register("/service/*", myRequestHandler1);
+handlerMapper.register("*.do", myRequestHandler2);
+handlerMapper.register("*", myRequestHandler3);
+HttpService httpService = new HttpService(httpproc, handlerMapper);
 ]]></programlisting>
                 <para>
                 Users are encouraged to provide more sophisticated implementations of
@@ -1135,12 +992,9 @@ httpService.setHandlerResolver(handlerResolver);
                 by the <classname>HttpService</classname> are thread-safe.
                 </para>
                 <programlisting><![CDATA[
-HttpService httpService;
-// Initialize HTTP service
-HttpServerConnection conn;
-// Initialize connection
-HttpContext context;
-// Initialize HTTP context
+HttpService httpService = <...>
+HttpServerConnection conn = <...>
+HttpContext context = <...>
 
 boolean active = true;
 try {
@@ -1167,23 +1021,21 @@ try {
             response has been received.
             </para>
             <programlisting><![CDATA[
-HttpClientConnection conn;
-// Create connection
-HttpParams params;
-// Initialize HTTP parameters
-HttpProcessor httpproc;
-// Initialize HTTP processor
-HttpContext context;
-// Initialize HTTP context
+HttpClientConnection conn = <...>
 
+HttpProcessor httpproc = HttpProcessorBuilder.create()
+        .add(new RequestContent())
+        .add(new RequestTargetHost())
+        .add(new RequestConnControl())
+        .add(new RequestUserAgent("MyClient/1.1"))
+        .add(new RequestExpectContinue(true))
+        .build();
 HttpRequestExecutor httpexecutor = new HttpRequestExecutor();
 
-BasicHttpRequest request = new BasicHttpRequest("GET", "/");
-request.setParams(params);
+HttpRequest request = new BasicHttpRequest("GET", "/");
+HttpCoreContext context = HttpCoreContext.create();
 httpexecutor.preProcess(request, httpproc, context);
-HttpResponse response = httpexecutor.execute(
-    request, conn, context);
-response.setParams(params);
+HttpResponse response = httpexecutor.execute(request, conn, context);
 httpexecutor.postProcess(response, httpproc, context);
 
 HttpEntity entity = response.getEntity();
@@ -1214,4 +1066,94 @@ EntityUtils.consume(entity);
             </para>
         </section>
     </section>
+    <section>
+        <title>Connection pools</title>
+        <para>
+        Efficient client-side HTTP transports often requires effective re-use of persistent
+        connections. HttpCore facilitates the process of connection re-use by providing support
+        for managing pools of persistent HTTP connections. Connection pool implementations are
+        thread-safe and can be used concurrently by multiple consumers.
+        </para>
+        <para>
+        By default the pool allows only 20 concurrent connections in total and two concurrent
+        connections per a unique route. The two connection limit is due to the requirements of the
+        HTTP specification. However, in practical terms this can often be too restrictive. One can
+        change the pool configuration at runtime to allow for more concurrent connections depending
+        on a particular application context.
+        </para>
+        <programlisting><![CDATA[
+HttpHost target = new HttpHost("localhost");
+BasicConnPool connpool = new BasicConnPool();
+connpool.setMaxTotal(200);
+connpool.setDefaultMaxPerRoute(10);
+connpool.setMaxPerRoute(target, 20);
+Future<BasicPoolEntry> future = connpool.lease(target, null);
+BasicPoolEntry poolEntry = future.get();
+HttpClientConnection conn = poolEntry.getConnection();
+]]></programlisting>
+        <para>
+        Please note that the connection pool has no way of knowing whether or not a leased
+        connection is still being used. It is the responsibility of the connection pool user
+        to ensure that the connection is released back to the pool once it is not longer needed,
+        even if the connection is not reusable.
+        </para>
+        <programlisting><![CDATA[
+BasicConnPool connpool = <...>
+Future<BasicPoolEntry> future = connpool.lease(target, null);
+BasicPoolEntry poolEntry = future.get();
+try {
+    HttpClientConnection conn = poolEntry.getConnection();
+} finally {
+    connpool.release(poolEntry, conn.isOpen());
+}
+]]></programlisting>
+        <para>
+        The state of the connection pool can be interrogated at runtime.
+        </para>
+        <programlisting><![CDATA[
+HttpHost target = new HttpHost("localhost");
+BasicConnPool connpool = <...>
+PoolStats totalStats = connpool.getTotalStats();
+System.out.println("total available: " + totalStats.getAvailable());
+System.out.println("total leased: " + totalStats.getLeased());
+System.out.println("total pending: " + totalStats.getPending());
+PoolStats targetStats = connpool.getStats(target);
+System.out.println("target available: " + targetStats.getAvailable());
+System.out.println("target leased: " + targetStats.getLeased());
+System.out.println("target pending: " + targetStats.getPending());
+]]></programlisting>
+        <para>
+        Please note that connection pools do not pro-actively evict expired connections. Even though
+        expired connection cannot be leased to the requester, the pool may accumulate stale
+        connections over time especially after a period of inactivity. It is generally advisable
+        to force eviction of expired and idle connections from the pool after an extensive period
+        of inactivity.
+        </para>
+        <programlisting><![CDATA[
+BasicConnPool connpool = <...>
+connpool.closeExpired();
+connpool.closeIdle(1, TimeUnit.MINUTES);
+]]></programlisting>
+    </section>
+    <section>
+        <title>TLS/SSL support</title>
+        <para>
+        Blocking connections can be bound to any arbitrary socket. This makes SSL support quite
+        straight-forward. Any <classname>SSLSocket</classname> instance can be bound to a blocking
+        connection in order to make all messages transmitted over than connection secured by
+        TLS/SSL.
+        </para>
+        <programlisting><![CDATA[
+SSLContext sslcontext = SSLContext.getInstance("Default");
+sslcontext.init(null, null, null);
+SocketFactory sf = sslcontext.getSocketFactory();
+SSLSocket socket = (SSLSocket) sf.createSocket("somehost", 443);
+socket.setEnabledCipherSuites(new String[] {
+        "TLS_RSA_WITH_AES_256_CBC_SHA",
+        "TLS_DHE_RSA_WITH_AES_256_CBC_SHA",
+        "TLS_DHE_DSS_WITH_AES_256_CBC_SHA" });
+DefaultBHttpClientConnection conn = new DefaultBHttpClientConnection(8 * 1204);
+conn.bind(socket);
+]]></programlisting>
+    </section>
 </chapter>
diff --git a/src/docbkx/nio-ext.xml b/src/docbkx/nio-ext.xml
index 4e62655..d8b7cea 100644
--- a/src/docbkx/nio-ext.xml
+++ b/src/docbkx/nio-ext.xml
@@ -23,34 +23,9 @@
 
 -->
 <chapter id="nio">
-    <title>NIO extensions</title>
+    <title>Asynchronous I/O based on NIO</title>
     <section>
-        <title>Benefits and shortcomings of the non-blocking I/O model</title>
-        <para>
-        Contrary to the popular belief, the performance of NIO in terms of raw data throughput is
-        significantly lower than that of blocking I/O. NIO does not necessarily fit all use cases
-        and should be used only where appropriate:
-        </para>
-        <itemizedlist>
-            <listitem>
-                <para>
-                handling of thousands of connections, a significant number of which can be idle.
-                </para>
-            </listitem>
-            <listitem>
-                <para>
-                handling high latency connections.
-                </para>
-            </listitem>
-            <listitem>
-                <para>
-                request / response handling needs to be decoupled.
-                </para>
-            </listitem>
-        </itemizedlist>
-    </section>
-    <section>
-        <title>Differences from other NIO frameworks</title>
+        <title>Differences from other I/O frameworks</title>
         <para>
         Solves similar problems as other frameworks, but has certain distinct features:
         </para>
@@ -91,10 +66,8 @@
         thread per CPU core.
         </para>
         <programlisting><![CDATA[
-HttpParams params = new BasicHttpParams();
-int workerCount = 2;
-IOReactor ioreactor = new DefaultConnectingIOReactor(workerCount,
-    params);
+IOReactorConfig config = IOReactorConfig.DEFAULT;
+IOReactor ioreactor = new DefaultConnectingIOReactor(config);
 ]]></programlisting>
         <section>
             <title>I/O dispatchers</title>
@@ -108,10 +81,9 @@ IOReactor ioreactor = new DefaultConnectingIOReactor(workerCount,
             events.
             </para>
             <programlisting><![CDATA[
-HttpParams params = new BasicHttpParams();
-IOReactor ioreactor = new DefaultConnectingIOReactor(2, params);
+IOReactor ioreactor = new DefaultConnectingIOReactor();
 
-IOEventDispatch eventDispatch = new MyIOEventDispatch();
+IOEventDispatch eventDispatch = <...>
 ioreactor.execute(eventDispatch);
 ]]></programlisting>
             <para>
@@ -171,6 +143,7 @@ ioreactor.execute(eventDispatch);
             remaining sessions.
             </para>
             <programlisting><![CDATA[
+IOReactor ioreactor = <...>
 long gracePeriod = 3000L; // milliseconds
 ioreactor.shutdown(gracePeriod);
 ]]></programlisting>
@@ -191,7 +164,7 @@ ioreactor.shutdown(gracePeriod);
             to the session.
             </para>
             <programlisting><![CDATA[
-IOSession iosession;
+IOSession iosession = <...>
 ReadableByteChannel ch = (ReadableByteChannel) iosession.channel();
 ByteBuffer dst = ByteBuffer.allocate(2048);
 ch.read(dst);
@@ -205,9 +178,11 @@ ch.read(dst);
             be stored within the session itself.
             </para>
             <programlisting><![CDATA[
-IOSession iosession;
-Object someState;
+IOSession iosession = <...>
+Object someState = <...>
 iosession.setAttribute("state", someState);
+...
+IOSession iosession = <...>
 Object currentState = iosession.getAttribute("state");
 ]]></programlisting>
             <para>
@@ -222,7 +197,7 @@ Object currentState = iosession.getAttribute("state");
             session by setting its event mask.
             </para>
             <programlisting><![CDATA[
-IOSession iosession;
+IOSession iosession = <...>
 iosession.setEventMask(SelectionKey.OP_READ | SelectionKey.OP_WRITE);
 ]]></programlisting>
             <para>
@@ -230,6 +205,7 @@ iosession.setEventMask(SelectionKey.OP_READ | SelectionKey.OP_WRITE);
             individually.
             </para>
             <programlisting><![CDATA[
+IOSession iosession = <...>
 iosession.setEvent(SelectionKey.OP_READ);
 iosession.clearEvent(SelectionKey.OP_READ);
 ]]></programlisting>
@@ -253,8 +229,8 @@ iosession.clearEvent(SelectionKey.OP_READ);
             SessionBufferStatus</interfacename> interface.
             </para>
             <programlisting><![CDATA[
-IOSession iosession;
-SessionBufferStatus myBufferStatus = new MySessionBufferStatus();
+IOSession iosession = <...>
+SessionBufferStatus myBufferStatus = <...>
 iosession.setBufferStatus(myBufferStatus);
 iosession.hasBufferedInput();
 iosession.hasBufferedOutput();
@@ -278,12 +254,10 @@ iosession.hasBufferedOutput();
             listening for incoming connections on one or several ports.
             </para>
             <programlisting><![CDATA[
-ListeningIOReactor ioreactor;
-
-ListenerEndpoint ep1 = ioreactor.listen(new InetSocketAddress(8081));
+ListeningIOReactor ioreactor = <...>
+ListenerEndpoint ep1 = ioreactor.listen(new InetSocketAddress(8081) );
 ListenerEndpoint ep2 = ioreactor.listen(new InetSocketAddress(8082));
 ListenerEndpoint ep3 = ioreactor.listen(new InetSocketAddress(8083));
-
 // Wait until all endpoints are up
 ep1.waitFor();
 ep2.waitFor();
@@ -299,7 +273,7 @@ ep3.waitFor();
             endpoint at runtime, and close it if desired.
             </para>
             <programlisting><![CDATA[
-ListeningIOReactor ioreactor;
+ListeningIOReactor ioreactor = <...>
 
 Set<ListenerEndpoint> eps = ioreactor.getEndpoints();
 for (ListenerEndpoint ep: eps) {
@@ -323,7 +297,7 @@ for (ListenerEndpoint ep: eps) {
             establishing connections with remote hosts.
             </para>
             <programlisting><![CDATA[
-ConnectingIOReactor ioreactor;
+ConnectingIOReactor ioreactor = <...>
 
 SessionRequest sessionRequest = ioreactor.connect(
         new InetSocketAddress("www.google.com", 80),
@@ -367,7 +341,7 @@ if (!sessionRequest.isCompleted()) {
             local address.
             </para>
             <programlisting><![CDATA[
-ConnectingIOReactor ioreactor;
+ConnectingIOReactor ioreactor = <...>
 
 SessionRequest sessionRequest = ioreactor.connect(
         new InetSocketAddress("www.google.com", 80),
@@ -396,7 +370,7 @@ HttpHost virtualHost = (HttpHost) iosession.getAttribute(
             as request completion, cancellation, failure or timeout.
             </para>
             <programlisting><![CDATA[
-ConnectingIOReactor ioreactor;
+ConnectingIOReactor ioreactor = <...>
 
 SessionRequest sessionRequest = ioreactor.connect(
         new InetSocketAddress("www.google.com", 80), null, null,
@@ -422,6 +396,31 @@ SessionRequest sessionRequest = ioreactor.connect(
         });
 ]]></programlisting>
         </section>
+    </section>
+    <section>
+        <title>I/O reactor configuration</title>
+        <para>
+        I/O reactors by default use system dependent configuration which in most cases should be
+        sensible enough.
+        </para>
+        <programlisting><![CDATA[
+IOReactorConfig config = IOReactorConfig.DEFAULT;
+IOReactor ioreactor = new DefaultListeningIOReactor(config);
+]]></programlisting>
+        <para>
+        However in some cases custom settings may be necessary, for instance, in order to alter
+        default socket properties and timeout values. One should rarely need to change other
+        parameters.
+        </para>
+        <programlisting><![CDATA[
+IOReactorConfig config = IOReactorConfig.custom()
+        .setTcpNoDelay(true)
+        .setSoTimeout(5000)
+        .setSoReuseAddress(true)
+        .setConnectTimeout(5000)
+        .build();
+IOReactor ioreactor = new DefaultListeningIOReactor(config);
+]]></programlisting>
         <section>
             <title>Queuing of I/O interest set operations</title>
             <para>
@@ -435,9 +434,9 @@ SessionRequest sessionRequest = ioreactor.connect(
             thread only when the I/O selector is not engaged in a select operation.
             </para>
             <programlisting><![CDATA[
-HttpParams params = new BasicHttpParams();
-NIOReactorParams.setInterestOpsQueueing(params, true);
-ListeningIOReactor ioreactor = new DefaultListeningIOReactor(2, params);
+IOReactorConfig config = IOReactorConfig.custom()
+        .setInterestOpQueued(true)
+        .build();
 ]]></programlisting>
         </section>
     </section>
@@ -459,7 +458,7 @@ ListeningIOReactor ioreactor = new DefaultListeningIOReactor(2, params);
         IOReactorExceptionHandler</interfacename> interface.
         </para>
         <programlisting><![CDATA[
-DefaultConnectingIOReactor ioreactor;
+DefaultConnectingIOReactor ioreactor = <...>
 
 ioreactor.setExceptionHandler(new IOReactorExceptionHandler() {
 
@@ -502,7 +501,7 @@ ioreactor.setExceptionHandler(new IOReactorExceptionHandler() {
             I/O reactor.
             </para>
             <programlisting><![CDATA[
-DefaultConnectingIOReactor ioreactor;
+DefaultConnectingIOReactor ioreactor = <...>
 
 // Give it 5 sec grace period
 ioreactor.shutdown(5000);
@@ -532,10 +531,8 @@ for (ExceptionEvent event: events) {
             </interfacename> instance is thread-safe and can be manipulated from multiple threads.
             </para>
             <programlisting><![CDATA[
-// Get non-blocking HTTP connection
-DefaultNHttpClientConnection conn;
-// State
-Object myStateObject;
+DefaultNHttpClientConnection conn = <...>
+Object myStateObject = <...>
 
 HttpContext context = conn.getContext();
 context.setAttribute("state", myStateObject);
@@ -549,17 +546,17 @@ context.setAttribute("state", myStateObject);
             be null if there is no incoming or outgoing message currently being transferred.
             </para>
             <programlisting><![CDATA[
-NHttpConnection conn;
+NHttpConnection conn = <...>
 
 HttpRequest request = conn.getHttpRequest();
 if (request != null) {
     System.out.println("Transferring request: " +
-        request.getRequestLine());
+            request.getRequestLine());
 }
 HttpResponse response = conn.getHttpResponse();
 if (response != null) {
     System.out.println("Transferring response: " +
-        response.getStatusLine());
+            response.getStatusLine());
 }
 ]]></programlisting>
             <para>
@@ -574,15 +571,11 @@ if (response != null) {
             Over-simplified process of submitting a request on the client side may look like this:
             </para>
             <programlisting><![CDATA[
-// Obtain HTTP connection
-NHttpClientConnection conn;
-
+NHttpClientConnection conn = <...>
 // Obtain execution context
 HttpContext context = conn.getContext();
-
 // Obtain processing state
 Object state = context.getAttribute("state");
-
 // Generate a request based on the state information
 HttpRequest request = new BasicHttpRequest("GET", "/");
 
@@ -593,12 +586,9 @@ System.out.println(conn.isRequestSubmitted());
             Over-simplified process of submitting a response on the server side may look like this:
             </para>
             <programlisting><![CDATA[
-// Obtain HTTP connection
-NHttpServerConnection conn;
-
+NHttpServerConnection conn = <...>
 // Obtain execution context
 HttpContext context = conn.getContext();
-
 // Obtain processing state
 Object state = context.getAttribute("state");
 
@@ -687,8 +677,7 @@ System.out.println(conn.isResponseSubmitted());
             transferred.
             </para>
             <programlisting><![CDATA[
-//Obtain content decoder
-ContentDecoder decoder;
+ContentDecoder decoder = <...>
 //Read data in
 ByteBuffer dst = ByteBuffer.allocate(2048);
 decoder.read(dst);
@@ -703,8 +692,7 @@ if (decoder.isCompleted()) {
             marked as fully transferred.
             </para>
             <programlisting><![CDATA[
-// Obtain content encoder
-ContentEncoder encoder;
+ContentEncoder encoder = <...>
 // Prepare output data
 ByteBuffer src = ByteBuffer.allocate(2048);
 // Write data out
@@ -721,8 +709,7 @@ encoder.complete();
             HttpEntity#writeTo()</methodname> methods of the enclosed entities.
             </para>
             <programlisting><![CDATA[
-// Obtain HTTP connection
-NHttpServerConnection conn;
+NHttpServerConnection conn  = <...>
 
 HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1,
     HttpStatus.SC_OK, "OK");
@@ -743,8 +730,7 @@ conn.submitResponse(response);
             of the incoming entity such as content length.
             </para>
             <programlisting><![CDATA[
-// Obtain HTTP connection
-NHttpClientConnection conn;
+NHttpClientConnection conn = <...>
 
 HttpResponse response = conn.getHttpResponse();
 HttpEntity entity = response.getEntity();
@@ -812,8 +798,7 @@ if (entity != null) {
             file bypassing an intermediate <classname>java.nio.ByteBuffer</classname>.
             </para>
             <programlisting><![CDATA[
-//Obtain content decoder
-ContentDecoder decoder;
+ContentDecoder decoder = <...>
 //Prepare file channel
 FileChannel dst;
 //Make use of direct file I/O if possible
@@ -833,8 +818,7 @@ if (decoder instanceof FileContentDecoder) {
             from a file bypassing an intermediate <classname>java.nio.ByteBuffer</classname>.
             </para>
             <programlisting><![CDATA[
-// Obtain content encoder
-ContentEncoder encoder;
+ContentEncoder encoder = <...>
 // Prepare file channel
 FileChannel src;
 // Make use of direct file I/O if possible
@@ -887,15 +871,15 @@ if (encoder instanceof FileContentEncoder) {
                 Triggered when the underlying channel is ready for reading a new portion of
                 the request entity through the corresponding content decoder. If the content
                 consumer is unable to process the incoming content, input event notifications can
-                temporarily suspended using <interfacename>IOControl</interfacename> interface 
+                temporarily suspended using <interfacename>IOControl</interfacename> interface
                 (super interface of <interfacename>NHttpServerConnection</interfacename>).
                 </para>
                 <para>
-                Please note that the <interfacename>NHttpServerConnection</interfacename> and 
-                <interfacename>ContentDecoder</interfacename> objects are not thread-safe and 
+                Please note that the <interfacename>NHttpServerConnection</interfacename> and
+                <interfacename>ContentDecoder</interfacename> objects are not thread-safe and
                 should only be used within the context of this method call. The <interfacename>
-                IOControl</interfacename> object can be shared and used on other thread to resume 
-                input event notifications when the handler is capable of processing more content.  
+                IOControl</interfacename> object can be shared and used on other thread to resume
+                input event notifications when the handler is capable of processing more content.
                 </para>
                 </formalpara>
             </listitem>
@@ -919,11 +903,11 @@ if (encoder instanceof FileContentEncoder) {
                 (super interface of <interfacename>NHttpServerConnection</interfacename>).
                 </para>
                 <para>
-                Please note that the <interfacename>NHttpServerConnection</interfacename> and 
-                <interfacename>ContentEncoder</interfacename> objects are not thread-safe and 
+                Please note that the <interfacename>NHttpServerConnection</interfacename> and
+                <interfacename>ContentEncoder</interfacename> objects are not thread-safe and
                 should only be used within the context of this method call. The <interfacename>
-                IOControl</interfacename> object can be shared and used on other thread to resume 
-                output event notifications when more content is made available.  
+                IOControl</interfacename> object can be shared and used on other thread to resume
+                output event notifications when more content is made available.
                 </para>
                 </formalpara>
             </listitem>
@@ -963,8 +947,8 @@ if (encoder instanceof FileContentEncoder) {
                 <formalpara>
                 <title><methodname>connected</methodname>:</title>
                 <para>
-                Triggered when a new outgoing connection has been created. The attachment object 
-                passed as a parameter to this event is an arbitrary object that was attached to 
+                Triggered when a new outgoing connection has been created. The attachment object
+                passed as a parameter to this event is an arbitrary object that was attached to
                 the session request.
                 </para>
                 </formalpara>
@@ -973,7 +957,7 @@ if (encoder instanceof FileContentEncoder) {
                 <formalpara>
                 <title><methodname>requestReady</methodname>:</title>
                 <para>
-                Triggered when the connection is ready to accept new HTTP request. The protocol 
+                Triggered when the connection is ready to accept new HTTP request. The protocol
                 handler does not have to submit a request if it is not ready.
                 </para>
                 </formalpara>
@@ -983,17 +967,17 @@ if (encoder instanceof FileContentEncoder) {
                 <title><methodname>outputReady</methodname>:</title>
                 <para>
                 Triggered when the underlying channel is ready for writing a next portion of the
-                request entity through the corresponding content encoder. If the content producer 
-                is unable to generate the outgoing content, output event notifications can be 
+                request entity through the corresponding content encoder. If the content producer
+                is unable to generate the outgoing content, output event notifications can be
                 temporarily suspended using <interfacename>IOControl</interfacename> interface
                 (super interface of <interfacename>NHttpClientConnection</interfacename>).
                 </para>
                 <para>
-                Please note that the <interfacename>NHttpClientConnection</interfacename> and 
-                <interfacename>ContentEncoder</interfacename> objects are not thread-safe and 
+                Please note that the <interfacename>NHttpClientConnection</interfacename> and
+                <interfacename>ContentEncoder</interfacename> objects are not thread-safe and
                 should only be used within the context of this method call. The <interfacename>
-                IOControl</interfacename> object can be shared and used on other thread to resume 
-                output event notifications when more content is made available.  
+                IOControl</interfacename> object can be shared and used on other thread to resume
+                output event notifications when more content is made available.
                 </para>
                 </formalpara>
             </listitem>
@@ -1013,17 +997,17 @@ if (encoder instanceof FileContentEncoder) {
                 <title><methodname>inputReady</methodname>:</title>
                 <para>
                 Triggered when the underlying channel is ready for reading a new portion of the
-                response entity through the corresponding content decoder. If the content consumer 
-                is unable to process the incoming content, input event notifications can be 
-                temporarily suspended using <interfacename>IOControl</interfacename> interface 
+                response entity through the corresponding content decoder. If the content consumer
+                is unable to process the incoming content, input event notifications can be
+                temporarily suspended using <interfacename>IOControl</interfacename> interface
                 (super interface of <interfacename>NHttpClientConnection</interfacename>).
                 </para>
                 <para>
-                Please note that the <interfacename>NHttpClientConnection</interfacename> and 
-                <interfacename>ContentDecoder</interfacename> objects are not thread-safe and 
+                Please note that the <interfacename>NHttpClientConnection</interfacename> and
+                <interfacename>ContentDecoder</interfacename> objects are not thread-safe and
                 should only be used within the context of this method call. The <interfacename>
-                IOControl</interfacename> object can be shared and used on other thread to resume 
-                input event notifications when the handler is capable of processing more content.  
+                IOControl</interfacename> object can be shared and used on other thread to resume
+                input event notifications when the handler is capable of processing more content.
                 </para>
                 </formalpara>
             </listitem>
@@ -1084,10 +1068,10 @@ if (encoder instanceof FileContentEncoder) {
                 the entity to be incorrectly delimited.
                 </para>
                 <para>
-                Please note that the <interfacename>ContentEncoder</interfacename> object is 
-                not thread-safe and should only be used within the context of this method call. 
-                The <interfacename>IOControl</interfacename> object can be shared and used on other 
-                thread resume output event notifications when more content is made available.  
+                Please note that the <interfacename>ContentEncoder</interfacename> object is
+                not thread-safe and should only be used within the context of this method call.
+                The <interfacename>IOControl</interfacename> object can be shared and used on other
+                thread resume output event notifications when more content is made available.
                 </para>
                 </formalpara>
             </listitem>
@@ -1142,28 +1126,24 @@ if (encoder instanceof FileContentEncoder) {
             <section id="bytearray-n-entity">
                 <title><classname>NByteArrayEntity</classname></title>
                 <para>
-                This is a simple self contained repeatable entity, which receives its content from
+                This is a simple self-contained repeatable entity, which receives its content from
                 a given byte array. This byte array is supplied to the constructor.
                 </para>
                 <programlisting><![CDATA[
-String myData = "Hello world on the other side!!";
-NByteArrayEntity entity = new NByteArrayEntity(myData.getBytes());
-    ]]></programlisting>
+NByteArrayEntity entity = new NByteArrayEntity(new byte[] {1, 2, 3});
+]]></programlisting>
             </section>
             <section id="string-n-entity">
                 <title><classname>NStringEntity</classname></title>
                 <para>
-                It's is a simple, self contained, repeatable entity that retrieves its data from a
+                It's is a simple, self-contained, repeatable entity that retrieves its data from a
                 <classname>java.lang.String</classname> object. It has 2 constructors, one simply
                 constructs with a given string where the other also takes a character encoding for
                 the data in the <classname>java.lang.String</classname>.
                 </para>
                 <programlisting><![CDATA[
-String myData = "Hello world on the other side!!";
-// construct without a character encoding
-NStringEntity myEntity1 = new NStringEntity(myData);
-// alternatively construct with an encoding
-NStringEntity myEntity2 = new NStringEntity(myData, "UTF-8");
+NStringEntity myEntity = new NStringEntity("important message",
+        Consts.UTF_8);
     ]]></programlisting>
             </section>
             <section id="file-n-entity">
@@ -1176,7 +1156,7 @@ NStringEntity myEntity2 = new NStringEntity(myData, "UTF-8");
                 </para>
                 <programlisting><![CDATA[
 File staticFile = new File("/path/to/myapp.jar");
-NHttpEntity entity = new NFileEntity(staticFile,
+NFileEntity entity = new NFileEntity(staticFile,
     ContentType.create("application/java-archive", null));
     ]]></programlisting>
                 <para>
@@ -1216,23 +1196,18 @@ NHttpEntity entity = new NFileEntity(staticFile,
             application specific content generation and processing.
             </para>
             <programlisting><![CDATA[
-HttpParams params;
-// Initialize HTTP parameters
-HttpProcessor httpproc;
-// Initialize HTTP processor
-HttpAsyncRequestHandlerResolver handlerResolver;
-// Initialize HTTP request resolver
-HttpAsyncService protocolHandler = new HttpAsyncService(
-        httpproc,
-        new DefaultConnectionReuseStrategy(),
-        new DefaultHttpResponseFactory(),
-        handlerResolver,
-        null,
-        params);
-NHttpConnectionFactory<DefaultNHttpServerConnection> connFactory;
-// Initialize HTTP connection factory
+HttpProcessor httpproc = HttpProcessorBuilder.create()
+        .add(new ResponseDate())
+        .add(new ResponseServer("MyServer-HTTP/1.1"))
+        .add(new ResponseContent())
+        .add(new ResponseConnControl())
+        .build();
+HttpAsyncService protocolHandler = new HttpAsyncService(httpproc, null);
 IOEventDispatch ioEventDispatch = new DefaultHttpServerIODispatch(
-    protocolHandler, connFactory);
+        protocolHandler,
+        new DefaultNHttpServerConnectionFactory(ConnectionConfig.DEFAULT));
+ListeningIOReactor ioreactor = new DefaultListeningIOReactor();
+ioreactor.execute(ioEventDispatch);
 ]]></programlisting>
             <section>
                 <title>Non-blocking HTTP request handlers</title>
@@ -1262,7 +1237,7 @@ HttpAsyncRequestHandler<HttpRequest> rh = new HttpAsyncRequestHandler<HttpReques
         HttpResponse response = httpexchange.getResponse();
         response.setStatusCode(HttpStatus.SC_OK);
         NFileEntity body = new NFileEntity(new File("static.html"),
-                ContentType.create("text/html", null));
+                ContentType.create("text/html", Consts.UTF_8));
         response.setEntity(body);
         httpexchange.submitResponse(new BasicAsyncResponseProducer(response));
     }
@@ -1377,7 +1352,7 @@ HttpAsyncRequestHandler<HttpRequest> rh = new HttpAsyncRequestHandler<HttpReques
                 HttpResponse response = httpexchange.getResponse();
                 response.setStatusCode(HttpStatus.SC_OK);
                 NFileEntity body = new NFileEntity(new File("static.html"),
-                        ContentType.create("text/html", null));
+                        ContentType.create("text/html", Consts.UTF_8));
                 response.setEntity(body);
                 httpexchange.submitResponse(new BasicAsyncResponseProducer(response));
             }
@@ -1430,10 +1405,10 @@ HttpAsyncRequestHandler<HttpRequest> rh = new HttpAsyncRequestHandler<HttpReques
                         has been fully consumed.
                         </para>
                         <para>
-                        Please note that the <interfacename>ContentDecoder</interfacename> object 
-                        is not thread-safe and should only be used within the context of this 
-                        method call. The <interfacename>IOControl</interfacename> object can be 
-                        shared and used on other thread to resume input event notifications 
+                        Please note that the <interfacename>ContentDecoder</interfacename> object
+                        is not thread-safe and should only be used within the context of this
+                        method call. The <interfacename>IOControl</interfacename> object can be
+                        shared and used on other thread to resume input event notifications
                         when the consumer is capable of processing more content.
                         </para>
                         <para>
@@ -1545,11 +1520,11 @@ HttpAsyncRequestHandler<HttpRequest> rh = new HttpAsyncRequestHandler<HttpReques
                         the entity to be incorrectly delimited.
                         </para>
                         <para>
-                        Please note that the <interfacename>ContentEncoder</interfacename> object 
-                        is not thread-safe and should only be used within the context of this 
-                        method call. The <interfacename>IOControl</interfacename> object can be 
-                        shared and used on other thread resume output event notifications when 
-                        more content is made available.  
+                        Please note that the <interfacename>ContentEncoder</interfacename> object
+                        is not thread-safe and should only be used within the context of this
+                        method call. The <interfacename>IOControl</interfacename> object can be
+                        shared and used on other thread resume output event notifications when
+                        more content is made available.
                         </para>
                         <para>
                         This event is invoked only for if the outgoing response message has
@@ -1610,8 +1585,11 @@ HttpAsyncRequestHandler<HttpRequest> rh = new HttpAsyncRequestHandler<HttpReques
                 <literal>*<uri></literal>.
                 </para>
                 <programlisting><![CDATA[
-HttpAsyncRequestHandlerRegistry handlerReqistry =
-    new HttpAsyncRequestHandlerRegistry();
+HttpAsyncRequestHandler<?> myRequestHandler1 = <...>
+HttpAsyncRequestHandler<?> myRequestHandler2 = <...>
+HttpAsyncRequestHandler<?> myRequestHandler3 = <...>
+UriHttpAsyncRequestHandlerMapper handlerReqistry =
+        new UriHttpAsyncRequestHandlerMapper();
 handlerReqistry.register("/service/*", myRequestHandler1);
 handlerReqistry.register("*.do", myRequestHandler2);
 handlerReqistry.register("*", myRequestHandler3);
@@ -1649,9 +1627,10 @@ handlerReqistry.register("*", myRequestHandler3);
             </para>
             <programlisting><![CDATA[
 HttpAsyncRequestExecutor ph = new HttpAsyncRequestExecutor();
-NHttpConnectionFactory<DefaultNHttpClientConnection> connFactory;
-// Initialize HTTP connection factory
-IOEventDispatch ioEventDispatch = new DefaultHttpClientIODispatch(ph, connFactory);
+IOEventDispatch ioEventDispatch = new DefaultHttpClientIODispatch(ph,
+        new DefaultNHttpClientConnectionFactory(ConnectionConfig.DEFAULT));
+ConnectingIOReactor ioreactor = new DefaultConnectingIOReactor();
+ioreactor.execute(ioEventDispatch);
 ]]></programlisting>
             <para>
             The <classname>HttpAsyncRequester</classname> utility class can be used to abstract
@@ -1661,17 +1640,15 @@ IOEventDispatch ioEventDispatch = new DefaultHttpClientIODispatch(ph, connFactor
             authentication and does not handle redirects automatically.
             </para>
             <programlisting><![CDATA[
-HttpParams params;
-// Initialize HTTP parameters
-HttpProcessor httpprocessor;
-// Initialize HTTP processor
-HttpAsyncRequester requester = new HttpAsyncRequester(
-        httpprocessor,
-        new DefaultConnectionReuseStrategy(),
-        params);
-
-//Obtain HTTP connection
-NHttpClientConnection conn;
+HttpProcessor httpproc = HttpProcessorBuilder.create()
+        .add(new RequestContent())
+        .add(new RequestTargetHost())
+        .add(new RequestConnControl())
+        .add(new RequestUserAgent("MyAgent-HTTP/1.1"))
+        .add(new RequestExpectContinue(true))
+        .build();
+HttpAsyncRequester requester = new HttpAsyncRequester(httpproc);
+NHttpClientConnection conn = <...>
 Future<HttpResponse> future = requester.execute(
         new BasicAsyncRequestProducer(
                 new HttpHost("localhost"),
@@ -1733,11 +1710,11 @@ HttpResponse response = future.get();
                         the entity to be incorrectly delimited
                         </para>
                         <para>
-                        Please note that the <interfacename>ContentEncoder</interfacename> object 
-                        is not thread-safe and should only be used within the context of this 
-                        method call. The <interfacename>IOControl</interfacename> object can be 
-                        shared and used on other thread resume output event notifications when 
-                        more content is made available.  
+                        Please note that the <interfacename>ContentEncoder</interfacename> object
+                        is not thread-safe and should only be used within the context of this
+                        method call. The <interfacename>IOControl</interfacename> object can be
+                        shared and used on other thread resume output event notifications when
+                        more content is made available.
                         </para>
                         <para>
                         This event is invoked only for if the outgoing request message has
@@ -1831,10 +1808,10 @@ HttpResponse response = future.get();
                         has been fully consumed.
                         </para>
                         <para>
-                        Please note that the <interfacename>ContentDecoder</interfacename> object 
-                        is not thread-safe and should only be used within the context of this 
-                        method call. The <interfacename>IOControl</interfacename> object can be 
-                        shared and used on other thread to resume input event notifications 
+                        Please note that the <interfacename>ContentDecoder</interfacename> object
+                        is not thread-safe and should only be used within the context of this
+                        method call. The <interfacename>IOControl</interfacename> object can be
+                        shared and used on other thread to resume input event notifications
                         when the consumer is capable of processing more content.
                         </para>
                         <para>
@@ -1913,6 +1890,62 @@ HttpResponse response = future.get();
         </section>
     </section>
     <section>
+        <title>Non-blocking connection pools</title>
+        <para>
+        Non-blocking connection pools are quite similar to blocking one with one significant
+        distinction that they have to reply an I/O reactor to establish new connections.
+        As a result connections leased from a non-blocking pool are returned fully initialized and
+        already bound to a particular I/O session. Non-blocking connections managed by a connection
+        pool cannot be bound to an arbitrary I/O session.
+        </para>
+        <programlisting><![CDATA[
+HttpHost target = new HttpHost("localhost");
+ConnectingIOReactor ioreactor = <...>
+BasicNIOConnPool connpool = new BasicNIOConnPool(ioreactor);
+connpool.lease(target, null,
+        10, TimeUnit.SECONDS,
+        new FutureCallback<BasicNIOPoolEntry>() {
+            @Override
+            public void completed(BasicNIOPoolEntry entry) {
+                NHttpClientConnection conn = entry.getConnection();
+                System.out.println("Connection successfully leased");
+                // Update connection context and request output
+                conn.requestOutput();
+            }
+
+            @Override
+            public void failed(Exception ex) {
+                System.out.println("Connection request failed");
+                ex.printStackTrace();
+            }
+
+            @Override
+            public void cancelled() {
+            }
+        });
+]]></programlisting>
+        <para>
+        Please note due to event-driven nature of asynchronous communication model it is quite
+        difficult to ensure proper release of persistent connections back to the pool. One can make
+        use of <classname>HttpAsyncRequester</classname> to handle connection lease and release
+        behind the scene.
+        </para>
+        <programlisting><![CDATA[
+ConnectingIOReactor ioreactor = <...>
+HttpProcessor httpproc = <...>
+BasicNIOConnPool connpool = new BasicNIOConnPool(ioreactor);
+HttpAsyncRequester requester = new HttpAsyncRequester(httpproc);
+HttpHost target = new HttpHost("localhost");
+Future<HttpResponse> future = requester.execute(
+        new BasicAsyncRequestProducer(
+                new HttpHost("localhost"),
+                new BasicHttpRequest("GET", "/")),
+        new BasicAsyncResponseConsumer(),
+        connpool);
+]]></programlisting>
+    </section>
+
+    <section>
         <title>Non-blocking TLS/SSL</title>
         <section>
             <title>SSL I/O session</title>
@@ -1924,20 +1957,15 @@ HttpResponse response = future.get();
             special preconditions or modifications.
             </para>
             <programlisting><![CDATA[
-// Initialize HTTP parameters
-HttpParams params;
-// Initialize default SSL context
-SSLContext sslcontext = SSLContext.getInstance("SSL");
+SSLContext sslcontext = SSLContext.getInstance("Default");
 sslcontext.init(null, null, null);
 // Plain I/O session
-IOSession iosession;
+IOSession iosession = <...>
 SSLIOSession sslsession = new SSLIOSession(
         iosession, SSLMode.CLIENT, sslcontext, null);
 iosession.setAttribute(SSLIOSession.SESSION_KEY, sslsession);
 NHttpClientConnection conn = new DefaultNHttpClientConnection(
-        sslsession,
-        new DefaultHttpResponseFactory(),
-        new HeapByteBufferAllocator(), params);
+        sslsession, 8 * 1024);
 ]]></programlisting>
             <para>
             One can also use <classname>SSLNHttpClientConnectionFactory</classname> or <classname>
@@ -1945,12 +1973,12 @@ NHttpClientConnection conn = new DefaultNHttpClientConnection(
             encrypterd HTTP connections.
             </para>
             <programlisting><![CDATA[
-// Initialize HTTP parameters
-HttpParams params;
+SSLContext sslcontext = SSLContext.getInstance("Default");
+sslcontext.init(null, null, null);
 // Plain I/O session
-IOSession iosession;
+IOSession iosession = <...>
 SSLNHttpClientConnectionFactory connfactory = new SSLNHttpClientConnectionFactory(
-        params);
+        sslcontext, null, ConnectionConfig.DEFAULT);
 NHttpClientConnection conn = connfactory.createConnection(iosession);
 ]]></programlisting>
             <section>
@@ -1989,14 +2017,13 @@ NHttpClientConnection conn = connfactory.createConnection(iosession);
                     </listitem>
                 </itemizedlist>
                 <programlisting><![CDATA[
-// Plain I/O session
-IOSession iosession;
-// Initialize default SSL context
-SSLContext sslcontext = SSLContext.getInstance("SSL");
+SSLContext sslcontext = SSLContext.getInstance("Default");
 sslcontext.init(null, null, null);
+// Plain I/O session
+IOSession iosession = <...>
 
 SSLIOSession sslsession = new SSLIOSession(
-    iosession, SSLMode.CLIENT, sslcontext, new SSLSetupHandler() {
+        iosession, SSLMode.CLIENT, sslcontext, new SSLSetupHandler() {
 
     public void initalize(final SSLEngine sslengine) throws SSLException {
         // Enforce strong ciphers
@@ -2024,11 +2051,11 @@ SSLIOSession sslsession = new SSLIOSession(
             SSLNHttpServerConnectionFactory</classname> classes.
             </para>
             <programlisting><![CDATA[
-// Initialize HTTP parameters
-HttpParams params;
-// Initialize default SSL context
-SSLContext sslcontext = SSLContext.getInstance("SSL");
+SSLContext sslcontext = SSLContext.getInstance("Default");
 sslcontext.init(null, null, null);
+// Plain I/O session
+IOSession iosession = <...>
+
 SSLSetupHandler mysslhandler = new SSLSetupHandler() {
 
     public void initalize(final SSLEngine sslengine) throws SSLException {
@@ -2045,11 +2072,8 @@ SSLSetupHandler mysslhandler = new SSLSetupHandler() {
 
 
 };
-// Plain I/O session
-IOSession iosession;
 SSLNHttpClientConnectionFactory connfactory = new SSLNHttpClientConnectionFactory(
-        sslcontext, mysslhandler, params);
-// Create SSL connection
+        sslcontext, mysslhandler, ConnectionConfig.DEFAULT);
 NHttpClientConnection conn = connfactory.createConnection(iosession);
 ]]></programlisting>
             </section>
diff --git a/src/docbkx/preface.xml b/src/docbkx/preface.xml
index c04dcd4..f344fa3 100644
--- a/src/docbkx/preface.xml
+++ b/src/docbkx/preface.xml
@@ -73,7 +73,7 @@
             </listitem>
             <listitem>
                 <para>
-                Self contained library (no external dependencies beyond JRE)
+                Self-contained library (no external dependencies beyond JRE)
                 </para>
             </listitem>
         </itemizedlist>
@@ -88,7 +88,7 @@
             </listitem>
             <listitem>
                 <para>
-                A replacement for a Servlet container or a competitor to the Servlet API
+                A replacement for Servlet APIs
                 </para>
             </listitem>
         </itemizedlist>
diff --git a/src/docbkx/resources/css/hc-tutorial.css b/src/docbkx/resources/css/hc-tutorial.css
index e4d0232..ddd1d30 100644
--- a/src/docbkx/resources/css/hc-tutorial.css
+++ b/src/docbkx/resources/css/hc-tutorial.css
@@ -23,7 +23,7 @@
    information on the Apache Software Foundation, please see
    <http://www.apache.org/>.
    ====================================================================
-   
+
     Based on the CSS file for the Spring Reference Documentation.
 */
 
@@ -306,4 +306,4 @@ div.note * td,
 .clear  {
   clear:both;
   visibility: hidden;
-}
\ No newline at end of file
+}
diff --git a/src/docbkx/resources/xsl/fopdf.xsl b/src/docbkx/resources/xsl/fopdf.xsl
index 0c7667a..f8647f1 100644
--- a/src/docbkx/resources/xsl/fopdf.xsl
+++ b/src/docbkx/resources/xsl/fopdf.xsl
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- 
+<!--
    ====================================================================
    Licensed to the Apache Software Foundation (ASF) under one
    or more contributor license agreements.  See the NOTICE file
@@ -31,7 +31,7 @@
     Thanks are due to Christian Bauer of the Hibernate project
     team for writing the original stylesheet upon which this one
     is based.
-    
+
 -->
 <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                 xmlns:fo="http://www.w3.org/1999/XSL/Format"
@@ -219,7 +219,7 @@
         </xsl:attribute>
     </xsl:attribute-set>
 
-    <!-- Why is the font-size for chapters hardcoded in the XSL FO templates? 
+    <!-- Why is the font-size for chapters hardcoded in the XSL FO templates?
         Let's remove it, so this sucker can use our attribute-set only... -->
     <xsl:template match="title" mode="chapter.titlepage.recto.auto.mode">
         <fo:block xmlns:fo="http://www.w3.org/1999/XSL/Format"
@@ -377,5 +377,5 @@
             </xsl:choose>
         </fo:basic-link>
     </xsl:template>
-    
+
 </xsl:stylesheet>
diff --git a/src/docbkx/resources/xsl/html.xsl b/src/docbkx/resources/xsl/html.xsl
index 53cec9e..49c223d 100644
--- a/src/docbkx/resources/xsl/html.xsl
+++ b/src/docbkx/resources/xsl/html.xsl
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- 
+<!--
    ====================================================================
    Licensed to the Apache Software Foundation (ASF) under one
    or more contributor license agreements.  See the NOTICE file
@@ -27,7 +27,7 @@
 
     Based on the XSL HTML configuration file for the Spring
     Reference Documentation.
-    
+
 -->
 <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                 xmlns:fo="http://www.w3.org/1999/XSL/Format"
diff --git a/src/docbkx/resources/xsl/html_chunk.xsl b/src/docbkx/resources/xsl/html_chunk.xsl
index 114918e..282b1ea 100644
--- a/src/docbkx/resources/xsl/html_chunk.xsl
+++ b/src/docbkx/resources/xsl/html_chunk.xsl
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- 
+<!--
    ====================================================================
    Licensed to the Apache Software Foundation (ASF) under one
    or more contributor license agreements.  See the NOTICE file
@@ -27,7 +27,7 @@
 
     Based on the XSL HTML configuration file for the Spring
     Reference Documentation.
-    
+
 -->
 <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                 xmlns:fo="http://www.w3.org/1999/XSL/Format"
diff --git a/src/main/assembly/bin.xml b/src/main/assembly/bin.xml
deleted file mode 100644
index ce94324..0000000
--- a/src/main/assembly/bin.xml
+++ /dev/null
@@ -1,85 +0,0 @@
-<!-- 
-   $HeadURL: https://svn.apache.org/repos/asf/httpcomponents/httpcore/tags/4.2.4-RC2/src/main/assembly/bin.xml $
-   $Revision: 1233961 $
-
-   ====================================================================
-   Licensed to the Apache Software Foundation (ASF) under one
-   or more contributor license agreements.  See the NOTICE file
-   distributed with this work for additional information
-   regarding copyright ownership.  The ASF licenses this file
-   to you 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.
-   ====================================================================
-
-   This software consists of voluntary contributions made by many
-   individuals on behalf of the Apache Software Foundation.  For more
-   information on the Apache Software Foundation, please see
-   <http://www.apache.org/>.
- -->
-<assembly>
-    <id>bin</id>
-    <formats>
-        <format>tar.gz</format>
-        <format>zip</format>
-    </formats>
-    <moduleSets>
-        <moduleSet>
-          <excludes>
-            <exclude>org.apache.httpcomponents:httpcore-osgi</exclude>
-          </excludes>
-          <binaries>
-            <includeDependencies>false</includeDependencies>
-            <outputDirectory>/lib</outputDirectory>
-            <unpack>false</unpack>
-          </binaries>
-        </moduleSet>
-    </moduleSets>
-    <fileSets>
-        <fileSet>
-          <directory></directory>
-          <outputDirectory>/</outputDirectory>
-          <includes>
-            <include>README.txt</include>
-            <include>LICENSE.txt</include>
-            <include>NOTICE.txt</include>
-            <include>RELEASE_NOTES.txt</include>
-          </includes>
-        </fileSet>
-        <!-- Javadocs -->
-        <fileSet>
-          <directory>target/site/apidocs</directory>
-          <outputDirectory>javadoc</outputDirectory>
-        </fileSet>
-        <!-- Tutorial -->
-        <fileSet>
-          <directory>target/site/tutorial</directory>
-          <outputDirectory>tutorial</outputDirectory>
-        </fileSet>
-        <!-- Examples: base module -->
-        <fileSet>
-          <directory>httpcore/src/examples/</directory>
-          <outputDirectory>examples</outputDirectory>
-          <includes>
-            <include>**/*.java</include>
-          </includes>
-        </fileSet>
-        <!-- Examples: NIO module -->
-        <fileSet>
-          <directory>httpcore-nio/src/examples/</directory>
-          <outputDirectory>examples</outputDirectory>
-          <includes>
-            <include>**/*.java</include>
-          </includes>
-        </fileSet>
-    </fileSets>
-</assembly>
diff --git a/src/main/assembly/build.xml b/src/main/assembly/build.xml
deleted file mode 100644
index 5aeddac..0000000
--- a/src/main/assembly/build.xml
+++ /dev/null
@@ -1,70 +0,0 @@
-<!-- 
-   ====================================================================
-   Licensed to the Apache Software Foundation (ASF) under one
-   or more contributor license agreements.  See the NOTICE file
-   distributed with this work for additional information
-   regarding copyright ownership.  The ASF licenses this file
-   to you 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.
-   ====================================================================
-
-   This software consists of voluntary contributions made by many
-   individuals on behalf of the Apache Software Foundation.  For more
-   information on the Apache Software Foundation, please see
-   <http://www.apache.org/>.
- -->
-<project name="assembly-postprocess" default="fixarchives" basedir=".">
-
-  <!-- Use property to define the source file types, as it is needed twice -->
-  <property name="src.file.types" 
-  	value="**/*.txt **/*.xml **/*.properties **/*.java **/*.html **/*.css **/*.apt **/*.xsl"/>
-
-  <target name="fixarchives" depends="_eolcheck,fixzip,fixtgz">
-  </target>
-
-  <target name="fixzip" unless="native.crlf">
-    <property name="tmp.dir" location="${target}/tmp"/>    
-    <property name="zip.file" location="${target}/${package.name}.zip"/>    
-    <delete dir="${tmp.dir}" />
-    <unzip src="${zip.file}" dest="${tmp.dir}"/>
-    <fixcrlf srcdir="${tmp.dir}" eol="crlf" eof="remove" fixlast="false"
-        includes="${src.file.types}" />
-    <zip destfile="${zip.file}" basedir="${tmp.dir}" duplicate="preserve" />
-    <delete dir="${tmp.dir}" />
-  </target>  
-
-  <target name="fixtgz" unless="native.lf">
-    <property name="tmp.dir" location="${target}/tmp"/>    
-    <property name="gz.file" location="${target}/${package.name}.tar.gz"/>    
-    <property name="tar.file" location="${target}/${package.name}.tar"/>    
-    <delete dir="${tmp.dir}" />
-    <gunzip src="${gz.file}" dest="${tar.file}"/>
-    <untar src="${tar.file}" dest="${tmp.dir}"/>
-    <fixcrlf srcdir="${tmp.dir}" eol="lf" eof="remove" fixlast="false"
-        includes="${src.file.types}" />
-    <tar destfile="${tar.file}" basedir="${tmp.dir}" longfile="gnu"/>
-    <gzip src="${tar.file}" destfile="${gz.file}"/>
-    <delete file="${tar.file}"/>
-    <delete dir="${tmp.dir}"/>
-  </target>  
-
-  <!-- Determine if the native format is CRLF or LF (or neither) -->
-  <target name="_eolcheck">
-    <condition property="native.lf">
-        <os family="unix"/>
-    </condition>
-    <condition property="native.crlf">
-        <os family="dos"/>
-    </condition>
-  </target>
-</project>
diff --git a/src/main/assembly/osgi-bin.xml b/src/main/assembly/osgi-bin.xml
deleted file mode 100644
index 755c267..0000000
--- a/src/main/assembly/osgi-bin.xml
+++ /dev/null
@@ -1,80 +0,0 @@
-<!-- 
-   ====================================================================
-   Licensed to the Apache Software Foundation (ASF) under one
-   or more contributor license agreements.  See the NOTICE file
-   distributed with this work for additional information
-   regarding copyright ownership.  The ASF licenses this file
-   to you 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.
-   ====================================================================
-
-   This software consists of voluntary contributions made by many
-   individuals on behalf of the Apache Software Foundation.  For more
-   information on the Apache Software Foundation, please see
-   <http://www.apache.org/>.
- -->
-<assembly>
-    <id>osgi-bin</id>
-    <formats>
-        <format>tar.gz</format>
-        <format>zip</format>
-    </formats>
-    <fileSets>
-        <fileSet>
-          <directory>httpcore-osgi/target</directory>
-          <outputDirectory>/</outputDirectory>
-          <includes>
-            <include>*.jar</include>
-          </includes>
-          <excludes>
-            <exclude>*sources.jar</exclude>
-          </excludes>
-        </fileSet>
-        <fileSet>
-          <directory></directory>
-          <outputDirectory>/</outputDirectory>
-          <includes>
-            <include>README.txt</include>
-            <include>LICENSE.txt</include>
-            <include>NOTICE.txt</include>
-            <include>RELEASE_NOTES.txt</include>
-          </includes>
-        </fileSet>
-        <!-- Javadocs -->
-        <fileSet>
-          <directory>target/site/apidocs</directory>
-          <outputDirectory>javadoc</outputDirectory>
-        </fileSet>
-        <!-- Tutorial -->
-        <fileSet>
-          <directory>target/site/tutorial</directory>
-          <outputDirectory>tutorial</outputDirectory>
-        </fileSet>
-        <!-- Examples: base module -->
-        <fileSet>
-          <directory>httpcore/src/examples/</directory>
-          <outputDirectory>examples</outputDirectory>
-          <includes>
-            <include>**/*.java</include>
-          </includes>
-        </fileSet>
-        <!-- Examples: NIO module -->
-        <fileSet>
-          <directory>httpcore-nio/src/examples/</directory>
-          <outputDirectory>examples</outputDirectory>
-          <includes>
-            <include>**/*.java</include>
-          </includes>
-        </fileSet>
-    </fileSets>
-</assembly>
diff --git a/src/main/assembly/src.xml b/src/main/assembly/src.xml
deleted file mode 100644
index 3f949b7..0000000
--- a/src/main/assembly/src.xml
+++ /dev/null
@@ -1,48 +0,0 @@
-<!-- 
-   ====================================================================
-   Licensed to the Apache Software Foundation (ASF) under one
-   or more contributor license agreements.  See the NOTICE file
-   distributed with this work for additional information
-   regarding copyright ownership.  The ASF licenses this file
-   to you 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.
-   ====================================================================
-
-   This software consists of voluntary contributions made by many
-   individuals on behalf of the Apache Software Foundation.  For more
-   information on the Apache Software Foundation, please see
-   <http://www.apache.org/>.
- -->
-<assembly>
-    <id>src</id>
-    <formats>
-        <format>tar.gz</format>
-        <format>zip</format>
-    </formats>
-    <fileSets>
-        <!-- Release materials -->
-        <fileSet>
-          <directory></directory>
-          <outputDirectory>/</outputDirectory>
-          <excludes>
-            <exclude>**/.*</exclude>
-            <exclude>**/.*/**</exclude>
-            <exclude>**/bin/**</exclude>
-            <exclude>**/target/**</exclude>
-            <exclude>**/local/**</exclude>
-            <exclude>**/lib/**</exclude>
-            <exclude>*.rdf</exclude>
-          </excludes>
-        </fileSet>
-    </fileSets>
-</assembly>
diff --git a/src/site/apt/download.apt b/src/site/apt/download.apt
deleted file mode 100644
index 6af4519..0000000
--- a/src/site/apt/download.apt
+++ /dev/null
@@ -1,66 +0,0 @@
-~~ ====================================================================
-~~ Licensed to the Apache Software Foundation (ASF) under one
-~~ or more contributor license agreements.  See the NOTICE file
-~~ distributed with this work for additional information
-~~ regarding copyright ownership.  The ASF licenses this file
-~~ to you 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.
-~~ ====================================================================
-~~ 
-~~ This software consists of voluntary contributions made by many
-~~ individuals on behalf of the Apache Software Foundation.  For more
-~~ information on the Apache Software Foundation, please see
-~~ <http://www.apache.org/>.
-
-    ----------
-    HttpComponents HttpCore Download Page
-    ----------
-    ----------
-    ----------
-
-HttpCore Downloads
-
-    The latest release available for download:
-
-    {{{http://hc.apache.org/downloads.cgi}Release packages}} - 
-    {{{http://www.apache.org/dist/httpcomponents/httpcore/RELEASE_NOTES.txt}Release Notes}} -
-    {{{http://www.apache.org/licenses/LICENSE-2.0.html}License}}
-
-{Dependency management with Maven}
-
-    If you are using {{{http://maven.apache.org}Maven}} for your project, you can create a dependency 
-    in your {{{http://maven.apache.org/guides/introduction/introduction-to-the-pom.html}pom.xml}} 
-    by adding the following block to the dependency descriptor:
-
-* {HttpComponents Core 4.2.4 (GA)}
-
--------------------------
-  <dependency>
-    <groupId>org.apache.httpcomponents</groupId>
-    <artifactId>httpcore</artifactId>
-    <version>4.2.4</version>
-    <scope>compile</scope>
-  </dependency>
--------------------------
-
-* {HttpComponents Core NIO 4.2.4 (GA)}
-
--------------------------
-  <dependency>
-    <groupId>org.apache.httpcomponents</groupId>
-    <artifactId>httpcore-nio</artifactId>
-    <version>4.2.4</version>
-    <scope>compile</scope>
-  </dependency>
--------------------------
-
diff --git a/src/site/apt/examples.apt b/src/site/apt/examples.apt
deleted file mode 100644
index 4663576..0000000
--- a/src/site/apt/examples.apt
+++ /dev/null
@@ -1,62 +0,0 @@
-~~ ====================================================================
-~~ Licensed to the Apache Software Foundation (ASF) under one
-~~ or more contributor license agreements.  See the NOTICE file
-~~ distributed with this work for additional information
-~~ regarding copyright ownership.  The ASF licenses this file
-~~ to you 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.
-~~ ====================================================================
-~~ 
-~~ This software consists of voluntary contributions made by many
-~~ individuals on behalf of the Apache Software Foundation.  For more
-~~ information on the Apache Software Foundation, please see
-~~ <http://www.apache.org/>.
-
-    ----------
-    HttpComponents HttpCore Examples
-    ----------
-    ----------
-    ----------
-
-HttpCore Examples
-
-    * {{{./httpcore/examples/org/apache/http/examples/ElementalHttpGet.java} Basic HTTP GET}}
-    
-    This example demonstrates how to execute a series of synchronous (blocking) HTTP GET requests.
-
-    * {{{./httpcore/examples/org/apache/http/examples/ElementalHttpPost.java} Basic HTTP POST}}
-    
-    This example demonstrates how to execute a series of synchronous (blocking) HTTP POST requests 
-    that enclose entity content of various types: a string, a byte array, an arbitrary input stream.  
-
-    * {{{./httpcore/examples/org/apache/http/examples/ElementalHttpServer.java} Basic HTTP server}}
-    
-    This is an example of an HTTP/1.1 file server based on a synchronous (blocking) I/O model.
-
-    * {{{./httpcore-nio/examples/org/apache/http/examples/nio/NHttpClient.java} Asynchronous HTTP GET}}
-    
-    This example demonstrates how HttpCore NIO can be used to execute multiple HTTP requests 
-    asynchronously using only one I/O thread.
-
-    * {{{./httpcore-nio/examples/org/apache/http/examples/nio/NHttpServer.java} Asynchronous HTTP 
-    server}}
-    
-    This example demonstrates the use of HttpCore NIO to build an asynchronous (non-blocking) 
-    HTTP server capable of direct channel (zero copy) data transfer.
-
-    * {{{./httpcore-nio/examples/org/apache/http/examples/nio/NHttpReverseProxy.java} Asynchronous 
-    HTTP reverse proxy}}
-    
-    This example demonstrates how HttpCore NIO can be used to build an asynchronous, fully
-    streaming reverse HTTP proxy.
-  
diff --git a/src/site/apt/index.apt b/src/site/apt/index.apt
deleted file mode 100644
index 5c572ca..0000000
--- a/src/site/apt/index.apt
+++ /dev/null
@@ -1,61 +0,0 @@
-~~ ====================================================================
-~~ Licensed to the Apache Software Foundation (ASF) under one
-~~ or more contributor license agreements.  See the NOTICE file
-~~ distributed with this work for additional information
-~~ regarding copyright ownership.  The ASF licenses this file
-~~ to you 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.
-~~ ====================================================================
-~~ 
-~~ This software consists of voluntary contributions made by many
-~~ individuals on behalf of the Apache Software Foundation.  For more
-~~ information on the Apache Software Foundation, please see
-~~ <http://www.apache.org/>.
-
-    ----------
-    HttpComponents HttpCore Overview
-    ----------
-    ----------
-    ----------
-
-HttpCore Overview
-
-    HttpCore is a set of low level HTTP transport components that can be used to build custom
-    client and server side HTTP services with a minimal footprint. HttpCore supports two I/O models: 
-    blocking I/O model based on the classic Java I/O and non-blocking, event driven I/O model based 
-    on Java NIO. 
-    
-    The blocking I/O model may be more appropriate for data intensive, low latency scenarios,
-    whereas the non-blocking model may be more appropriate for high latency scenarios where raw data
-    throughput is less important than the ability to handle thousands of simultaneous HTTP 
-    connections in a resource efficient manner.
-
-    * {{{./httpcore/index.html}HttpCore}}
-
-    * {{{./httpcore-nio/index.html}HttpCore NIO}}
-    
-{Documentation}
-
-    * HttpCore Tutorial ( {{{./tutorial/html/index.html}HTML}} / {{{./tutorial/pdf/httpcore-tutorial.pdf}PDF}} )
-    
-    * Some examples of HttpCore components in action can be found {{{./examples.html}here}}
-    
-{Standards Compliance}
-
-    HttpCore components strive to conform to the following specifications endorsed by the Internet 
-    Engineering Task Force (IETF) and the internet at large:
-
-    * {{{http://www.ietf.org/rfc/rfc1945.txt}RFC 1945}} - Hypertext Transfer Protocol -- HTTP/1.0
-
-    * {{{http://www.ietf.org/rfc/rfc2616.txt}RFC 2616}} - Hypertext Transfer Protocol -- HTTP/1.1
-    
diff --git a/src/site/resources/css/site.css b/src/site/resources/css/site.css
deleted file mode 100644
index 41016d1..0000000
--- a/src/site/resources/css/site.css
+++ /dev/null
@@ -1 +0,0 @@
- at import url("../../css/hc-maven.css");
diff --git a/src/site/site.xml b/src/site/site.xml
deleted file mode 100644
index 16ede72..0000000
--- a/src/site/site.xml
+++ /dev/null
@@ -1,45 +0,0 @@
-<?xml version="1.0" encoding="ISO-8859-1"?>
-<!--
-   ====================================================================
-   Licensed to the Apache Software Foundation (ASF) under one
-   or more contributor license agreements.  See the NOTICE file
-   distributed with this work for additional information
-   regarding copyright ownership.  The ASF licenses this file
-   to you 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.
-   ====================================================================
-
-   This software consists of voluntary contributions made by many
-   individuals on behalf of the Apache Software Foundation.  For more
-   information on the Apache Software Foundation, please see
-   <http://www.apache.org/>.
- -->
-
-<project name="HttpCore">
-
-  <body>
-    <menu name="HttpCore Overview">
-      <item name="Description" href="index.html"/>
-    </menu>
-    <menu name="Documentation">
-      <item name="Tutorial" href="tutorial/html/index.html"/>
-      <item name="Examples" href="examples.html"/>
-    </menu>
-    <menu name="Modules">
-      <item name="HttpCore" href="httpcore/index.html"/>
-      <item name="HttpCore NIO" href="httpcore-nio/index.html"/>
-    </menu>
-    <!-- Reports don't really apply at this level; in particular the dependecy report is misleading -->
-    <!-- menu ref="reports"/-->
-  </body>
-</project>

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-java/httpcomponents-core.git



More information about the pkg-java-commits mailing list