/// <summary>
        /// Continues receiving and processing of the message in half-sync mode.
        /// </summary>
        /// <param name="socketAsObject">The connection.</param>
        private void Pool_Server_ContinueHalfSyncReceiving(object socketAsObject)
        {
            BinaryLogWriter binaryLogWriter = this.ITransportContext.BinaryLogWriter;

            XHttpConnection xHttpConnection = null;
            XHttpPhysicalConnection xHttpPhysicalConnection = null;
            Socket socket = (Socket) socketAsObject;

            byte protocolVersion;
            string remoteUri = null;
            int sequenceNo = 0;
            GenuineConnectionType genuineConnectionType = GenuineConnectionType.None;
            Guid hostId = Guid.Empty;
            HttpPacketType httpPacketType = HttpPacketType.Unkown;
            string connectionName;
            int remoteHostUniqueIdentifier;

            try
            {
                // server & sender - parse messages, execute them, send confirmation
                // server & listener - if messages are available, send them all. otherwise set available flag and hold the connection for a while

                // first, read the header
                Stream inputStream = this.LowLevel_ParseHttpContent(GenuineUtility.GetTimeout(GenuineUtility.ConvertToMilliseconds(this.ITransportContext.IParameterProvider[GenuineParameter.XHttpReadHttpMessageTimeout])),
                    false, socket, null, out protocolVersion, out remoteUri, out sequenceNo, out genuineConnectionType, out hostId, out httpPacketType, out connectionName, out remoteHostUniqueIdentifier);

                // who it was
                HostInformation remote = this.ITransportContext.KnownHosts["_ghttp://" + hostId.ToString("N")];
                remote.UpdateUri(remote.Uri, remoteHostUniqueIdentifier);
                remote.ProtocolVersion = protocolVersion;

                // get the connection
                lock (remote.PersistentConnectionEstablishingLock)
                {
                    xHttpConnection = this._persistent.Get(remote.Uri, connectionName) as XHttpConnection;

                    if (httpPacketType == HttpPacketType.Establishing_ResetConnection && xHttpConnection != null)
                    {
                        xHttpConnection.Dispose(GenuineExceptions.Get_Receive_ConnectionClosed("The connection was closed by HttpPacketType.Establishing_ResetConnection client request."));
                        xHttpConnection = null;
                    }

                    if (xHttpConnection == null)
                    {
                        using (new ReaderAutoLocker(this._disposeLock))
                        {
                            if (this._disposed)
                                throw OperationException.WrapException(this._disposeReason);

                            // provide a possibility to decline the connection
                            ConnectionAcceptedCancellableEventParameter connectionAcceptedCancellableEventParameter = new ConnectionAcceptedCancellableEventParameter();
                            connectionAcceptedCancellableEventParameter.Socket = socket;
                            connectionAcceptedCancellableEventParameter.IPEndPoint = (IPEndPoint) socket.RemoteEndPoint;
                            this.ITransportContext.IGenuineEventProvider.Fire(new GenuineEventArgs(GenuineEventType.GHttpConnectionAccepted, null, null, connectionAcceptedCancellableEventParameter));
                            if (connectionAcceptedCancellableEventParameter.Cancel)
                                throw GenuineExceptions.Get_Connect_CanNotAcceptIncomingConnection("Connection accepting was cancelled by the event consumer.");

                            xHttpConnection = this.Pool_CreateConnection(remote, remote.Uri, false, connectionName);
                        }
                    }
                }

                bool theSamePacketIsRequested;

                lock (xHttpConnection.Listener.PhysicalConnectionStateLock)
                {
                    if (httpPacketType == HttpPacketType.Listening)
                    {
                        // if there is an already registered listener request - release it
                        if (xHttpConnection.Listener.ConnectionAvailable && xHttpConnection.Listener.Socket != socket)
                        {
                            // shut down the previous physical connection
                            this.LowLevel_SendServerError(new PhysicalConnectionAndSocket(xHttpConnection.Listener, socket));
            //							GenuineThreadPool.QueueUserWorkItem(new WaitCallback(this.LowLevel_SendServerError), new PhysicalConnectionAndSocket(xHttpConnection.Listener, socket), true);
                            xHttpConnection.Listener.AcquireIfAvailable();
                        }

                        xHttpConnection.Listener.Socket = socket;
                        xHttpPhysicalConnection = xHttpConnection.Listener;
                    }
                    else
                    {
                        xHttpConnection.Sender.Socket = socket;
                        xHttpPhysicalConnection = xHttpConnection.Sender;
                    }

                    theSamePacketIsRequested = xHttpPhysicalConnection.SequenceNo == sequenceNo && xHttpPhysicalConnection.SentContent != null;

            #if DEBUG
                    xHttpPhysicalConnection.TypeOfSocket = "Accepted";
            #endif

                    xHttpPhysicalConnection.Remote.PhysicalAddress = socket.RemoteEndPoint;
                    xHttpPhysicalConnection.Remote.LocalPhysicalAddress = socket.LocalEndPoint;
                }	// lock (xHttpConnection.Listener.PhysicalConnectionStateLock)

                // renew connection lifetime
                xHttpConnection.Renew();
                xHttpPhysicalConnection.XHttpConnection.SignalState(GenuineEventType.GeneralConnectionEstablished, null, null);

                // if the same packet stream is requested, send the response
                if (theSamePacketIsRequested)
                {
                    // skip the current stream
                    inputStream.Close();

                    // send the stream and initiate receiving
                    this.LowLevel_SendHttpContent(remote.ExpireTime, null, null, null, null, xHttpPhysicalConnection, genuineConnectionType, HttpPacketType.RequestRepeated, true, true, true, true);
                    return ;
                }

                lock (xHttpConnection.Listener.PhysicalConnectionStateLock)
                {
                    // if desynchronization, report and continue
                    if (httpPacketType != HttpPacketType.Establishing_ResetConnection && xHttpPhysicalConnection.SequenceNo > sequenceNo || sequenceNo > xHttpPhysicalConnection.SequenceNo + 1)
                    {
                        // LOG:
                        if ( binaryLogWriter != null && binaryLogWriter[LogCategory.Connection] > 0 )
                        {
                            binaryLogWriter.WriteEvent(LogCategory.Connection, "XHttpConnectionManager.Pool_Server_ContinueHalfSyncreceiving",
                                LogMessageType.ConnectionStreamDesynchronization, GenuineExceptions.Get_Debugging_GeneralWarning("Stream desynchronization."),
                                null, xHttpPhysicalConnection.Remote, null,
                                GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name,
                                xHttpPhysicalConnection.ConnectionLevelSecurity, xHttpPhysicalConnection.ConnectionLevelSecurity == null ? null : xHttpPhysicalConnection.ConnectionLevelSecurity.Name,
                                xHttpConnection.DbgConnectionId, 0, 0, 0, null, null, null, null,
                                "Stream desynchronization error. Received sequence number: {0}. Expected sequence number: {1}.", xHttpPhysicalConnection.SequenceNo, sequenceNo);
                        }

                        // send the stream and initiate receiving
                        this.LowLevel_SendHttpContent(remote.ExpireTime, null, null, null, null, xHttpPhysicalConnection, genuineConnectionType, HttpPacketType.Desynchronization, false, true, true, true);
                        return ;
                    }

                    // the next sequence is requested
                    if (xHttpPhysicalConnection.SentContent != null)
                    {
                        // release the content
                        xHttpPhysicalConnection.SentContent.Close();
                        xHttpPhysicalConnection.SentContent = null;
                    }

                    // respond with the same seq No
                    xHttpPhysicalConnection.SequenceNo = sequenceNo;
                    xHttpPhysicalConnection.Socket = socket;
                    xHttpPhysicalConnection.MessagesBeingSent.Clear();
                }

                // LOG:
                if ( binaryLogWriter != null && binaryLogWriter[LogCategory.Connection] > 0 )
                {
                    binaryLogWriter.WriteEvent(LogCategory.Connection, "XHttpConnectionManager.Pool_Server_ContinueHalfSyncreceiving",
                        LogMessageType.ReceivingFinished, null,
                        null, xHttpPhysicalConnection.Remote, null,
                        GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name,
                        xHttpPhysicalConnection.ConnectionLevelSecurity, xHttpPhysicalConnection.ConnectionLevelSecurity == null ? null : xHttpPhysicalConnection.ConnectionLevelSecurity.Name,
                        xHttpConnection.DbgConnectionId, 0, 0, 0, null, null, null, null,
                        "HTTP Stream received. Packet type: {0}.", Enum.Format(typeof(HttpPacketType), httpPacketType, "g"));
                }

                // analyze the type of the packet
                switch(httpPacketType)
                {
                    case HttpPacketType.Establishing_ResetConnection:
                    case HttpPacketType.Establishing:
                        // mark the remote host as client
                        lock (remote.PersistentConnectionEstablishingLock)
                            remote.GenuinePersistentConnectionState = GenuinePersistentConnectionState.Accepted;

                        // read CLSS streams
                        BinaryReader binaryReader = new BinaryReader(inputStream);
                        Stream clsseStream = null;
                        GenuineChunkedStream outputStream = new GenuineChunkedStream(false);

                        // process the sender info
                        int writtenSize = binaryReader.ReadInt32();

                        using (new GenuineChunkedStreamSizeLabel(outputStream))
                        {
                            if (xHttpConnection.Sender.ConnectionLevelSecurity != null && ! xHttpConnection.Sender.ConnectionLevelSecurity.IsEstablished)
                            {
                                using (Stream clssData = new DelimiterStream(inputStream, writtenSize))
                                {
                                    clsseStream = xHttpConnection.Sender.ConnectionLevelSecurity.EstablishSession(clssData, true);
                                }
                            }

                            if (clsseStream != null)
                                GenuineUtility.CopyStreamToStream(clsseStream, outputStream);
                        }

                        // process the listener info
                        writtenSize = binaryReader.ReadInt32();
                        using (new GenuineChunkedStreamSizeLabel(outputStream))
                        {
                            if (xHttpConnection.Listener.ConnectionLevelSecurity != null && ! xHttpConnection.Listener.ConnectionLevelSecurity.IsEstablished)
                            {
                                using (Stream clssData = new DelimiterStream(inputStream, writtenSize))
                                {
                                    clsseStream = xHttpConnection.Listener.ConnectionLevelSecurity.EstablishSession(clssData, true);
                                }
                            }

                            if (clsseStream != null)
                                GenuineUtility.CopyStreamToStream(clsseStream, outputStream);
                        }

                        // skip remaining part of the packet
                        inputStream.Close();

                        this.LowLevel_SendHttpContent(remote.ExpireTime, null, outputStream, null, null, xHttpPhysicalConnection,
                            genuineConnectionType, httpPacketType, false, true, true, false);
                        break;

                    case HttpPacketType.Listening:
                        // if messages are available, send them immediately
                        // otherwise put the connection off for a while

                        // skip the remaining content
                        inputStream.Close();
                        Pool_Server_ProcessListenerRequest(xHttpConnection, xHttpPhysicalConnection);
                        break;

                    case HttpPacketType.Usual:
                        // apply CLSS if it was established
                        if (xHttpPhysicalConnection.ConnectionLevelSecurity != null)
                            inputStream = xHttpPhysicalConnection.ConnectionLevelSecurity.Decrypt(inputStream);
                        Pool_Server_ProcessSenderRequest(xHttpConnection, xHttpPhysicalConnection, inputStream);
                        break;

                    default:
                        throw GenuineExceptions.Get_Receive_IncorrectData("Unexpected type of the packet.");
                }
            }
            catch(Exception ex)
            {
                try
                {
                    // LOG:
                    if ( binaryLogWriter != null && binaryLogWriter[LogCategory.Connection] > 0 )
                    {
                        binaryLogWriter.WriteEvent(LogCategory.Connection, "XHttpConnectionManager.Pool_Server_ContinueHalfSyncreceiving",
                            LogMessageType.ReceivingFinished, ex,
                            null, xHttpPhysicalConnection.Remote, null,
                            GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name,
                            xHttpPhysicalConnection.ConnectionLevelSecurity, xHttpPhysicalConnection.ConnectionLevelSecurity == null ? null : xHttpPhysicalConnection.ConnectionLevelSecurity.Name,
                            xHttpConnection.DbgConnectionId, 0, 0, 0, null, null, null, null,
                            "Error occurred while receiving HTTP Stream. Sequence No: {0}. Connection type: {1}. Packet type: {2}.",
                            sequenceNo, genuineConnectionType, httpPacketType);
                    }

                    SocketUtility.CloseSocket(socket);
                }
                catch
                {
                }
            }
        }
        /// <summary>
        /// Handles the incoming HTTP request.
        /// </summary>
        /// <param name="httpServerRequestResultAsObject">The HTTP request.</param>
        public void HandleIncomingRequest(object httpServerRequestResultAsObject)
        {
            BinaryLogWriter binaryLogWriter = this.ITransportContext.BinaryLogWriter;

            HttpServerRequestResult httpServerRequestResult = (HttpServerRequestResult) httpServerRequestResultAsObject;
            HttpServerConnection httpServerConnection = null;
            bool postponeResponse = false;

            try
            {
                // get the stream
                HttpRequest httpRequest = httpServerRequestResult.HttpContext.Request;
                Stream incomingStream = httpRequest.InputStream;

                if (incomingStream.Length <= 0)
                {
                    // LOG:
                    if ( binaryLogWriter != null && binaryLogWriter[LogCategory.LowLevelTransport] > 0 )
                    {
                        binaryLogWriter.WriteEvent(LogCategory.Connection, "HttpServerConnectionManager.HandleIncomingRequest",
                            LogMessageType.LowLevelTransport_AsyncReceivingCompleted, null, null, null, null,
                            GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, null, null,
                            -1, 0, 0, 0, null, null, null, null,
                            "Empty content has been received. It will be ignored.");
                    }

                    return ;
                }

                // LOG:
                if ( binaryLogWriter != null && binaryLogWriter[LogCategory.LowLevelTransport] > 0 )
                {
                    bool writeContent = binaryLogWriter[LogCategory.LowLevelTransport] > 1;
                    GenuineChunkedStream content = null;
                    if (writeContent)
                    {
                        content = new GenuineChunkedStream(false);
                        GenuineUtility.CopyStreamToStream(incomingStream, content);
                    }

                    binaryLogWriter.WriteTransportContentEvent(LogCategory.LowLevelTransport, "HttpServerConnectionManager.HandleIncomingRequest",
                        LogMessageType.LowLevelTransport_AsyncReceivingCompleted, null, null, null,
                        writeContent ? content : null,
                        GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, -1, (int) httpServerRequestResult.HttpContext.Request.ContentLength,
                        httpServerRequestResult.HttpContext.Request.UserHostAddress,
                        null, null,
                        "HTTP request has been received.");

                    if (writeContent)
                        incomingStream = content;
                }

                BinaryReader binaryReader = new BinaryReader(incomingStream);

                // read the header
                byte protocolVersion;
                GenuineConnectionType genuineConnectionType;
                Guid hostId;
                HttpPacketType httpPacketType;
                int sequenceNo;
                string connectionName;
                int remoteHostUniqueIdentifier;
                HttpMessageCoder.ReadRequestHeader(binaryReader, out protocolVersion, out genuineConnectionType, out hostId, out httpPacketType, out sequenceNo, out connectionName, out remoteHostUniqueIdentifier);

                HostInformation remote = this.ITransportContext.KnownHosts["_ghttp://" + hostId.ToString("N")];
                remote.ProtocolVersion = protocolVersion;
            //				remote.Renew(this._hostRenewingSpan, false);
                remote.PhysicalAddress = httpRequest.UserHostAddress;

                // raise an event if we were not recognized
                remote.UpdateUri(remote.Uri, remoteHostUniqueIdentifier);

                // LOG:
                if ( binaryLogWriter != null && binaryLogWriter[LogCategory.Connection] > 0 )
                {
                    binaryLogWriter.WriteEvent(LogCategory.Connection, "HttpServerConnectionManager.HandleIncomingRequest",
                        LogMessageType.ReceivingFinished, null, null, remote, null,
                        GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, null, null, -1,
                        0, 0, 0, null, null, null, null,
                        "HTTP request is being processed. Packet type: {0}. Sequence no: {1}. Content length: {2}. Host address: {3}.",
                        Enum.Format(typeof(HttpPacketType), httpPacketType, "g"), sequenceNo, httpRequest.ContentLength, httpRequest.UserHostAddress);
                }

                // prepare the output stream
                GenuineChunkedStream outputStream = new GenuineChunkedStream(false);
                BinaryWriter binaryWriter = new BinaryWriter(outputStream);
                HttpMessageCoder.WriteResponseHeader(binaryWriter, protocolVersion, this.ITransportContext.ConnectionManager.Local.Uri, sequenceNo, httpPacketType, remote.LocalHostUniqueIdentifier);

                // analyze the received packet
                switch(genuineConnectionType)
                {
                    case GenuineConnectionType.Persistent:
                    {
                        // get the server connection
                        lock (remote.PersistentConnectionEstablishingLock)
                        {
                            httpServerConnection = this._persistent.Get(remote.Uri, connectionName) as HttpServerConnection;
                            if (httpServerConnection != null && httpServerConnection._disposed)
                                httpServerConnection = null;

                            // initialize CLSS from the very beginning, if necessary
                            if (httpPacketType == HttpPacketType.Establishing_ResetConnection)
                            {
                                if (httpServerConnection != null)
                                    httpServerConnection.Dispose(GenuineExceptions.Get_Receive_ConnectionClosed("Client sends Establishing_ResetCLSS flag."));
                                httpServerConnection = null;
                            }

                            if (httpServerConnection == null)
                            {
                                // create the new connection
                                httpServerConnection = new HttpServerConnection(this.ITransportContext, hostId, remote, connectionName,
                                    GenuineUtility.ConvertToMilliseconds(this.ITransportContext.IParameterProvider[GenuineParameter.ClosePersistentConnectionAfterInactivity]) + GenuineUtility.ConvertToMilliseconds(this.ITransportContext.IParameterProvider[GenuineParameter.MaxTimeSpanToReconnect]));

                                if ( binaryLogWriter != null && binaryLogWriter[LogCategory.Connection] > 0 )
                                {
                                    binaryLogWriter.WriteConnectionParameterEvent(LogCategory.Connection, "HttpServerConnectionManager.HandleIncomingRequest",
                                        LogMessageType.ConnectionParameters, null, remote, this.ITransportContext.IParameterProvider,
                                        GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, httpServerConnection.DbgConnectionId,
                                        "HTTP connection is being established.");
                                }

                                this._persistent.Set(remote.Uri, connectionName, httpServerConnection);

                                // and CLSS
                                string securitySessionName = this.ITransportContext.IParameterProvider[GenuineParameter.SecuritySessionForPersistentConnections] as string;
                                if (securitySessionName != null)
                                {
                                    httpServerConnection.Sender_SecuritySession = this.ITransportContext.IKeyStore.GetKey(securitySessionName).CreateSecuritySession(securitySessionName, null);
                                    httpServerConnection.Listener_SecuritySession = this.ITransportContext.IKeyStore.GetKey(securitySessionName).CreateSecuritySession(securitySessionName, null);
                                }

                                // LOG:
                                if ( binaryLogWriter != null && binaryLogWriter[LogCategory.Connection] > 0 )
                                {
                                    binaryLogWriter.WriteEvent(LogCategory.Connection, "HttpServerConnectionManager.HandleIncomingRequest",
                                        LogMessageType.ConnectionEstablished, null, null, remote, null,
                                        GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, httpServerConnection.Sender_SecuritySession, securitySessionName,
                                        httpServerConnection.DbgConnectionId, (int) GenuineConnectionType.Persistent, 0, 0, this.GetType().Name, null, null, null,
                                        "The connection is being established.");
                                }

                                // LOG:
                                if ( binaryLogWriter != null && binaryLogWriter[LogCategory.HostInformation] > 0 )
                                {
                                    binaryLogWriter.WriteHostInformationEvent("HttpServerConnectionManager.HandleIncomingRequest",
                                        LogMessageType.HostInformationCreated, null, remote,
                                        GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, httpServerConnection.Sender_SecuritySession,
                                        securitySessionName, httpServerConnection.DbgConnectionId,
                                        "HostInformation is ready for actions.");
                                }

                                this.ITransportContext.IGenuineEventProvider.Fire(new GenuineEventArgs(GenuineEventType.GHttpConnectionAccepted, null, remote, httpRequest.UserHostAddress));
                            }
                        }

                        httpServerConnection.Renew();
                        httpServerConnection.SignalState(GenuineEventType.GeneralConnectionEstablished, null, null);

                        switch(httpPacketType)
                        {
                            case HttpPacketType.Establishing_ResetConnection:
                            case HttpPacketType.Establishing:
                                Stream clsseStream = Stream.Null;

                                // establish the CLSS
                                // P/Sender
                                int length = binaryReader.ReadInt32();
                                if (httpServerConnection.Sender_SecuritySession != null)
                                {
                                    using (Stream senderClssReading = new DelimiterStream(incomingStream, length))
                                    {
                                        clsseStream = httpServerConnection.Sender_SecuritySession.EstablishSession(
                                            senderClssReading, true);
                                    }
                                }

                                if (clsseStream == null)
                                    clsseStream = Stream.Null;

                                using (new GenuineChunkedStreamSizeLabel(outputStream))
                                    GenuineUtility.CopyStreamToStream(clsseStream, outputStream);

                                // P/Listener
                                length = binaryReader.ReadInt32();
                                clsseStream = Stream.Null;
                                if (httpServerConnection.Listener_SecuritySession != null)
                                    clsseStream = httpServerConnection.Listener_SecuritySession.EstablishSession(
                                        new DelimiterStream(incomingStream, length), true);

                                if (clsseStream == null)
                                    clsseStream = Stream.Null;

                                using (new GenuineChunkedStreamSizeLabel(outputStream))
                                    GenuineUtility.CopyStreamToStream(clsseStream, outputStream);

                                // write the answer
                                Stream finalStream = outputStream;
                                this.LowLevel_SendStream(httpServerRequestResult.HttpContext, false, null, false, ref finalStream, httpServerConnection);
                                break;

                            case HttpPacketType.Listening:
                                postponeResponse = this.LowLevel_ProcessListenerRequest(httpServerRequestResult, httpServerConnection, sequenceNo);
                                break;

                            case HttpPacketType.Usual:
                                this.LowLevel_ProcessSenderRequest(genuineConnectionType, incomingStream, httpServerRequestResult, httpServerConnection, sequenceNo, remote);
                                break;

                            default:
                                // LOG:
                                if ( binaryLogWriter != null && binaryLogWriter[LogCategory.Connection] > 0 )
                                {
                                    binaryLogWriter.WriteEvent(LogCategory.Connection, "HttpServerConnectionManager.HandleIncomingRequest",
                                        LogMessageType.Error, GenuineExceptions.Get_Debugging_GeneralWarning("Unexpected type of the packet."), null, remote, null,
                                        GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, null, null, httpServerConnection == null ? -1 : httpServerConnection.DbgConnectionId,
                                        0, 0, 0, null, null, null, null,
                                        "Unexpected type of the packet. Packet type: {0}. Sequence no: {1}. Content length: {2}. Host address: {3}.",
                                        Enum.Format(typeof(HttpPacketType), httpPacketType, "g"), sequenceNo, httpRequest.ContentLength, httpRequest.UserHostAddress);
                                }
                                break;
                        }
                    }
                        break;

                    case GenuineConnectionType.Named:
                        throw new NotSupportedException("Named connections are not supported.");

                    case GenuineConnectionType.Invocation:
                        // renew the host
                        remote.Renew(this._closeInvocationConnectionAfterInactivity, false);

                        this.LowLevel_ProcessSenderRequest(genuineConnectionType, incomingStream, httpServerRequestResult, null, sequenceNo, remote);
                        break;
                }
            }
            catch(Exception ex)
            {
                // LOG:
                if ( binaryLogWriter != null && binaryLogWriter[LogCategory.Connection] > 0 )
                {
                    binaryLogWriter.WriteEvent(LogCategory.Connection, "HttpServerConnectionManager.HandleIncomingRequest",
                        LogMessageType.ReceivingFinished, ex, null, null, null,
                        GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, null, null, -1,
                        0, 0, 0, null, null, null, null,
                        "Error occurred while processing incoming HTTP request.");
                }
            }
            finally
            {
                if (! postponeResponse)
                    httpServerRequestResult.Complete(true);
            }
        }
        /// <summary>
        /// Parses HTTP request or response.
        /// </summary>
        /// <param name="timeout">The reading timeout.</param>
        /// <param name="client">Specifies the parsing logic.</param>
        /// <param name="socket">The connection.</param>
        /// <param name="connectionLevelSecurity">Connection-level Security Session.</param>
        /// <param name="protocolVersion">The version of the protocol.</param>
        /// <param name="uri">The URI of the remote host.</param>
        /// <param name="sequenceNo">The sequence no of the parsing packet.</param>
        /// <param name="genuineConnectionType">The type of the connection.</param>
        /// <param name="hostId">The identifier of the host.</param>
        /// <param name="httpPacketType">The type of the HTTP packet.</param>
        /// <param name="connectionName">The name of the connection.</param>
        /// <param name="remoteHostUniqueIdentifier">The unique identifier of the HostInformation used by the remote host.</param>
        /// <returns>A stream based on the specified socket.</returns>
        private Stream LowLevel_ParseHttpContent(int timeout, bool client, Socket socket, SecuritySession connectionLevelSecurity, out byte protocolVersion, out string uri, out int sequenceNo, out GenuineConnectionType genuineConnectionType, out Guid hostId, out HttpPacketType httpPacketType, out string connectionName, out int remoteHostUniqueIdentifier)
        {
            BinaryLogWriter binaryLogWriter = this.ITransportContext.BinaryLogWriter;
            protocolVersion = MessageCoder.PROTOCOL_VERSION;
            uri = null;
            genuineConnectionType = GenuineConnectionType.None;
            hostId = Guid.Empty;
            httpPacketType = HttpPacketType.Unkown;
            connectionName = null;

            // read the entire header
            Stream inputStream = new BufferedStream(new SyncSocketStream(socket, this, timeout));

            int contentLength = -1;

            #if DEBUG
            GenuineChunkedStream httpHeadersContent = new GenuineChunkedStream(false);
            StreamWriter httpTraffic = new StreamWriter(httpHeadersContent);
            #endif

            GXHTTPHeaderParser gxhttpHeaderParser = new GXHTTPHeaderParser(client);
            int indexOfFirstDigit;
            int indexOfLastDigit;

            for ( ; ; )
            {
                string line = this.LowLevel_ReadToUpperLine(inputStream, out indexOfFirstDigit, out indexOfLastDigit);

            #if DEBUG
                httpTraffic.Write(line);
                httpTraffic.Write(Environment.NewLine);
            #endif

                if (line.Length <= 0)
                    break;

                if (gxhttpHeaderParser.ParseHeader(line, indexOfFirstDigit, indexOfLastDigit) == GXHTTPHeaderParser.HeaderFields.Expect100Continue && gxhttpHeaderParser.IsHttp11)
                    this.LowLevel_Send100Continue(socket);
            }

            contentLength = (int) gxhttpHeaderParser.ContentLength;

            #if DEBUG
            // LOG:
            if ( binaryLogWriter != null && binaryLogWriter[LogCategory.LowLevelTransport] > 0 )
            {
                binaryLogWriter.WriteTransportContentEvent(LogCategory.LowLevelTransport, "XHttpConnectionManager.LowLevel_ParseHttpContent",
                    LogMessageType.LowLevelTransport_SyncReceivingCompleted, null, null, null,
                    binaryLogWriter[LogCategory.LowLevelTransport] > 1 ? httpHeadersContent : null,
                    GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name,
                    -1, contentLength, socket.RemoteEndPoint.ToString(),
                    null, null,
                    "XHTTP Headers parsed. Content Length: {0}.", contentLength);
            }

            httpHeadersContent.Dispose();
            #endif

            // ok, the header has been successfully skipped
            if (contentLength < 0)
                throw GenuineExceptions.Get_Receive_IncorrectData();

            // TODO: fix this! there is socket -> buffer -> delimiter chain, while it must be socket -> delimiter -> buffer
            // and we know the content length
            inputStream = new DelimiterStream(inputStream, contentLength);

            // LOG:
            if ( binaryLogWriter != null && binaryLogWriter[LogCategory.LowLevelTransport] > 0 )
            {
                GenuineChunkedStream contentCopy = null;
                bool writeContent = binaryLogWriter[LogCategory.LowLevelTransport] > 1;
                if (writeContent)
                {
                    contentCopy = new GenuineChunkedStream(false);
                    GenuineUtility.CopyStreamToStream(inputStream, contentCopy, contentLength);
                }

                binaryLogWriter.WriteTransportContentEvent(LogCategory.LowLevelTransport, "XHttpConnectionManager.LowLevel_ParseHttpContent",
                    LogMessageType.LowLevelTransport_SyncReceivingCompleted, null, null, null,
                    writeContent ? contentCopy : null,
                    GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name,
                    -1, contentLength, socket.RemoteEndPoint.ToString(),
                    null, null,
                    "XHTTP Message.", contentLength);

                if (writeContent)
                    inputStream = contentCopy;
            }

            // server always encrypts the entire content, including response headers
            if (client && connectionLevelSecurity != null && connectionLevelSecurity.IsEstablished)
                inputStream = connectionLevelSecurity.Decrypt(inputStream);

            BinaryReader binaryReader = new BinaryReader(inputStream);

            // read binary header
            if (client)
                HttpMessageCoder.ReadResponseHeader(binaryReader, out uri, out sequenceNo, out httpPacketType, out remoteHostUniqueIdentifier);
            else
                HttpMessageCoder.ReadRequestHeader(binaryReader, out protocolVersion, out genuineConnectionType, out hostId, out httpPacketType, out sequenceNo, out connectionName, out remoteHostUniqueIdentifier);

            return inputStream;
        }