/// <summary>
        /// Processes incoming requests and responses.
        /// </summary>
        /// <param name="stream">The stream containing a request or a response.</param>
        /// <param name="remote">The remote host.</param>
        /// <param name="genuineConnectionType">The type of the connection.</param>
        /// <param name="connectionName">Connection id to send a response through.</param>
        /// <param name="dbgConnectionId">The identifier of the connection, which is used for debugging purposes only.</param>
        /// <param name="useThisThread">True to invoke the target in the current thread.</param>
        /// <param name="iMessageRegistrator">The message registrator.</param>
        /// <param name="connectionLevelSecuritySession">Connection Level Security Session.</param>
        /// <param name="httpServerRequestResult">The HTTP request through which the message was received.</param>
        /// <returns>True if it's a one-way message.</returns>
        public bool HandleMessage(Stream stream, HostInformation remote, GenuineConnectionType genuineConnectionType, string connectionName, int dbgConnectionId, bool useThisThread, IMessageRegistrator iMessageRegistrator, SecuritySession connectionLevelSecuritySession, HttpServerRequestResult httpServerRequestResult)
        {
            // read the Security Session name
            BinaryReader binaryReader = new BinaryReader(stream);
            string sessionName = binaryReader.ReadString();
            Message message = null;
            BinaryLogWriter binaryLogWriter = this.ITransportContext.BinaryLogWriter;

            // and decode the packet
            SecuritySession securitySession = remote.GetSecuritySession(sessionName, this.ITransportContext.IKeyStore);
            if (securitySession == null)
            {
                // LOG:
                if ( binaryLogWriter != null && binaryLogWriter[LogCategory.Security] > 0 )
                {
                    binaryLogWriter.WriteEvent(LogCategory.Security, "GenuineReceivingHandler.HandleMessage",
                        LogMessageType.SecuritySessionApplied, GenuineExceptions.Get_Security_ContextNotFound(sessionName),
                        message, remote,
                        null, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name,
                        securitySession, sessionName, dbgConnectionId,
                        0, 0, 0, null, null, null, null,
                        "The requested Security Session can not be constructed or established. The name of Security Session: {0}.",
                        sessionName);
                }

                this.ITransportContext.IGenuineEventProvider.Fire(new GenuineEventArgs(GenuineEventType.SecuritySessionWasNotFound, GenuineExceptions.Get_Security_ContextNotFound(sessionName),
                    remote, null));

                return true;
            }

            // decode the stream and roll back if it was a Security Session's message
            stream = securitySession.Decrypt(stream);
            if (stream == null)
                return true;

            // read the message
            message = MessageCoder.Deserialize(stream, sessionName);
            message.ConnectionName = connectionName;
            message.SecuritySessionParameters._connectionName = connectionName;
            message.SecuritySessionParameters._genuineConnectionType = genuineConnectionType;
            message.Sender = remote;
            message.ITransportContext = this.ITransportContext;
            message.ConnectionLevelSecuritySession = connectionLevelSecuritySession;
            message.HttpServerRequestResult = httpServerRequestResult;

            // LOG:
            if ( binaryLogWriter != null && binaryLogWriter[LogCategory.Security] > 0 )
            {
                binaryLogWriter.WriteEvent(LogCategory.Security, "GenuineReceivingHandler.HandleMessage",
                    LogMessageType.SecuritySessionApplied, null, message, remote,
                    null, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name,
                    securitySession, sessionName, dbgConnectionId,
                    0, 0, 0, null, null, null, null,
                    "The Security Session has been used for decrypting the message.");
            }

            // LOG:
            if ( binaryLogWriter != null && binaryLogWriter[LogCategory.MessageProcessing] > 0 )
            {
                bool readContent = this.ITransportContext.BinaryLogWriter[LogCategory.MessageProcessing] > 1;
                if (readContent)
                {
                    GenuineChunkedStream streamClone = new GenuineChunkedStream();
                    GenuineUtility.CopyStreamToStream(message.Stream, streamClone);
                    message.Stream = streamClone;
                }

                binaryLogWriter.WriteMessageCreatedEvent("GenuineReceivingHandler.HandleMessage",
                    LogMessageType.MessageReceived, null, message, message.ReplyToId > 0, remote,
                    readContent ? message.Stream : null,
                    message.ITransportHeaders[Message.TransportHeadersInvocationTarget] as string, message.ITransportHeaders[Message.TransportHeadersMethodName] as string,
                    GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, connectionName, dbgConnectionId,
                    connectionLevelSecuritySession == null ? -1 : connectionLevelSecuritySession.SecuritySessionId,
                    connectionLevelSecuritySession == null ? null : connectionLevelSecuritySession.Name,
                    securitySession == null ? -1 : securitySession.SecuritySessionId,
                    securitySession.Name,
                    "The message has been received.");
            }

            if (message.ReplyToId == PING_MESSAGE_REPLYID)
                return true;

            if (iMessageRegistrator != null && iMessageRegistrator.WasRegistered(remote.Uri, message.MessageId, message.ReplyToId))
            {
                // LOG:
                if ( binaryLogWriter != null && binaryLogWriter[LogCategory.MessageProcessing] > 0 )
                    binaryLogWriter.WriteEvent(LogCategory.MessageProcessing, "GenuineReceivingHandler.HandleMessage",
                        LogMessageType.MessageDispatched, GenuineExceptions.Get_Debugging_GeneralWarning("The message has been already processed."), message, remote,
                        null,
                        GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, securitySession, securitySession.Name,
                        dbgConnectionId,
                        GenuineUtility.TickCount, 0, message.SeqNo, null, null, null, null,
                        "The message has been already processed. Therefore, this message is ignored.");

                return true;
            }

            // if it's a response, then direct the message to the response handler
            if (message.ReplyToId > 0)
            {
                message.IsOneWay = true;
                IResponseProcessor iResponseProcessor = GenuineReceivingHandler._responseHandlers[message.ReplyToId] as IResponseProcessor;

                // nothing waits for this request
                if (iResponseProcessor == null)
                    return true;

                // 2.5.1: set the answer flag
                if (iResponseProcessor.Message != null)
                    iResponseProcessor.Message.HasBeenAsnwered = true;

                if (iResponseProcessor.IsShortInProcessing)
                {
                    iResponseProcessor.ProcessRespose(message);

            #if TRIAL
            #else
                    if (iResponseProcessor.IsExpired(GenuineUtility.TickCount))
                        GenuineReceivingHandler._responseHandlers.Remove(message.ReplyToId);
            #endif

                    return true;
                }
            }

            // take care about the thread and call context
            if (useThisThread)
                InternalExecuteMessage(message);
            else
                GenuineThreadPool.QueueUserWorkItem(this._waitCallback_InternalExecuteMessagewaitCallback, message, false);

            return message.IsOneWay;
        }
 /// <summary>
 /// Puts down the Security Session Identifier.
 /// </summary>
 /// <param name="securitySession">The Security Session.</param>
 private void WriteSecuritySessionId(SecuritySession securitySession)
 {
     this.BinaryWriter.Write( (bool) (securitySession != null) );
     if (securitySession != null)
         this.BinaryWriter.Write( (int) securitySession.SecuritySessionId );
 }
        /// <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;
        }
        /// <summary>
        /// Puts down detailed information about the specified instance of the HostInformation class.
        /// </summary>
        /// <param name="author">The author.</param>
        /// <param name="type">The type of the event(Subcategory).</param>
        /// <param name="exception">The exception associated with the event.</param>
        /// <param name="remote">The remote host participating in the event.</param>
        /// <param name="sourceThreadId">The id of the thread where the invocation was made.</param>
        /// <param name="sourceThreadName">The name of the thread.</param>
        /// <param name="securitySession">The Security Session.</param>
        /// <param name="securitySessionName">The name of the Security Session</param>
        /// <param name="connectionId">The connection identifier.</param>
        /// <param name="description">The description of the event.</param>
        /// <param name="parameters">Parameters to the description.</param>
        public void WriteHostInformationEvent(string author, LogMessageType type, Exception exception, 
            HostInformation remote, int sourceThreadId, string sourceThreadName,
            SecuritySession securitySession, string securitySessionName, int connectionId,
            string description, params object[] parameters)
        {
            if (remote == null)
            {
                this.WriteImplementationWarningEvent("BinaryLogWriter.WriteHostInformationCreatedEvent", LogMessageType.Error, null,
                    sourceThreadId, sourceThreadName, "The reference is null. Stack trace: " + Environment.StackTrace);
                return ;
            }

            lock (this._streamLock)
            {
                this.WriteRecordHeader(BinaryRecordVersion.HostInformationInfo, LogCategory.HostInformation, type, author);
                this.WriteException( exception );

                this.WriteHostInformation(remote);

                this.BinaryWriter.Write( (int) sourceThreadId);
                this.WriteString( sourceThreadName );

                this.WriteSecuritySessionId( securitySession );
                this.WriteString( securitySessionName );

                this.BinaryWriter.Write( (int) connectionId );
                this.WriteStringWithParameters( description, parameters);

                this.BinaryWriter.Flush();
            }
        }
        /// <summary>
        /// Puts down a record describing a general Genuine Channels event.
        /// </summary>
        /// <param name="logCategory">The category of the event.</param>
        /// <param name="author">The author.</param>
        /// <param name="type">The type of the event(Subcategory).</param>
        /// <param name="exception">The exception associated with the event.</param>
        /// <param name="message">The message associated with the event.</param>
        /// <param name="remote">The remote host participating in the event.</param>
        /// <param name="content">The content associated with the record.</param>
        /// <param name="sourceThreadId">The id of the thread where the invocation was made.</param>
        /// <param name="sourceThreadName">The name of the thread.</param>
        /// <param name="securitySession">The Security Session.</param>
        /// <param name="securitySessionName">The name of the Security Session</param>
        /// <param name="connectionId">The identifier of the connection.</param>
        /// <param name="number1">An additional integer parameter.</param>
        /// <param name="number2">An additional integer parameter.</param>
        /// <param name="number3">An additional integer parameter.</param>
        /// <param name="string1">The first string that elaborates the current event.</param>
        /// <param name="string2">The second string that elaborates the current event.</param>
        /// <param name="string3">The third string that elaborates the current event.</param>
        /// <param name="string4">The fourth string that elaborates the current event.</param>
        /// <param name="description">The description of the event.</param>
        /// <param name="parameters">Parameters to the description.</param>
        public void WriteEvent(LogCategory logCategory, string author, LogMessageType type, Exception exception, 
            Message message, HostInformation remote, Stream content, int sourceThreadId, string sourceThreadName,
            SecuritySession securitySession, string securitySessionName,
            int connectionId, int number1, int number2, int number3, string string1, string string2, string string3, string string4, string description, params object[] parameters)
        {
            lock (this._streamLock)
            {
                this.WriteRecordHeader(BinaryRecordVersion.GeneralRecord, logCategory, type, author);
                this.WriteException( exception );

                this.WriteMessageSeqNo( message );
                this.WriteHostInformationId( remote );
                this.WriteBinaryContent( content );

                this.BinaryWriter.Write( (int) sourceThreadId);
                this.WriteString( sourceThreadName );

                this.WriteSecuritySessionId( securitySession );
                this.WriteString( securitySessionName );

                this.BinaryWriter.Write( (int) connectionId );

                this.BinaryWriter.Write( (int) number1 );
                this.BinaryWriter.Write( (int) number2 );
                this.BinaryWriter.Write( (int) number3 );

                this.WriteString( string1 );
                this.WriteString( string2 );
                this.WriteString( string3 );
                this.WriteString( string4 );

                this.WriteStringWithParameters( description, parameters);

                this.BinaryWriter.Flush();
            }
        }
        /// <summary>
        /// Puts down a record describing a general Genuine Channels event.
        /// </summary>
        /// <param name="logCategory">The category of the event.</param>
        /// <param name="author">The author.</param>
        /// <param name="type">The type of the event(Subcategory).</param>
        /// <param name="exception">The exception associated with the event.</param>
        /// <param name="message">The message associated with the event.</param>
        /// <param name="remote">The remote host participating in the event.</param>
        /// <param name="content">The content associated with the record.</param>
        /// <param name="sourceThreadId">The id of the thread where the invocation was made.</param>
        /// <param name="sourceThreadName">The name of the thread.</param>
        /// <param name="securitySession">The Security Session.</param>
        /// <param name="securitySessionName">The name of the Security Session</param>
        /// <param name="writeDispatcherSettings">A value indicating whether it is necessary to put down broadcast dispatcher's settings.</param>
        /// <param name="dispatcher">The broadcast dispatcher.</param>
        /// <param name="resultCollector">The broadcast result collector.</param>
        /// <param name="writeReceiverInfoSettings">A value indicating whether it is necessary to put down information about the specified broadcast recipient.</param>
        /// <param name="receiverInfo">The broadcast recipient.</param>
        /// <param name="string1">The first string that elaborates the current event.</param>
        /// <param name="string2">The second string that elaborates the current event.</param>
        /// <param name="description">The description of the event.</param>
        /// <param name="parameters">Parameters to the description.</param>
        public void WriteBroadcastEngineEvent(LogCategory logCategory, string author, LogMessageType type, Exception exception, 
            Message message, HostInformation remote, Stream content, int sourceThreadId, string sourceThreadName,
            SecuritySession securitySession, string securitySessionName,
            bool writeDispatcherSettings, Dispatcher dispatcher, ResultCollector resultCollector, bool writeReceiverInfoSettings,
            ReceiverInfo receiverInfo, string string1, string string2, string description, params object[] parameters)
        {
            if (dispatcher == null)
            {
                this.WriteImplementationWarningEvent("BinaryLogWriter.WriteBroadcastEngineEvent", LogMessageType.Error, null,
                    sourceThreadId, sourceThreadName, "The reference is null. Stack trace: " + Environment.StackTrace);
                return ;
            }

            lock (this._streamLock)
            {
                this.WriteRecordHeader(BinaryRecordVersion.TransportBroadcastEngineRecord, logCategory, type, author);
                this.WriteException( exception );

                this.WriteMessageSeqNo( message );
                this.WriteHostInformationId( remote );
                this.WriteBinaryContent( content );

                this.BinaryWriter.Write( (int) sourceThreadId);
                this.WriteString( sourceThreadName );

                this.WriteSecuritySessionId( securitySession );
                this.WriteString( securitySessionName );

                this.WriteResultCollectorId(resultCollector);
                this.WriteDispatcherSettings(writeDispatcherSettings, dispatcher);
                this.WriteReceiverInfo(writeReceiverInfoSettings, receiverInfo);

                this.WriteString( string1 );
                this.WriteString( string2 );
                this.WriteStringWithParameters( description, parameters);

                this.BinaryWriter.Flush();
            }
        }
        /// <summary>
        /// Reads messages from the stream and processes them.
        /// </summary>
        /// <param name="stream">The source stream.</param>
        /// <param name="intermediateBuffer">The intermediate buffer.</param>
        /// <param name="httpClientConnection">The connection.</param>
        /// <param name="connectionLevelSecuritySession">The Connection Level Security Session that decrypted this message.</param>
        public void LowLevel_ParseLabelledStream(Stream stream, byte[] intermediateBuffer, HttpClientConnection httpClientConnection, SecuritySession connectionLevelSecuritySession)
        {
            bool directExecution = httpClientConnection.GenuineConnectionType == GenuineConnectionType.Invocation;

            BinaryReader binaryReader = new BinaryReader(stream);

            while ( binaryReader.ReadByte() == 0 )
            {
                using (LabelledStream labelledStream = new LabelledStream(this.ITransportContext, stream, intermediateBuffer))
                {
                    if (directExecution)
                        this.ITransportContext.IIncomingStreamHandler.HandleMessage(labelledStream, httpClientConnection.Remote, httpClientConnection.GenuineConnectionType, httpClientConnection.ConnectionName, httpClientConnection.DbgConnectionId, true, null, connectionLevelSecuritySession, null);
                    else
                    {
                        GenuineChunkedStream receivedContent = new GenuineChunkedStream(true);
                        GenuineUtility.CopyStreamToStream(labelledStream, receivedContent);
                        this.ITransportContext.IIncomingStreamHandler.HandleMessage(receivedContent, httpClientConnection.Remote, httpClientConnection.GenuineConnectionType, httpClientConnection.ConnectionName, httpClientConnection.DbgConnectionId, false, null, connectionLevelSecuritySession, null);
                    }
                }
            }
        }
        /// <summary>
        /// Establishes Connection Level Security Session and gather their output into specified stream.
        /// </summary>
        /// <param name="senderInput">The input stream.</param>
        /// <param name="listenerInput">The input stream.</param>
        /// <param name="output">The output stream.</param>
        /// <param name="sender">The sender's Security Session.</param>
        /// <param name="listener">The listener's Security Session.</param>
        /// <returns>True if at least one Security Session requested sending of data.</returns>
        public bool GatherContentOfConnectionLevelSecuritySessions(Stream senderInput, Stream listenerInput, GenuineChunkedStream output, SecuritySession sender, SecuritySession listener)
        {
            bool clssDataPresents = false;
            Stream clsseStream;

            // CLSSE info
            using (new GenuineChunkedStreamSizeLabel(output))
            {
                if (sender != null && ! sender.IsEstablished)
                {
                    clsseStream = sender.EstablishSession(senderInput, true);
                    if (clsseStream != null)
                    {
                        clssDataPresents = true;
                        GenuineUtility.CopyStreamToStream(clsseStream, output);
                    }
                }
            }

            // CLSSE info
            using (new GenuineChunkedStreamSizeLabel(output))
            {
                if (listener != null && ! listener.IsEstablished)
                {
                    clsseStream = listener.EstablishSession(listenerInput, true);
                    if (clsseStream != null)
                    {
                        clssDataPresents = true;
                        GenuineUtility.CopyStreamToStream(clsseStream, output);
                    }
                }
            }

            return clssDataPresents;
        }