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

            try
            {
                tcpSocketInfo = (TcpSocketInfo) tcpSocketInfoAsObject;

                bool automaticallyContinueReceiving = (tcpSocketInfo.ConnectionLevelSecurity == null);

                // create the stream
                SyncSocketReadingStream stream = new SyncSocketReadingStream(this, tcpSocketInfo, GenuineUtility.GetTimeout(tcpSocketInfo.CloseConnectionAfterInactivity), automaticallyContinueReceiving);

                tcpSocketInfo.Renew();

                if (stream.IsMessageProcessed)
                {
                    // it's a ping

                    // LOG:
                    if ( binaryLogWriter != null && binaryLogWriter[LogCategory.Connection] > 0 )
                        binaryLogWriter.WriteEvent(LogCategory.Connection, "TcpConnectionManager.Pool_ContinueHalfSyncReceiving",
                            LogMessageType.ConnectionPingReceived, null, null, tcpSocketInfo == null ? null : tcpSocketInfo.Remote, null,
                            GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name,
                            null, null, tcpSocketInfo.DbgConnectionId, 0, 0, 0, null, null, null, null,
                            "The ping message has been received. Stream number: {0}.", stream.DbgStreamId);

                    if (!automaticallyContinueReceiving)
                        this.LowLevel_HalfSync_StartReceiving(tcpSocketInfo);

                    return ;
                }

                // provide an option to read the entire message first
                Stream resultStream = null;
                bool contentLoggingRequired = binaryLogWriter != null && binaryLogWriter[LogCategory.Transport] > 1;
                if (this._tcpReadRequestBeforeProcessing || contentLoggingRequired)
                {
                    resultStream = new GenuineChunkedStream(contentLoggingRequired ? false : true);
                    GenuineUtility.CopyStreamToStream(stream, resultStream);
                }
                else
                    resultStream = stream;

                // LOG:
                if (binaryLogWriter != null && binaryLogWriter[LogCategory.Transport] > 0)
                    binaryLogWriter.WriteTransportContentEvent(LogCategory.Transport, "TcpConnectionManager.Pool_ContinueHalfSyncReceiving",
                        LogMessageType.ReceivingFinished, null, null, tcpSocketInfo.Remote,
                        contentLoggingRequired ? resultStream : null,
                        GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name,
                        tcpSocketInfo.DbgConnectionId, binaryLogWriter[LogCategory.Transport] > 1 ? (int)resultStream.Length : 0, tcpSocketInfo.Remote.PhysicalAddress.ToString(),
                        null, null,
                        "Content has been received. Stream number: {0}.", stream.DbgStreamId);

                if (tcpSocketInfo.ConnectionLevelSecurity != null)
                    resultStream = tcpSocketInfo.ConnectionLevelSecurity.Decrypt(resultStream);

                if (!automaticallyContinueReceiving)
                    this.LowLevel_HalfSync_StartReceiving(tcpSocketInfo);

                // provide it to the handler
                this.ITransportContext.IIncomingStreamHandler.HandleMessage(resultStream, tcpSocketInfo.Remote, tcpSocketInfo.GenuineConnectionType, tcpSocketInfo.ConnectionName, tcpSocketInfo.DbgConnectionId, true, tcpSocketInfo._iMessageRegistrator, tcpSocketInfo.ConnectionLevelSecurity, null);

                tcpSocketInfo.Renew();
            }
            catch(Exception ex)
            {
                this.SocketFailed(ex, tcpSocketInfo);
            }
        }
        /// <summary>
        /// Provides a stream reading synchronously from the given connection.
        /// </summary>
        /// <param name="tcpSocketInfo">Socket structure.</param>
        /// <param name="timeoutInMilliseconds">Read timeout.</param>
        /// <param name="automaticallyContinueReading">Indicates whether this instance will automatically initiate reading of the next message from the specified connection.</param>
        /// <returns>A stream.</returns>
        private Stream LowLevel_ReadSync(TcpSocketInfo tcpSocketInfo, int timeoutInMilliseconds, bool automaticallyContinueReading)
        {
            Stream inputStream = new SyncSocketReadingStream(this, tcpSocketInfo, timeoutInMilliseconds, automaticallyContinueReading);

            if (tcpSocketInfo.ConnectionLevelSecurity != null)
                return tcpSocketInfo.ConnectionLevelSecurity.Decrypt(inputStream);
            return inputStream;
        }