You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hc.apache.org by ol...@apache.org on 2018/08/26 15:34:11 UTC

[3/6] httpcomponents-core git commit: Removed HttpCore 4.x tutorual sources

http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/c53af482/src/docbkx/nio.xml
----------------------------------------------------------------------
diff --git a/src/docbkx/nio.xml b/src/docbkx/nio.xml
deleted file mode 100644
index beb3963..0000000
--- a/src/docbkx/nio.xml
+++ /dev/null
@@ -1,2195 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE preface PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
-                 "http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd">
-<!--
-   ====================================================================
-   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.
-   ====================================================================
-
--->
-<chapter id="nio">
-    <title>Asynchronous I/O based on NIO</title>
-    <para>
-    Asynchronous I/O model may be more appropriate for those scenarios where raw data throughput
-    is less important than the ability to handle thousands of simultaneous connections in
-    a scalable, resource efficient manner. Asynchronous I/O is arguably more complex and usually
-    requires a special care when dealing with large message payloads.
-    </para>
-    <section>
-        <title>Differences from other I/O frameworks</title>
-        <para>
-        Solves similar problems as other frameworks, but has certain distinct features:
-        </para>
-        <itemizedlist>
-            <listitem>
-                <para>
-                minimalistic, optimized for data volume intensive protocols such as HTTP.
-                </para>
-            </listitem>
-            <listitem>
-                <para>
-                efficient memory management: data consumer can read is only as much input data as it
-                can process without having to allocate more memory.
-                </para>
-            </listitem>
-            <listitem>
-                <para>
-                direct access to the NIO channels where possible.
-                </para>
-            </listitem>
-        </itemizedlist>
-    </section>
-    <section>
-        <title>I/O reactor</title>
-        <para>
-        HttpCore NIO is based on the Reactor pattern as described by Doug Lea. The purpose of I/O
-        reactors is to react to I/O events and to dispatch event notifications to individual I/O
-        sessions. The main idea of I/O reactor pattern is to break away from the one thread per
-        connection model imposed by the classic blocking I/O model. The <interfacename>IOReactor
-        </interfacename> interface represents an abstract object which implements the Reactor pattern.
-        Internally, <interfacename>IOReactor</interfacename> implementations encapsulate
-        functionality of the NIO <classname>java.nio.channels.Selector</classname>.
-        </para>
-        <para>
-        I/O reactors usually employ a small number of dispatch threads (often as few as one) to
-        dispatch I/O event notifications to a much greater number (often as many as several
-        thousands) of I/O sessions or connections. It is generally recommended to have one dispatch
-        thread per CPU core.
-        </para>
-        <programlisting><![CDATA[
-IOReactorConfig config = IOReactorConfig.DEFAULT;
-IOReactor ioreactor = new DefaultConnectingIOReactor(config);
-]]></programlisting>
-        <section>
-            <title>I/O dispatchers</title>
-            <para>
-            <interfacename>IOReactor</interfacename> implementations make use of the
-            <interfacename>IOEventDispatch</interfacename> interface to notify clients of events
-            pending for a particular session. All methods of the <interfacename>IOEventDispatch
-            </interfacename> are executed on a dispatch thread of the I/O reactor. Therefore, it is
-            important that processing that takes place in the event methods will not block the
-            dispatch thread for too long, as the I/O reactor will be unable to react to other
-            events.
-            </para>
-            <programlisting><![CDATA[
-IOReactor ioreactor = new DefaultConnectingIOReactor();
-
-IOEventDispatch eventDispatch = <...>
-ioreactor.execute(eventDispatch);
-]]></programlisting>
-            <para>
-            Generic I/O events as defined by the <interfacename>IOEventDispatch</interfacename>
-            interface:
-            </para>
-            <itemizedlist>
-                <listitem>
-                    <formalpara>
-                    <title><methodname>connected</methodname>:</title>
-                    <para>
-                    Triggered when a new session has been created.
-                    </para>
-                    </formalpara>
-                </listitem>
-                <listitem>
-                    <formalpara>
-                    <title><methodname>inputReady</methodname>:</title>
-                    <para>
-                    Triggered when the session has pending input.
-                    </para>
-                    </formalpara>
-                </listitem>
-                <listitem>
-                    <formalpara>
-                    <title><methodname>outputReady</methodname>:</title>
-                    <para>
-                    Triggered when the session is ready for output.
-                    </para>
-                    </formalpara>
-                </listitem>
-                <listitem>
-                    <formalpara>
-                    <title><methodname>timeout</methodname>:</title>
-                    <para>
-                    Triggered when the session has timed out.
-                    </para>
-                    </formalpara>
-                </listitem>
-                <listitem>
-                    <formalpara>
-                    <title><methodname>disconnected</methodname>:</title>
-                    <para>
-                    Triggered when the session has been terminated.
-                    </para>
-                    </formalpara>
-                </listitem>
-            </itemizedlist>
-        </section>
-        <section>
-            <title>I/O reactor shutdown</title>
-            <para>
-            The shutdown of I/O reactors is a complex process and may usually take a while to
-            complete. I/O reactors will attempt to gracefully terminate all active I/O sessions and
-            dispatch threads approximately within the specified grace period. If any of the I/O
-            sessions fails to terminate correctly, the I/O reactor will forcibly shut down
-            remaining sessions.
-            </para>
-            <programlisting><![CDATA[
-IOReactor ioreactor = <...>
-long gracePeriod = 3000L; // milliseconds
-ioreactor.shutdown(gracePeriod);
-]]></programlisting>
-            <para>
-            The <methodname>IOReactor#shutdown(long)</methodname> method is safe to call from any
-            thread.
-            </para>
-        </section>
-        <section>
-            <title>I/O sessions</title>
-            <para>
-            The <interfacename>IOSession</interfacename> interface represents a sequence of
-            logically related data exchanges between two end points. <interfacename>IOSession
-            </interfacename> encapsulates functionality of NIO <classname>
-            java.nio.channels.SelectionKey</classname> and <classname>
-            java.nio.channels.SocketChannel</classname>. The channel associated with the
-            <interfacename>IOSession</interfacename> can be used to read data from and write data
-            to the session.
-            </para>
-            <programlisting><![CDATA[
-IOSession iosession = <...>
-ReadableByteChannel ch = (ReadableByteChannel) iosession.channel();
-ByteBuffer dst = ByteBuffer.allocate(2048);
-ch.read(dst);
-]]></programlisting>
-        </section>
-        <section>
-            <title>I/O session state management</title>
-            <para>
-            I/O sessions are not bound to an execution thread, therefore one cannot use the context
-            of the thread to store a session's state. All details about a particular session must
-            be stored within the session itself.
-            </para>
-            <programlisting><![CDATA[
-IOSession iosession = <...>
-Object someState = <...>
-iosession.setAttribute("state", someState);
-...
-IOSession iosession = <...>
-Object currentState = iosession.getAttribute("state");
-]]></programlisting>
-            <para>
-            Please note that if several sessions make use of shared objects, access to those
-            objects must be made thread-safe.
-            </para>
-        </section>
-        <section>
-            <title>I/O session event mask</title>
-            <para>
-            One can declare an interest in a particular type of I/O events for a particular I/O
-            session by setting its event mask.
-            </para>
-            <programlisting><![CDATA[
-IOSession iosession = <...>
-iosession.setEventMask(SelectionKey.OP_READ | SelectionKey.OP_WRITE);
-]]></programlisting>
-            <para>
-            One can also toggle <literal>OP_READ</literal> and <literal>OP_WRITE</literal> flags
-            individually.
-            </para>
-            <programlisting><![CDATA[
-IOSession iosession = <...>
-iosession.setEvent(SelectionKey.OP_READ);
-iosession.clearEvent(SelectionKey.OP_READ);
-]]></programlisting>
-            <para>
-            Event notifications will not take place if the corresponding interest flag is not set.
-            </para>
-        </section>
-        <section>
-            <title>I/O session buffers</title>
-            <para>
-            Quite often I/O sessions need to maintain internal I/O buffers in order to transform
-            input / output data prior to returning it to the consumer or writing it to the
-            underlying channel. Memory management in HttpCore NIO is based on the fundamental
-            principle that the data a consumer can read, is only as much input data as it can process
-            without having to allocate more memory. That means, quite often some input data may
-            remain unread in one of the internal or external session buffers. The I/O reactor can
-            query the status of these session buffers, and make sure the consumer gets notified
-            correctly as more data gets stored in one of the session buffers, thus allowing the
-            consumer to read the remaining data once it is able to process it. I/O sessions can be
-            made aware of the status of external session buffers using the <interfacename>
-            SessionBufferStatus</interfacename> interface.
-            </para>
-            <programlisting><![CDATA[
-IOSession iosession = <...>
-SessionBufferStatus myBufferStatus = <...>
-iosession.setBufferStatus(myBufferStatus);
-iosession.hasBufferedInput();
-iosession.hasBufferedOutput();
-]]></programlisting>
-        </section>
-        <section>
-            <title>I/O session shutdown</title>
-            <para>
-            One can close an I/O session gracefully by calling <methodname>IOSession#close()
-            </methodname> allowing the session to be closed in an orderly manner or by calling
-            <methodname>IOSession#shutdown()</methodname> to forcibly close the underlying channel.
-            The distinction between two methods is of primary importance for those types of I/O
-            sessions that involve some sort of a session termination handshake such as SSL/TLS
-            connections.
-            </para>
-        </section>
-        <section>
-            <title>Listening I/O reactors</title>
-            <para>
-            <interfacename>ListeningIOReactor</interfacename> represents an I/O reactor capable of
-            listening for incoming connections on one or several ports.
-            </para>
-            <programlisting><![CDATA[
-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();
-ep3.waitFor();
-]]></programlisting>
-            <para>
-            Once an endpoint is fully initialized it starts accepting incoming connections and
-            propagates I/O activity notifications to the <interfacename>IOEventDispatch
-            </interfacename> instance.
-            </para>
-            <para>
-            One can obtain a set of registered endpoints at runtime, query the status of an
-            endpoint at runtime, and close it if desired.
-            </para>
-            <programlisting><![CDATA[
-ListeningIOReactor ioreactor = <...>
-
-Set<ListenerEndpoint> eps = ioreactor.getEndpoints();
-for (ListenerEndpoint ep: eps) {
-    // Still active?
-    System.out.println(ep.getAddress());
-    if (ep.isClosed()) {
-        // If not, has it terminated due to an exception?
-        if (ep.getException() != null) {
-            ep.getException().printStackTrace();
-        }
-    } else {
-        ep.close();
-    }
-}
-]]></programlisting>
-        </section>
-        <section>
-            <title>Connecting I/O reactors</title>
-            <para>
-            <interfacename>ConnectingIOReactor</interfacename> represents an I/O reactor capable of
-            establishing connections with remote hosts.
-            </para>
-            <programlisting><![CDATA[
-ConnectingIOReactor ioreactor = <...>
-
-SessionRequest sessionRequest = ioreactor.connect(
-        new InetSocketAddress("www.google.com", 80),
-        null, null, null);
-]]></programlisting>
-            <para>
-            Opening a connection to a remote host usually tends to be a time consuming process and
-            may take a while to complete. One can monitor and control the process of session
-            initialization by means of the <interfacename>SessionRequest</interfacename>interface.
-            </para>
-            <programlisting><![CDATA[
-// Make sure the request times out if connection
-// has not been established after 1 sec
-sessionRequest.setConnectTimeout(1000);
-// Wait for the request to complete
-sessionRequest.waitFor();
-// Has request terminated due to an exception?
-if (sessionRequest.getException() != null) {
-    sessionRequest.getException().printStackTrace();
-}
-// Get hold of the new I/O session
-IOSession iosession = sessionRequest.getSession();
-]]></programlisting>
-            <para>
-            <interfacename>SessionRequest</interfacename> implementations are expected to be
-            thread-safe. Session request can be aborted at any time by calling <methodname>
-            IOSession#cancel()</methodname> from another thread of execution.
-            </para>
-            <programlisting><![CDATA[
-if (!sessionRequest.isCompleted()) {
-    sessionRequest.cancel();
-}
-]]></programlisting>
-            <para>
-            One can pass several optional parameters to the <methodname>
-            ConnectingIOReactor#connect()</methodname> method to exert a greater control over the
-            process of session initialization.
-            </para>
-            <para>
-            A non-null local socket address parameter can be used to bind the socket to a specific
-            local address.
-            </para>
-            <programlisting><![CDATA[
-ConnectingIOReactor ioreactor = <...>
-
-SessionRequest sessionRequest = ioreactor.connect(
-        new InetSocketAddress("www.google.com", 80),
-        new InetSocketAddress("192.168.0.10", 1234),
-        null, null);
-]]></programlisting>
-            <para>
-            One can provide an attachment object, which will be added to the new session's context
-            upon initialization. This object can be used to pass an initial processing state to
-            the protocol handler.
-            </para>
-            <programlisting><![CDATA[
-SessionRequest sessionRequest = ioreactor.connect(
-        new InetSocketAddress("www.google.com", 80),
-        null, new HttpHost("www.google.ru"), null);
-
-IOSession iosession = sessionRequest.getSession();
-HttpHost virtualHost = (HttpHost) iosession.getAttribute(
-    IOSession.ATTACHMENT_KEY);
-]]></programlisting>
-            <para>
-            It is often desirable to be able to react to the completion of a session request
-            asynchronously without having to wait for it, blocking the current thread of execution.
-            One can optionally provide an implementation <interfacename>SessionRequestCallback
-            </interfacename> interface to get notified of events related to session requests, such
-            as request completion, cancellation, failure or timeout.
-            </para>
-            <programlisting><![CDATA[
-ConnectingIOReactor ioreactor = <...>
-
-SessionRequest sessionRequest = ioreactor.connect(
-        new InetSocketAddress("www.google.com", 80), null, null,
-        new SessionRequestCallback() {
-
-            public void cancelled(SessionRequest request) {
-            }
-
-            public void completed(SessionRequest request) {
-                System.out.println("new connection to " +
-                    request.getRemoteAddress());
-            }
-
-            public void failed(SessionRequest request) {
-                if (request.getException() != null) {
-                    request.getException().printStackTrace();
-                }
-            }
-
-            public void timeout(SessionRequest request) {
-            }
-
-        });
-]]></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>
-            Several older JRE implementations (primarily from IBM) include what Java API
-            documentation refers to as a naive implementation of the <classname>
-            java.nio.channels.SelectionKey</classname> class. The problem with <classname>
-            java.nio.channels.SelectionKey</classname> in such JREs is that reading or writing
-            of the I/O interest set may block indefinitely if the I/O selector is in the process
-            of executing a select operation. HttpCore NIO can be configured to operate in a special
-            mode wherein I/O interest set operations are queued and executed by on the dispatch
-            thread only when the I/O selector is not engaged in a select operation.
-            </para>
-            <programlisting><![CDATA[
-IOReactorConfig config = IOReactorConfig.custom()
-        .setInterestOpQueued(true)
-        .build();
-]]></programlisting>
-        </section>
-    </section>
-    <section>
-        <title>I/O reactor exception handling</title>
-        <para>
-        Protocol specific exceptions as well as those I/O exceptions thrown in the course of
-        interaction with the session's channel are to be expected and are to be dealt with by specific
-        protocol handlers. These exceptions may result in termination of an individual session but
-        should not affect the I/O reactor and all other active sessions. There are situations,
-        however, when the I/O reactor itself encounters an internal problem such as an I/O
-        exception in the underlying NIO classes or an unhandled runtime exception. Those types of
-        exceptions are usually fatal and will cause the I/O reactor to shut down automatically.
-        </para>
-        <para>
-        There is a possibility to override this behavior and prevent I/O reactors from shutting
-        down automatically in case of a runtime exception or an I/O exception in internal classes.
-        This can be accomplished by providing a custom implementation of the <interfacename>
-        IOReactorExceptionHandler</interfacename> interface.
-        </para>
-        <programlisting><![CDATA[
-DefaultConnectingIOReactor ioreactor = <...>
-
-ioreactor.setExceptionHandler(new IOReactorExceptionHandler() {
-
-    public boolean handle(IOException ex) {
-        if (ex instanceof BindException) {
-            // bind failures considered OK to ignore
-            return true;
-        }
-        return false;
-    }
-
-    public boolean handle(RuntimeException ex) {
-        if (ex instanceof UnsupportedOperationException) {
-            // Unsupported operations considered OK to ignore
-            return true;
-        }
-        return false;
-    }
-
-});
-]]></programlisting>
-        <para>
-        One needs to be very careful about discarding exceptions indiscriminately. It is often much
-        better to let the I/O reactor shut down itself cleanly and restart it rather than leaving
-        it in an inconsistent or unstable state.
-        </para>
-        <section>
-            <title>I/O reactor audit log</title>
-            <para>
-            If an I/O reactor is unable to automatically recover from an I/O or a runtime exception
-            it will enter the shutdown mode. First off, it will close all active listeners and
-            cancel all pending new session requests. Then it will attempt to close all active I/O
-            sessions gracefully giving them some time to flush pending output data and terminate
-            cleanly. Lastly, it will forcibly shut down those I/O sessions that still remain active
-            after the grace period. This is a fairly complex process, where many things can fail at
-            the same time and many different exceptions can be thrown in the course of the shutdown
-            process. The I/O reactor will record all exceptions thrown during the shutdown process,
-            including the original one that actually caused the shutdown in the first place, in an
-            audit log. One can examine the audit log and decide whether it is safe to restart the
-            I/O reactor.
-            </para>
-            <programlisting><![CDATA[
-DefaultConnectingIOReactor ioreactor = <...>
-
-// Give it 5 sec grace period
-ioreactor.shutdown(5000);
-List<ExceptionEvent> events = ioreactor.getAuditLog();
-for (ExceptionEvent event: events) {
-    System.err.println("Time: " + event.getTimestamp());
-    event.getCause().printStackTrace();
-}
-]]></programlisting>
-        </section>
-    </section>
-    <section>
-        <title>Non-blocking HTTP connections</title>
-        <para>
-        Effectively non-blocking HTTP connections are wrappers around <interfacename>IOSession
-        </interfacename> with HTTP specific functionality. Non-blocking HTTP connections are
-        stateful and not thread-safe. Input / output operations on non-blocking HTTP connections
-        should be restricted to the dispatch events triggered by the I/O event dispatch thread.
-        </para>
-        <section>
-            <title>Execution context of non-blocking HTTP connections</title>
-            <para>
-            Non-blocking HTTP connections are not bound to a particular thread of execution and
-            therefore they need to maintain their own execution context. Each non-blocking HTTP
-            connection has an <interfacename>HttpContext</interfacename> instance associated with
-            it, which can be used to maintain a processing state. The <interfacename>HttpContext
-            </interfacename> instance is thread-safe and can be manipulated from multiple threads.
-            </para>
-            <programlisting><![CDATA[
-DefaultNHttpClientConnection conn = <...>
-Object myStateObject = <...>
-
-HttpContext context = conn.getContext();
-context.setAttribute("state", myStateObject);
-]]></programlisting>
-        </section>
-        <section>
-            <title>Working with non-blocking HTTP connections</title>
-            <para>
-            At any point of time one can obtain the request and response objects currently being
-            transferred over the non-blocking HTTP connection. Any of these objects, or both, can
-            be null if there is no incoming or outgoing message currently being transferred.
-            </para>
-            <programlisting><![CDATA[
-NHttpConnection conn = <...>
-
-HttpRequest request = conn.getHttpRequest();
-if (request != null) {
-    System.out.println("Transferring request: " +
-            request.getRequestLine());
-}
-HttpResponse response = conn.getHttpResponse();
-if (response != null) {
-    System.out.println("Transferring response: " +
-            response.getStatusLine());
-}
-]]></programlisting>
-            <para>
-            However, please note that the current request and the current response may not
-            necessarily represent the same message exchange! Non-blocking HTTP connections can
-            operate in a full duplex mode. One can process incoming and outgoing messages
-            completely independently from one another. This makes non-blocking HTTP connections
-            fully pipelining capable, but at same time implies that this is the job of the protocol
-            handler to match logically related request and the response messages.
-            </para>
-            <para>
-            Over-simplified process of submitting a request on the client side may look like this:
-            </para>
-            <programlisting><![CDATA[
-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", "/");
-
-conn.submitRequest(request);
-System.out.println(conn.isRequestSubmitted());
-]]></programlisting>
-            <para>
-            Over-simplified process of submitting a response on the server side may look like this:
-            </para>
-            <programlisting><![CDATA[
-NHttpServerConnection conn = <...>
-// Obtain execution context
-HttpContext context = conn.getContext();
-// Obtain processing state
-Object state = context.getAttribute("state");
-
-// Generate a response based on the state information
-HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1,
-    HttpStatus.SC_OK, "OK");
-BasicHttpEntity entity = new BasicHttpEntity();
-entity.setContentType("text/plain");
-entity.setChunked(true);
-response.setEntity(entity);
-
-conn.submitResponse(response);
-System.out.println(conn.isResponseSubmitted());
-]]></programlisting>
-            <para>
-            Please note that one should rarely need to transmit messages using these low level
-            methods and should use appropriate higher level HTTP service implementations instead.
-            </para>
-        </section>
-        <section>
-            <title>HTTP I/O control</title>
-            <para>
-            All non-blocking HTTP connections classes implement <interfacename>IOControl
-            </interfacename> interface, which represents a subset of connection functionality for
-            controlling interest in I/O even notifications. <interfacename>IOControl
-            </interfacename> instances are expected to be fully thread-safe. Therefore
-            <interfacename>IOControl</interfacename> can be used to request / suspend I/O event
-            notifications from any thread.
-            </para>
-            <para>
-            One must take special precautions when interacting with non-blocking connections.
-            <interfacename>HttpRequest</interfacename> and <interfacename>HttpResponse
-            </interfacename>are not thread-safe. It is generally advisable that all input / output
-            operations on a non-blocking connection are executed from the I/O event dispatch
-            thread.
-            </para>
-            <para>
-            The following pattern is recommended:
-            </para>
-            <itemizedlist>
-                <listitem>
-                    <para>
-                    Use <interfacename>IOControl</interfacename> interface to pass control over
-                    connection's I/O events to another thread / session.
-                    </para>
-                </listitem>
-                <listitem>
-                    <para>
-                    If input / output operations need be executed on that particular connection,
-                    store all the required information (state) in the connection context and
-                    request the appropriate I/O operation by calling <methodname>
-                    IOControl#requestInput()</methodname> or <methodname>IOControl#requestOutput()
-                    </methodname> method.
-                    </para>
-                </listitem>
-                <listitem>
-                    <para>
-                    Execute the required operations from the event method on the dispatch thread
-                    using information stored in connection context.
-                    </para>
-                </listitem>
-            </itemizedlist>
-            <para>
-            Please note all operations that take place in the event methods should not block for
-            too long, because while the dispatch thread remains blocked in one session, it is
-            unable to process events for all other sessions. I/O operations with the underlying
-            channel of the session are not a problem as they are guaranteed to be non-blocking.
-            </para>
-        </section>
-        <section>
-            <title>Non-blocking content transfer</title>
-            <para>
-            The process of content transfer for non-blocking connections works completely
-            differently compared to that of blocking connections, as non-blocking connections need
-            to accommodate to the asynchronous nature of the NIO model. The main distinction
-            between two types of connections is inability to use the usual, but inherently blocking
-            <classname>java.io.InputStream</classname> and <classname>java.io.OutputStream
-            </classname> classes to represent streams of inbound and outbound content. HttpCore NIO
-            provides <interfacename>ContentEncoder</interfacename> and <interfacename>
-            ContentDecoder</interfacename> interfaces to handle the process of asynchronous content
-            transfer. Non-blocking HTTP connections will instantiate the appropriate implementation
-            of a content codec based on properties of the entity enclosed with the message.
-            </para>
-            <para>
-            Non-blocking HTTP connections will fire input events until the content entity is fully
-            transferred.
-            </para>
-            <programlisting><![CDATA[
-ContentDecoder decoder = <...>
-//Read data in
-ByteBuffer dst = ByteBuffer.allocate(2048);
-decoder.read(dst);
-// Decode will be marked as complete when
-// the content entity is fully transferred
-if (decoder.isCompleted()) {
-    // Done
-}
-]]></programlisting>
-            <para>
-            Non-blocking HTTP connections will fire output events until the content entity is
-            marked as fully transferred.
-            </para>
-            <programlisting><![CDATA[
-ContentEncoder encoder = <...>
-// Prepare output data
-ByteBuffer src = ByteBuffer.allocate(2048);
-// Write data out
-encoder.write(src);
-// Mark content entity as fully transferred when done
-encoder.complete();
-]]></programlisting>
-            <para>
-            Please note, one still has to provide an HttpEntity instance when submitting an entity
-            enclosing message to the non-blocking HTTP connection. Properties of that entity will
-            be used to initialize an <interfacename>ContentEncoder</interfacename> instance to be
-            used for transferring entity content. Non-blocking HTTP connections, however, ignore
-            inherently blocking <methodname>HttpEntity#getContent()</methodname> and <methodname>
-            HttpEntity#writeTo()</methodname> methods of the enclosed entities.
-            </para>
-            <programlisting><![CDATA[
-NHttpServerConnection conn  = <...>
-
-HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1,
-    HttpStatus.SC_OK, "OK");
-BasicHttpEntity entity = new BasicHttpEntity();
-entity.setContentType("text/plain");
-entity.setChunked(true);
-entity.setContent(null);
-response.setEntity(entity);
-
-conn.submitResponse(response);
-]]></programlisting>
-            <para>
-            Likewise, incoming entity enclosing message will have an <interfacename>HttpEntity
-            </interfacename> instance associated with them, but an attempt to call <methodname>
-            HttpEntity#getContent()</methodname> or <methodname>HttpEntity#writeTo()</methodname>
-            methods will cause an <classname>java.lang.IllegalStateException</classname>. The
-            <interfacename>HttpEntity</interfacename> instance can be used to determine properties
-            of the incoming entity such as content length.
-            </para>
-            <programlisting><![CDATA[
-NHttpClientConnection conn = <...>
-
-HttpResponse response = conn.getHttpResponse();
-HttpEntity entity = response.getEntity();
-if (entity != null) {
-    System.out.println(entity.getContentType());
-    System.out.println(entity.getContentLength());
-    System.out.println(entity.isChunked());
-}
-]]></programlisting>
-        </section>
-        <section>
-            <title>Supported non-blocking content transfer mechanisms</title>
-            <para>
-            Default implementations of the non-blocking HTTP connection interfaces support three
-            content transfer mechanisms defined by the HTTP/1.1 specification:
-            </para>
-            <itemizedlist>
-                <listitem>
-                    <formalpara>
-                    <title><literal>Content-Length</literal> delimited:</title>
-                    <para>
-                    The end of the content entity is determined by the value of the
-                    <literal>Content-Length</literal> header. Maximum entity length:
-                    <methodname>Long#MAX_VALUE</methodname>.
-                    </para>
-                    </formalpara>
-                </listitem>
-                <listitem>
-                    <formalpara>
-                    <title>Identity coding:</title>
-                    <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.
-                    </para>
-                    </formalpara>
-                </listitem>
-                <listitem>
-                    <formalpara>
-                    <title>Chunk coding:</title>
-                    <para>
-                    The content is sent in small chunks. Max entity length: unlimited.
-                    </para>
-                    </formalpara>
-                </listitem>
-            </itemizedlist>
-            <para>
-            The appropriate content codec will be created automatically depending on properties of
-            the entity enclosed with the message.
-            </para>
-        </section>
-        <section>
-            <title>Direct channel I/O</title>
-            <para>
-            Content codes are optimized to read data directly from or write data directly to the
-            underlying I/O session's channel, whenever possible avoiding intermediate buffering in
-            a session buffer. Moreover, those codecs that do not perform any content transformation
-            (<literal>Content-Length</literal> delimited and identity codecs, for example) can
-            leverage NIO <classname>java.nio.FileChannel</classname> methods for significantly
-            improved performance of file transfer operations both inbound and outbound.
-            </para>
-            <para>
-            If the actual content decoder implements <interfacename>FileContentDecoder
-            </interfacename> one can make use of its methods to read incoming content directly to a
-            file bypassing an intermediate <classname>java.nio.ByteBuffer</classname>.
-            </para>
-            <programlisting><![CDATA[
-ContentDecoder decoder = <...>
-//Prepare file channel
-FileChannel dst;
-//Make use of direct file I/O if possible
-if (decoder instanceof FileContentDecoder) {
-    long Bytesread = ((FileContentDecoder) decoder)
-        .transfer(dst, 0, 2048);
-     // Decode will be marked as complete when
-     // the content entity is fully transmitted
-     if (decoder.isCompleted()) {
-         // Done
-     }
-}
-]]></programlisting>
-            <para>
-            If the actual content encoder implements <interfacename>FileContentEncoder
-            </interfacename> one can make use of its methods to write outgoing content directly
-            from a file bypassing an intermediate <classname>java.nio.ByteBuffer</classname>.
-            </para>
-            <programlisting><![CDATA[
-ContentEncoder encoder = <...>
-// Prepare file channel
-FileChannel src;
-// Make use of direct file I/O if possible
-if (encoder instanceof FileContentEncoder) {
-    // Write data out
-    long bytesWritten = ((FileContentEncoder) encoder)
-        .transfer(src, 0, 2048);
-    // Mark content entity as fully transferred when done
-    encoder.complete();
-}
-]]></programlisting>
-        </section>
-    </section>
-    <section>
-        <title>HTTP I/O event dispatchers</title>
-        <para>
-        HTTP I/O event dispatchers serve to convert generic I/O events triggered by an I/O reactor
-        to HTTP protocol specific events. They rely on <interfacename>NHttpClientEventHandler
-        </interfacename> and <interfacename>NHttpServerEventHandler</interfacename> interfaces to
-        propagate HTTP protocol events to a HTTP protocol handler.
-        </para>
-        <para>
-        Server side HTTP I/O events as defined by the <interfacename>NHttpServerEventHandler
-        </interfacename> interface:
-        </para>
-        <itemizedlist>
-            <listitem>
-                <formalpara>
-                <title><methodname>connected</methodname>:</title>
-                <para>
-                Triggered when a new incoming connection has been created.
-                </para>
-                </formalpara>
-            </listitem>
-            <listitem>
-                <formalpara>
-                <title><methodname>requestReceived</methodname>:</title>
-                <para>
-                Triggered when a new HTTP request is received. The connection passed as a parameter
-                to this method is guaranteed to return a valid HTTP request object. If the request
-                received encloses a request entity this method will be followed a series of
-                <methodname>inputReady</methodname> events to transfer the request content.
-                </para>
-                </formalpara>
-            </listitem>
-            <listitem>
-                <formalpara>
-                <title><methodname>inputReady</methodname>:</title>
-                <para>
-                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
-                (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
-                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.
-                </para>
-                </formalpara>
-            </listitem>
-            <listitem>
-                <formalpara>
-                <title><methodname>responseReady</methodname>:</title>
-                <para>
-                Triggered when the connection is ready to accept new HTTP response. The protocol
-                handler does not have to submit a response if it is not ready.
-                </para>
-                </formalpara>
-            </listitem>
-            <listitem>
-                <formalpara>
-                <title><methodname>outputReady</methodname>:</title>
-                <para>
-                Triggered when the underlying channel is ready for writing a next portion of the
-                response 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>NHttpServerConnection</interfacename>).
-                </para>
-                <para>
-                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.
-                </para>
-                </formalpara>
-            </listitem>
-            <listitem>
-                <formalpara>
-                <title><methodname>exception</methodname>:</title>
-                <para>
-                Triggered when an I/O error occurrs while reading from or writing to the underlying
-                channel or when an HTTP protocol violation occurs while receiving an HTTP request.
-                </para>
-                </formalpara>
-            </listitem>
-            <listitem>
-                <formalpara>
-                <title><methodname>timeout</methodname>:</title>
-                <para>
-                Triggered when no input is detected on this connection over the maximum period of
-                inactivity.
-                </para>
-                </formalpara>
-            </listitem>
-            <listitem>
-                <formalpara>
-                <title><methodname>closed</methodname>:</title>
-                <para>
-                Triggered when the connection has been closed.
-                </para>
-                </formalpara>
-            </listitem>
-        </itemizedlist>
-        <para>
-        Client side HTTP I/O events as defined by the <interfacename>NHttpClientEventHandler
-        </interfacename> interface:
-        </para>
-        <itemizedlist>
-            <listitem>
-                <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
-                the session request.
-                </para>
-                </formalpara>
-            </listitem>
-            <listitem>
-                <formalpara>
-                <title><methodname>requestReady</methodname>:</title>
-                <para>
-                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>
-            </listitem>
-            <listitem>
-                <formalpara>
-                <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
-                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
-                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.
-                </para>
-                </formalpara>
-            </listitem>
-            <listitem>
-                <formalpara>
-                <title><methodname>responseReceived</methodname>:</title>
-                <para>
-                Triggered when an HTTP response is received. The connection passed as a parameter to
-                this method is guaranteed to return a valid HTTP response object. If the response
-                received encloses a response entity this method will be followed a series of
-                <methodname>inputReady</methodname> events to transfer the response content.
-                </para>
-                </formalpara>
-            </listitem>
-             <listitem>
-                <formalpara>
-                <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
-                (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
-                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.
-                </para>
-                </formalpara>
-            </listitem>
-            <listitem>
-                <formalpara>
-                <title><methodname>exception</methodname>:</title>
-                <para>
-                Triggered when an I/O error occurs while reading from or writing to the underlying
-                channel or when an HTTP protocol violation occurs while receiving an HTTP response.
-                </para>
-                </formalpara>
-            </listitem>
-            <listitem>
-                <formalpara>
-                <title><methodname>timeout</methodname>:</title>
-                <para>
-                Triggered when no input is detected on this connection over the maximum period of
-                inactivity.
-                </para>
-                </formalpara>
-            </listitem>
-            <listitem>
-                <formalpara>
-                <title><methodname>closed</methodname>:</title>
-                <para>
-                Triggered when the connection has been closed.
-                </para>
-                </formalpara>
-            </listitem>
-        </itemizedlist>
-    </section>
-    <section>
-        <title>Non-blocking HTTP content producers</title>
-        <para>
-        As discussed previously the process of content transfer for non-blocking connections works
-        completely differently compared to that for blocking connections. For obvious reasons
-        classic I/O abstraction based on inherently blocking <classname>java.io.InputStream
-        </classname> and <classname>java.io.OutputStream</classname> classes is not well suited
-        for asynchronous data transfer. In order to avoid inefficient and potentially blocking
-        I/O operation redirection through <methodname>java.nio.channels.Channles#newChannel
-        </methodname> non-blocking HTTP entities are expected to implement NIO specific extension
-        interface <interfacename>HttpAsyncContentProducer</interfacename>.
-        </para>
-        <para>
-        The <interfacename>HttpAsyncContentProducer</interfacename> interface defines several
-        additional method for efficient streaming of content to a non-blocking HTTP connection:
-        </para>
-        <itemizedlist>
-            <listitem>
-                <formalpara>
-                <title><methodname>produceContent</methodname>:</title>
-                <para>
-                Invoked to write out a chunk of content to the <interfacename>ContentEncoder
-                </interfacename>. The <interfacename>IOControl</interfacename> interface can be
-                used to suspend output events if the entity is temporarily unable to produce more
-                content. When all content is finished, the producer MUST call
-                <methodname>ContentEncoder#complete()</methodname>. Failure to do so may cause
-                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.
-                </para>
-                </formalpara>
-            </listitem>
-            <listitem>
-                <formalpara>
-                <title><methodname>isRepeatable</methodname>:</title>
-                <para>
-                Determines whether or not this producer is capable of producing its content more
-                than once. Repeatable content producers are expected to be able to recreate
-                their content even after having been closed.
-                </para>
-                </formalpara>
-            </listitem>
-            <listitem>
-                <formalpara>
-                <title><methodname>close</methodname>:</title>
-                <para>
-                Closes the producer and releases all resources currently allocated by it.
-                </para>
-                </formalpara>
-            </listitem>
-        </itemizedlist>
-        <section>
-            <title>Creating non-blocking entities</title>
-            <para>
-            Several HTTP entity implementations included in HttpCore NIO support
-            <interfacename>HttpAsyncContentProducer</interfacename> interface:
-            </para>
-            <itemizedlist>
-                <listitem>
-                    <para>
-                    <link linkend="bytearray-n-entity">
-                        <classname>NByteArrayEntity</classname>
-                    </link>
-                    </para>
-                </listitem>
-                <listitem>
-                    <para>
-                    <link linkend="string-n-entity">
-                        <classname>NStringEntity</classname>
-                    </link>
-                    </para>
-                </listitem>
-                <listitem>
-                    <para>
-                    <link linkend="file-n-entity">
-                        <classname>NFileEntity</classname>
-                    </link>
-                    </para>
-                </listitem>
-            </itemizedlist>
-            <section id="bytearray-n-entity">
-                <title><classname>NByteArrayEntity</classname></title>
-                <para>
-                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[
-NByteArrayEntity entity = new NByteArrayEntity(new byte[] {1, 2, 3});
-]]></programlisting>
-            </section>
-            <section id="string-n-entity">
-                <title><classname>NStringEntity</classname></title>
-                <para>
-                This 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[
-NStringEntity myEntity = new NStringEntity("important message",
-        Consts.UTF_8);
-    ]]></programlisting>
-            </section>
-            <section id="file-n-entity">
-                <title><classname>NFileEntity</classname></title>
-                <para>
-                This entity reads its content body from a file. This class is mostly used to stream
-                large files of different types, so one needs to supply the content type of the file
-                to make sure the content can be correctly recognized and processed by the
-                recipient.
-                </para>
-                <programlisting><![CDATA[
-File staticFile = new File("/path/to/myapp.jar");
-NFileEntity entity = new NFileEntity(staticFile,
-    ContentType.create("application/java-archive", null));
-    ]]></programlisting>
-                <para>
-                The <classname>NHttpEntity</classname> will make use of the direct channel I/O
-                whenever possible, provided the content encoder is capable of transferring data
-                directly from a file to the socket of the underlying connection.
-                </para>
-            </section>
-        </section>
-    </section>
-    <section>
-        <title>Non-blocking HTTP protocol handlers</title>
-        <section>
-            <title>Asynchronous HTTP service</title>
-            <para>
-            <classname>HttpAsyncService</classname> is a fully asynchronous HTTP server side
-            protocol handler based on the non-blocking (NIO) I/O model. <classname>
-            HttpAsyncService</classname> translates individual events fired through the
-            <interfacename>NHttpServerEventHandler</interfacename> interface into logically
-            related HTTP message exchanges.
-            </para>
-            <para>
-            Upon receiving an incoming request the <classname>HttpAsyncService</classname>
-            verifies the message for compliance with the server expectations using <interfacename>
-            HttpAsyncExpectationVerifier</interfacename>, if provided, and then <interfacename>
-            HttpAsyncRequestHandlerResolver</interfacename> is used to resolve the request URI to
-            a particular <interfacename>HttpAsyncRequestHandler</interfacename> intended to handle
-            the request with the given URI. The protocol handler uses the selected <interfacename>
-            HttpAsyncRequestHandler</interfacename> instance to process the incoming request and
-            to generate an outgoing response.
-            </para>
-            <para>
-            <classname>HttpAsyncService</classname> relies on <interfacename>HttpProcessor
-            </interfacename> to generate mandatory protocol headers for all outgoing messages
-            and apply common, cross-cutting message transformations to all incoming and outgoing
-            messages, whereas individual HTTP request handlers are expected to implement
-            application specific content generation and processing.
-            </para>
-            <programlisting><![CDATA[
-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,
-        new DefaultNHttpServerConnectionFactory(ConnectionConfig.DEFAULT));
-ListeningIOReactor ioreactor = new DefaultListeningIOReactor();
-ioreactor.execute(ioEventDispatch);
-]]></programlisting>
-            <section>
-                <title>Non-blocking HTTP request handlers</title>
-                <para>
-                <interfacename>HttpAsyncRequestHandler</interfacename> represents a routine for
-                asynchronous processing of a specific group of non-blocking HTTP requests.
-                Protocol handlers are designed to take care of protocol specific aspects, whereas
-                individual request handlers are expected to take care of application specific HTTP
-                processing. The main purpose of a request handler is to generate a response object
-                with a content entity to be sent back to the client in response to the given
-                request.
-                </para>
-                <programlisting><![CDATA[
-HttpAsyncRequestHandler<HttpRequest> rh = new HttpAsyncRequestHandler<HttpRequest>() {
-
-    public HttpAsyncRequestConsumer<HttpRequest> processRequest(
-            final HttpRequest request,
-            final HttpContext context) {
-        // Buffer request content in memory for simplicity
-        return new BasicAsyncRequestConsumer();
-    }
-
-    public void handle(
-            final HttpRequest request,
-            final HttpAsyncExchange httpexchange,
-            final HttpContext context) throws HttpException, IOException {
-        HttpResponse response = httpexchange.getResponse();
-        response.setStatusCode(HttpStatus.SC_OK);
-        NFileEntity body = new NFileEntity(new File("static.html"),
-                ContentType.create("text/html", Consts.UTF_8));
-        response.setEntity(body);
-        httpexchange.submitResponse(new BasicAsyncResponseProducer(response));
-    }
-
-};
-]]></programlisting>
-                <para>
-                Request handlers must be implemented in a thread-safe manner. Similarly to
-                servlets, request handlers should not use instance variables unless access to those
-                variables are synchronized.
-                </para>
-            </section>
-            <section>
-                <title>Asynchronous HTTP exchange</title>
-                <para>
-                The most fundamental difference of the non-blocking request handlers compared to
-                their blocking counterparts is ability to defer transmission of the HTTP response
-                back to the client without blocking the I/O thread by delegating the process of
-                handling the HTTP request to a worker thread or another service. The instance of
-                <interfacename>HttpAsyncExchange</interfacename> passed as a parameter to the
-                <methodname>HttpAsyncRequestHandler#handle</methodname> method to submit
-                a response as at a later point once response content becomes available.
-                </para>
-                <para>
-                The <interfacename>HttpAsyncExchange</interfacename> interface can be interacted
-                with using the following methods:
-                </para>
-                <itemizedlist>
-                    <listitem>
-                        <formalpara>
-                        <title><methodname>getRequest</methodname>:</title>
-                        <para>
-                        Returns the received HTTP request message.
-                        </para>
-                        </formalpara>
-                    </listitem>
-                    <listitem>
-                        <formalpara>
-                        <title><methodname>getResponse</methodname>:</title>
-                        <para>
-                        Returns the default HTTP response message that can submitted once ready.
-                        </para>
-                        </formalpara>
-                    </listitem>
-                    <listitem>
-                        <formalpara>
-                        <title><methodname>submitResponse</methodname>:</title>
-                        <para>
-                        Submits an HTTP response and completed the message exchange.
-                        </para>
-                        </formalpara>
-                    </listitem>
-                    <listitem>
-                        <formalpara>
-                        <title><methodname>isCompleted</methodname>:</title>
-                        <para>
-                        Determines whether or not the message exchange has been completed.
-                        </para>
-                        </formalpara>
-                    </listitem>
-                    <listitem>
-                        <formalpara>
-                        <title><methodname>setCallback</methodname>:</title>
-                        <para>
-                        Sets <interfacename>Cancellable</interfacename> callback to be invoked
-                        in case the underlying 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.
-                        </para>
-                        </formalpara>
-                    </listitem>
-                    <listitem>
-                        <formalpara>
-                        <title><methodname>setTimeout</methodname>:</title>
-                        <para>
-                        Sets timeout for this message exchange.
-                        </para>
-                        </formalpara>
-                    </listitem>
-                    <listitem>
-                        <formalpara>
-                        <title><methodname>getTimeout</methodname>:</title>
-                        <para>
-                        Returns timeout for this message exchange.
-                        </para>
-                        </formalpara>
-                    </listitem>
-                </itemizedlist>
-                <programlisting><![CDATA[
-HttpAsyncRequestHandler<HttpRequest> rh = new HttpAsyncRequestHandler<HttpRequest>() {
-
-    public HttpAsyncRequestConsumer<HttpRequest> processRequest(
-            final HttpRequest request,
-            final HttpContext context) {
-        // Buffer request content in memory for simplicity
-        return new BasicAsyncRequestConsumer();
-    }
-
-    public void handle(
-            final HttpRequest request,
-            final HttpAsyncExchange httpexchange,
-            final HttpContext context) throws HttpException, IOException {
-
-        new Thread() {
-
-            @Override
-            public void run() {
-                try {
-                    Thread.sleep(10);
-                }
-                catch(InterruptedException ie) {}
-                HttpResponse response = httpexchange.getResponse();
-                response.setStatusCode(HttpStatus.SC_OK);
-                NFileEntity body = new NFileEntity(new File("static.html"),
-                        ContentType.create("text/html", Consts.UTF_8));
-                response.setEntity(body);
-                httpexchange.submitResponse(new BasicAsyncResponseProducer(response));
-            }
-        }.start();
-
-    }
-
-};
-]]></programlisting>
-                <para>
-                Please note <interfacename>HttpResponse</interfacename> instances are not
-                thread-safe and may not be modified concurrently. Non-blocking request handlers
-                must ensure HTTP response cannot be accessed by more than one thread at a time.
-                </para>
-            </section>
-            <section>
-                <title>Asynchronous HTTP request consumer</title>
-                <para>
-                <interfacename>HttpAsyncRequestConsumer</interfacename> facilitates the process of
-                asynchronous processing of HTTP requests. It is a callback interface used by
-                <interfacename>HttpAsyncRequestHandler</interfacename>s to process an incoming
-                HTTP request message and to stream its content from a non-blocking server side
-                HTTP connection.
-                </para>
-                <para>
-                HTTP I/O events and methods as defined by the <interfacename>
-                HttpAsyncRequestConsumer</interfacename> interface:
-                </para>
-                <itemizedlist>
-                    <listitem>
-                        <formalpara>
-                        <title><methodname>requestReceived</methodname>:</title>
-                        <para>
-                        Invoked when a HTTP request message is received.
-                        </para>
-                        </formalpara>
-                    </listitem>
-                    <listitem>
-                        <formalpara>
-                        <title><methodname>consumeContent</methodname>:</title>
-                        <para>
-                        Invoked to process a chunk of content from the <interfacename>
-                        ContentDecoder</interfacename>. The <interfacename>IOControl
-                        </interfacename> interface can be used to suspend input events if
-                        the consumer is temporarily unable to consume more content.
-                        </para>
-                        <para>
-                        The consumer can use the <methodname>ContentDecoder#isCompleted()
-                        </methodname> method to find out whether or not the message content
-                        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
-                        when the consumer is capable of processing more content.
-                        </para>
-                        <para>
-                        This event is invoked only if the incoming request message has
-                        a content entity enclosed in it.
-                        </para>
-                        </formalpara>
-                    </listitem>
-                    <listitem>
-                        <formalpara>
-                        <title><methodname>requestCompleted</methodname>:</title>
-                        <para>
-                        Invoked to signal that the request has been fully processed.
-                        </para>
-                        </formalpara>
-                    </listitem>
-                    <listitem>
-                        <formalpara>
-                        <title><methodname>failed</methodname>:</title>
-                        <para>
-                        Invoked to signal that the request processing terminated abnormally.
-                        </para>
-                        </formalpara>
-                    </listitem>
-                    <listitem>
-                        <formalpara>
-                        <title><methodname>getException</methodname>:</title>
-                        <para>
-                        Returns an exception in case of an abnormal termination. This method
-                        returns <code>null</code> if the request execution is still ongoing or if
-                        it completed successfully.
-                        </para>
-                        </formalpara>
-                    </listitem>
-                    <listitem>
-                        <formalpara>
-                        <title><methodname>getResult</methodname>:</title>
-                        <para>
-                        Returns a result of the request execution, when available. This method
-                        returns <code>null</code> if the request execution is still ongoing.
-                        </para>
-                        </formalpara>
-                    </listitem>
-                    <listitem>
-                        <formalpara>
-                        <title><methodname>isDone</methodname>:</title>
-                        <para>
-                        Determines whether or not the request execution completed. If the
-                        request processing terminated normally <methodname>getResult()</methodname>
-                        can be used to obtain the result. If the request processing terminated
-                        abnormally <methodname>getException()</methodname> can be used to obtain
-                        the cause.
-                        </para>
-                        </formalpara>
-                    </listitem>
-                    <listitem>
-                        <formalpara>
-                        <title><methodname>close</methodname>:</title>
-                        <para>
-                        Closes the consumer and releases all resources currently allocated by it.
-                        </para>
-                        </formalpara>
-                    </listitem>
-                </itemizedlist>
-                <para>
-                <interfacename>HttpAsyncRequestConsumer</interfacename> implementations are
-                expected to be thread-safe.
-                </para>
-                <para>
-                <classname>BasicAsyncRequestConsumer</classname> is a very basic implementation
-                of the <interfacename>HttpAsyncRequestConsumer</interfacename> interface shipped
-                with the library. Please note that this consumer buffers request content in memory and
-                therefore should be used for relatively small request messages.
-                </para>
-            </section>
-            <section>
-                <title>Asynchronous HTTP response producer</title>
-                <para>
-                <interfacename>HttpAsyncResponseProducer</interfacename> facilitates the process of
-                asynchronous generation of HTTP responses. It is a callback interface used by
-                <interfacename>HttpAsyncRequestHandler</interfacename>s to generate an HTTP response
-                message and to stream its content to a non-blocking server side HTTP connection.
-                </para>
-                <para>
-                HTTP I/O events and methods as defined by the
-                <interfacename>HttpAsyncResponseProducer</interfacename> interface:
-                </para>
-                <itemizedlist>
-                    <listitem>
-                        <formalpara>
-                        <title><methodname>generateResponse</methodname>:</title>
-                        <para>
-                        Invoked to generate a HTTP response message header.
-                        </para>
-                        </formalpara>
-                    </listitem>
-                    <listitem>
-                        <formalpara>
-                        <title><methodname>produceContent</methodname>:</title>
-                        <para>
-                        Invoked to write out a chunk of content to the <interfacename>
-                        ContentEncoder</interfacename>. The <interfacename>IOControl
-                        </interfacename> interface can be used to suspend output events if
-                        the producer is temporarily unable to produce more content.
-                        </para>
-                        <para>
-                        When all content is finished, the producer MUST call <methodname>
-                        ContentEncoder#complete()</methodname>. Failure to do so may cause
-                        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.
-                        </para>
-                        <para>
-                        This event is invoked only for if the outgoing response message has
-                        a content entity enclosed in it, that is <methodname>
-                        HttpResponse#getEntity()</methodname> returns <code>null</code>.
-                        </para>
-                        </formalpara>
-                    </listitem>
-                    <listitem>
-                        <formalpara>
-                        <title><methodname>responseCompleted</methodname>:</title>
-                        <para>
-                        Invoked to signal that the response has been fully written out.
-                        </para>
-                        </formalpara>
-                    </listitem>
-                    <listitem>
-                        <formalpara>
-                        <title><methodname>failed</methodname>:</title>
-                        <para>
-                        Invoked to signal that the response processing terminated abnormally.
-                        </para>
-                        </formalpara>
-                    </listitem>
-                    <listitem>
-                        <formalpara>
-                        <title><methodname>close</methodname>:</title>
-                        <para>
-                        Closes the producer and releases all resources currently allocated by it.
-                        </para>
-                        </formalpara>
-                    </listitem>
-                </itemizedlist>
-                <para>
-                <interfacename>HttpAsyncResponseProducer</interfacename> implementations are
-                expected to be thread-safe.
-                </para>
-                <para>
-                <classname>BasicAsyncResponseProducer</classname> is a basic implementation
-                of the <interfacename>HttpAsyncResponseProducer</interfacename> interface shipped
-                with the library. The producer can make use of the <interfacename>
-                HttpAsyncContentProducer</interfacename> interface to efficiently stream out
-                message content to a non-blocking HTTP connection, if it is implemented by the
-                <interfacename>HttpEntity</interfacename> enclosed in the response.
-                </para>
-            </section>
-            <section>
-                <title>Non-blocking request handler resolver</title>
-                <para>
-                The management of non-blocking HTTP request handlers is quite similar to that of
-                blocking HTTP request handlers. Usually an instance of <interfacename>
-                HttpAsyncRequestHandlerResolver</interfacename> is used to maintain a registry of
-                request handlers and to matches a request URI to a particular request handler.
-                HttpCore includes only a very simple implementation of the request handler resolver
-                based on a trivial pattern matching algorithm: <classname>
-                HttpAsyncRequestHandlerRegistry</classname> supports only three formats:
-                <literal>*</literal>, <literal>&lt;uri&gt;*</literal> and
-                <literal>*&lt;uri&gt;</literal>.
-                </para>
-                <programlisting><![CDATA[
-HttpAsyncRequestHandler<?> myRequestHandler1 = <...>
-HttpAsyncRequestHandler<?> myRequestHandler2 = <...>
-HttpAsyncRequestHandler<?> myRequestHandler3 = <...>
-UriHttpAsyncRequestHandlerMapper handlerReqistry =
-        new UriHttpAsyncRequestHandlerMapper();
-handlerReqistry.register("/service/*", myRequestHandler1);
-handlerReqistry.register("*.do", myRequestHandler2);
-handlerReqistry.register("*", myRequestHandler3);
-]]></programlisting>
-                <para>
-                Users are encouraged to provide more sophisticated implementations of
-                <interfacename>HttpAsyncRequestHandlerResolver</interfacename>, for instance, based
-                on regular expressions.
-                </para>
-            </section>
-        </section>
-        <section>
-            <title>Asynchronous HTTP request executor</title>
-            <para>
-            <classname>HttpAsyncRequestExecutor</classname> is a fully asynchronous client side
-            HTTP protocol handler based on the NIO (non-blocking) I/O model. <classname>
-            HttpAsyncRequestExecutor</classname> translates individual events fired through the
-            <interfacename>NHttpClientEventHandler</interfacename> interface into logically
-            related HTTP message exchanges.
-            </para>
-            <para>
-            <classname>HttpAsyncRequestExecutor</classname> relies on <interfacename>
-            HttpAsyncRequestExecutionHandler</interfacename> to implement application specific
-            content generation and processing and to handle logically related series of HTTP
-            request / response exchanges, which may also span across multiple connections.
-            <interfacename>HttpProcessor</interfacename> provided by the <interfacename>
-            HttpAsyncRequestExecutionHandler</interfacename> instance will be used to generate
-            mandatory protocol headers for all outgoing messages and apply common, cross-cutting
-            message transformations to all incoming and outgoing messages. The caller is expected
-            to pass an instance of <interfacename>HttpAsyncRequestExecutionHandler</interfacename>
-            to be used for the next series of HTTP message exchanges through the connection
-            context using <methodname>HttpAsyncRequestExecutor#HTTP_HANDLER</methodname> attribute.
-            HTTP exchange sequence is considered complete when the <methodname>
-            HttpAsyncRequestExecutionHandler#isDone()</methodname> method returns <code>true</code>.
-            </para>
-            <programlisting><![CDATA[
-HttpAsyncRequestExecutor ph = new HttpAsyncRequestExecutor();
-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
-            away low level details of <interfacename>HttpAsyncRequestExecutionHandler
-            </interfacename> management. Please note <classname>HttpAsyncRequester</classname>
-            supports single HTTP request / response exchanges only. It does not support HTTP
-            authentication and does not handle redirects automatically.
-            </para>
-            <programlisting><![CDATA[
-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"),
-                new BasicHttpRequest("GET", "/")),
-        new BasicAsyncResponseConsumer(),
-        conn);
-HttpResponse response = future.get();
-]]></programlisting>
-            <section>
-                <title>Asynchronous HTTP request producer</title>
-                <para>
-                <interfacename>HttpAsyncRequestProducer</interfacename> facilitates the process of
-                asynchronous generation of HTTP requests. It is a callback interface whose methods
-                get invoked to generate an HTTP request message and to stream message content to
-                a non-blocking client side HTTP connection.
-                </para>
-                <para>
-                Repeatable request producers capable of generating the same request message more
-                than once can be reset to their initial state by calling the <methodname>
-                resetRequest()</methodname> 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.
-                </para>
-                <para>
-                HTTP I/O events and methods as defined by the
-                <interfacename>HttpAsyncRequestProducer</interfacename> interface:
-                </para>
-                <itemizedlist>
-                    <listitem>
-                        <formalpara>
-                        <title><methodname>getTarget</methodname>:</title>
-                        <para>
-                        Invoked to obtain the request target host.
-                        </para>
-                        </formalpara>
-                    </listitem>
-                    <listitem>
-                        <formalpara>
-                        <title><methodname>generateRequest</methodname>:</title>
-                        <para>
-                        Invoked to generate a HTTP request message header. The message is expected
-                        to implement the <interfacename>HttpEntityEnclosingRequest</interfacename>
-                        interface if it is to enclose a content entity.
-                        </para>
-                        </formalpara>
-                    </listitem>
-                    <listitem>
-                        <formalpara>
-                        <title><methodname>produceContent</methodname>:</title>
-                        <para>
-                        Invoked to write out a chunk of content to the <interfacename>
-                        ContentEncoder</interfacename>. The <interfacename>IOControl
-                        </interfacename> interface can be used to suspend output events if
-                        the producer is temporarily unable to produce more content.
-                        </para>
-                        <para>
-                        When all content is finished, the producer MUST call <methodname>
-                        ContentEncoder#complete()</methodname>. Failure to do so may cause
-                        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.
-                        </para>
-                        <para>
-                        This event is invoked only for if the outgoing request message has
-                        a content entity enclosed in it, that is <methodname>
-                        HttpEntityEnclosingRequest#getEntity()</methodname> returns <code>null
-                        </code>.
-                        </para>
-                        </formalpara>
-                    </listitem>
-                    <listitem>
-                        <formalpara>
-                        <title><methodname>requestCompleted</methodname>:</title>
-                        <para>
-                        Invoked to signal that the request has been fully written out.
-                        </para>
-                        </formalpara>
-                    </listitem>
-                    <listitem>
-                        <formalpara>
-                        <title><methodname>failed</methodname>:</title>
-                        <para>
-                        Invoked to signal that the request processing terminated abnormally.
-                        </para>
-                        </formalpara>
-                    </listitem>
-                    <listitem>
-                        <formalpara>
-                        <title><methodname>resetRequest</methodname>:</title>
-                        <para>
-                        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.
-                        </para>
-                        </formalpara>
-                    </listitem>
-                    <listitem>
-                        <formalpara>
-                        <title><methodname>close</methodname>:</title>
-                        <para>
-                        Closes the producer and releases all resources currently allocated by it.
-                        </para>
-                        </formalpara>
-                    </listitem>
-                </itemizedlist>
-                <para>
-                <interfacename>HttpAsyncRequestProducer</interfacename> implementations are
-                expected to be thread-safe.
-                </para>
-                <para>
-                <classname>BasicAsyncRequestProducer</classname> is a basic implementation
-                of the <interfacename>HttpAsyncRequestProducer</interfacename> interface shipped
-                with the library. The producer can mak

<TRUNCATED>