/// <summary>
        /// Initiates receiving of the message's header.
        /// </summary>
        /// <param name="xHttpPhysicalConnection">The physical connection.</param>
        internal void LowLevel_HalfSync_Client_StartReceiving(XHttpPhysicalConnection xHttpPhysicalConnection)
        {
            // LOG:
            BinaryLogWriter binaryLogWriter = this.ITransportContext.BinaryLogWriter;
            if ( binaryLogWriter != null && binaryLogWriter[LogCategory.Transport] > 0 )
            {
                binaryLogWriter.WriteEvent(LogCategory.Transport, "XHttpConnectionManager.LowLevel_HalfSync_Client_StartReceiving",
                    LogMessageType.ReceivingStarted, null, null, xHttpPhysicalConnection.Remote, null,
                    GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name,
                    xHttpPhysicalConnection.ConnectionLevelSecurity,
                    xHttpPhysicalConnection.ConnectionLevelSecurity == null ? null : xHttpPhysicalConnection.ConnectionLevelSecurity.Name,
                    xHttpPhysicalConnection.XHttpConnection.DbgConnectionId, 0, 0, 0, null, null, null, null,
                    "The asynchronous receiving is initiated.");
            }

            // check the connection
            xHttpPhysicalConnection.CheckConnectionStatus();

            // and initiate receiving
            AsyncThreadStarter.QueueTask(new Async_InitiateSocketReceiving(xHttpPhysicalConnection.Socket,
                this._unusedBuffer, 0,
                1,
                _HalfSync_Client_onEndReceiving, xHttpPhysicalConnection));
        }
        /// <summary>
        /// Sends HTTP content to the remote host.
        /// Does not process exceptions.
        /// Automatically initiates asynchronous receiving.
        /// Automatically manages stream seqNo for clients' connections.
        /// </summary>
        /// <param name="timeout">Operation timeout.</param>
        /// <param name="message">The message.</param>
        /// <param name="content">The content sent instead of the message.</param>
        /// <param name="exceptionToBeSent">The exception being sent in the response.</param>
        /// <param name="messageContainer">The message container.</param>
        /// <param name="xHttpPhysicalConnection">The physical connection.</param>
        /// <param name="genuineConnectionType">The type of the connection.</param>
        /// <param name="httpPacketType">The type of the HTTP packet.</param>
        /// <param name="repeatSending">Whether the content was already packed.</param>
        /// <param name="synchronous">Whether to send content synchronously.</param>
        /// <param name="startAutomaticReceiving">Indicates whether to start automatic receiving of the response/request if the type of the sending is synchronous.</param>
        /// <param name="applyClss">A boolean value indicating whether the CLSS should be applied.</param>
        private void LowLevel_SendHttpContent(int timeout, Message message, 
            GenuineChunkedStream content, Exception exceptionToBeSent,
            MessageContainer messageContainer, XHttpPhysicalConnection xHttpPhysicalConnection,
            GenuineConnectionType genuineConnectionType, HttpPacketType httpPacketType,
            bool repeatSending, bool synchronous, bool startAutomaticReceiving, bool applyClss
            )
        {
            BinaryLogWriter binaryLogWriter = this.ITransportContext.BinaryLogWriter;

            // check whether the connection is valid and available
            xHttpPhysicalConnection.CheckConnectionStatus();

            // prevent the ping
            if (! xHttpPhysicalConnection.IsSender)
                xHttpPhysicalConnection.XHttpConnection.LastTimeContentWasSent = GenuineUtility.TickCount;

            // valid copies
            Socket socket;
            Stream sentContent;

            // to prevent from changing sequence information or disposing sent content during its encryption
            lock (xHttpPhysicalConnection.PhysicalConnectionStateLock)
            {
                if (! repeatSending)
                {
                    if (xHttpPhysicalConnection.XHttpConnection.IsClient)
                        xHttpPhysicalConnection.SequenceNo ++;

                    if (message != null || (message == null && content == null && exceptionToBeSent == null))
                    {
                        GenuineChunkedStream packedMessages = new GenuineChunkedStream(false);
                        MessageCoder.FillInLabelledStream(message, messageContainer,
                            xHttpPhysicalConnection.MessagesBeingSent, packedMessages,
                            xHttpPhysicalConnection.AsyncSendBuffer,
                            (int) this.ITransportContext.IParameterProvider[GenuineParameter.HttpRecommendedPacketSize]);

                        // LOG:
                        if ( binaryLogWriter != null && binaryLogWriter[LogCategory.Transport] > 0 )
                        {
                            for ( int i = 0; i < xHttpPhysicalConnection.MessagesBeingSent.Count; i++)
                            {
                                Message nextMessage = (Message) xHttpPhysicalConnection.MessagesBeingSent[i];

                                binaryLogWriter.WriteEvent(LogCategory.Transport, "XHttpConnectionManager.LowLevel_SendHttpContent",
                                    LogMessageType.MessageIsSentAsynchronously, null, nextMessage, xHttpPhysicalConnection.Remote, null,
                                    GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, xHttpPhysicalConnection.ConnectionLevelSecurity, null,
                                    xHttpPhysicalConnection.XHttpConnection.DbgConnectionId, xHttpPhysicalConnection.SequenceNo, 0, 0, null, null, null, null,
                                    "The message will be sent in the {0} stream N: {1}.",
                                    xHttpPhysicalConnection == xHttpPhysicalConnection.XHttpConnection.Sender ? "SENDER" : "LISTENER",
                                    xHttpPhysicalConnection.SequenceNo);
                            }
                        }

                        xHttpPhysicalConnection.SentContent = packedMessages;
                    }
                    else if (content != null)
                    {
                        xHttpPhysicalConnection.MessagesBeingSent.Clear();
                        xHttpPhysicalConnection.SentContent = content;
                    }
                    else //if (exceptionToBeSent != null)
                    {
            #if DEBUG
                        Debug.Assert(httpPacketType == HttpPacketType.SenderError);
            #endif

                        Exception exception = OperationException.WrapException(exceptionToBeSent);
                        GenuineChunkedStream output = new GenuineChunkedStream(false);
                        BinaryFormatter binaryFormatter = new BinaryFormatter(new RemotingSurrogateSelector(), new StreamingContext(StreamingContextStates.Other));
                        binaryFormatter.Serialize(output, exception);

                        xHttpPhysicalConnection.MessagesBeingSent.Clear();
                        xHttpPhysicalConnection.SentContent = output;
                    }

                    // client applies CLSSE only to the actual content
                    if (applyClss && xHttpPhysicalConnection.XHttpConnection.IsClient && xHttpPhysicalConnection.ConnectionLevelSecurity != null)
                    {
                        GenuineChunkedStream encryptedContent = new GenuineChunkedStream(false);
                        xHttpPhysicalConnection.ConnectionLevelSecurity.Encrypt(xHttpPhysicalConnection.SentContent, encryptedContent);
                        xHttpPhysicalConnection.SentContent = encryptedContent;
                    }

                    // write the binary header
                    GenuineChunkedStream resultStream = new GenuineChunkedStream(false);
                    BinaryWriter binaryWriter = new BinaryWriter(resultStream);

                    if (xHttpPhysicalConnection.XHttpConnection.IsClient)
                        HttpMessageCoder.WriteRequestHeader(binaryWriter, MessageCoder.PROTOCOL_VERSION, genuineConnectionType, xHttpPhysicalConnection.XHttpConnection.HostId, httpPacketType, xHttpPhysicalConnection.SequenceNo, xHttpPhysicalConnection.XHttpConnection.ConnectionName, xHttpPhysicalConnection.XHttpConnection.Remote.LocalHostUniqueIdentifier);
                    else
                        HttpMessageCoder.WriteResponseHeader(binaryWriter, xHttpPhysicalConnection.XHttpConnection.Remote.ProtocolVersion, this.ITransportContext.ConnectionManager.Local.Uri, xHttpPhysicalConnection.SequenceNo, httpPacketType, xHttpPhysicalConnection.XHttpConnection.Remote.LocalHostUniqueIdentifier);

                    resultStream.WriteStream(xHttpPhysicalConnection.SentContent);
                    xHttpPhysicalConnection.SentContent = resultStream;

                    // while server applies CLSSE to the entire response (except HTTP stuff, of course)
                    if (applyClss && ! xHttpPhysicalConnection.XHttpConnection.IsClient && xHttpPhysicalConnection.ConnectionLevelSecurity != null)
                    {
                        GenuineChunkedStream encryptedContent = new GenuineChunkedStream(false);
                        xHttpPhysicalConnection.ConnectionLevelSecurity.Encrypt(xHttpPhysicalConnection.SentContent, encryptedContent);
                        xHttpPhysicalConnection.SentContent = encryptedContent;
                    }

                    // generally it's impossible to have xHttpPhysicalConnection.SentContent without available length in the current implementation
                    // nevertheless, it's necessary to calculate the final length of the content if it's unknown
                    if (! xHttpPhysicalConnection.SentContent.CanSeek)
                    {
                        GenuineChunkedStream actualContent = new GenuineChunkedStream(false);
                        GenuineUtility.CopyStreamToStream(xHttpPhysicalConnection.SentContent, actualContent, xHttpPhysicalConnection.AsyncSendBuffer);
                        xHttpPhysicalConnection.SentContent = actualContent;
                    }

                    // write the header and compose final content
                    resultStream = new GenuineChunkedStream(false);
                    StreamWriter streamWriter = new StreamWriter(new NonClosableStream(resultStream), Encoding.ASCII, 3500);

                    if (xHttpPhysicalConnection.XHttpConnection.IsClient)
                        streamWriter.Write("POST /{0} HTTP/1.1\r\nAccept: */*\r\nContent-Type: application/octet-stream\r\nContent-Length: {1}\r\nUser-Agent: {2}\r\nHost: {3}\r\nConnection: Keep-Alive\r\nPragma: no-cache\r\n\r\n",
                            xHttpPhysicalConnection.EntryUri, xHttpPhysicalConnection.SentContent.Length, xHttpPhysicalConnection.XHttpConnection.UserAgent, xHttpPhysicalConnection.LocalEndPoint);
                    else
                    {
                        string now = DateTime.Now.ToString("r");
                        streamWriter.Write("HTTP/1.1 200 OK\r\nServer: GXHTTP\r\nDate: {0}\r\nX-Powered-By: Genuine Channels\r\nCache-Control: private\r\nContent-Type: application/octet-stream\r\nContent-Length: {1}\r\n\r\n",
                            now, xHttpPhysicalConnection.SentContent.Length);
                    }

                    streamWriter.Flush();
                    streamWriter.Close();
                    resultStream.WriteStream(xHttpPhysicalConnection.SentContent);

                    xHttpPhysicalConnection.SentContent = resultStream;
                }
                else
                {
                    xHttpPhysicalConnection.SentContent.Position = 0;
                }

                socket = xHttpPhysicalConnection.Socket;
                sentContent = xHttpPhysicalConnection.SentContent;
            }	// lock (xHttpPhysicalConnection.PhysicalConnectionStateLock)

            if (synchronous)
            {
                // send the content
                SyncSocketWritingStream syncSocketWritingStream = new SyncSocketWritingStream(this, socket, timeout, xHttpPhysicalConnection.XHttpConnection.DbgConnectionId, xHttpPhysicalConnection.Remote);
                GenuineUtility.CopyStreamToStreamPhysically(sentContent, syncSocketWritingStream, xHttpPhysicalConnection.AsyncSendBuffer);

                // automatically start receiving the response/request
                if (startAutomaticReceiving)
                {
                    if (xHttpPhysicalConnection.XHttpConnection.IsClient)
                        this.LowLevel_HalfSync_Client_StartReceiving(xHttpPhysicalConnection);
                    else
                        this.LowLevel_HalfSync_Server_StartReceiving(xHttpPhysicalConnection.Socket);
                }
            }
            else
            {
                xHttpPhysicalConnection.AsyncSendBufferCurrentPosition = 0;
                xHttpPhysicalConnection.AsyncSendBufferIsLastPacket = false;
                xHttpPhysicalConnection.AsyncSendBufferSizeOfValidContent = 0;
                xHttpPhysicalConnection.AsyncSendStream = sentContent;

                this.LowLevel_InitiateAsyncSending(xHttpPhysicalConnection);
            }
        }