/// <summary>
        /// Constructs an instance of the XHttpPhysicalConnection class.
        /// </summary>
        /// <param name="xHttpConnection">The physical connection.</param>
        /// <param name="sender">The sender.</param>
        public XHttpPhysicalConnection(XHttpConnection xHttpConnection, bool sender)
        {
            this.XHttpConnection = xHttpConnection;
            this.IsSender        = sender;

            this.AsyncSendBuffer    = new byte[35000];
            this.AsyncReceiveBuffer = new byte[35000];

#if DEBUG
            this._connectionNumber = Interlocked.Increment(ref _TotalConnections);
#endif
        }
        /// <summary>
        /// Operates with failed sockets.
        /// </summary>
        /// <param name="exception">The source exception.</param>
        /// <param name="xHttpConnection">The failed logical connection.</param>
        /// <param name="xHttpPhysicalConnection">The failed physical connection.</param>
        private void ConnectionFailed(Exception exception, XHttpConnection xHttpConnection, XHttpPhysicalConnection xHttpPhysicalConnection)
        {
            BinaryLogWriter binaryLogWriter = this.ITransportContext.BinaryLogWriter;

            try
            {
                if (xHttpPhysicalConnection == null && xHttpConnection == null)
                {
                    // LOG:
                    if ( binaryLogWriter != null )
                    {
                        binaryLogWriter.WriteImplementationWarningEvent("XHttpConnectionManager.ConnectionFailed",
                            LogMessageType.ConnectionFailed, exception,
                            GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name,
                            "The connection has not been specified while invoking XHttpConnectionManager.ConnectionFailed.");
                    }
                    return ;
                }

                OperationException operationException = exception as OperationException;
                bool conflict409Received = false;
                if (operationException != null)
                    conflict409Received = operationException.OperationErrorMessage.ErrorIdentifier.IndexOf("ConflictOfConnections") >= 0;

                // if it's a server, just close the connection
                // if it's a client sender, re-send it again
                // if it's a client listener, re-send the request again with the same seq no
                bool tryToReestablish = ! ConnectionManager.IsExceptionCritical(exception as OperationException);

                HostInformation remote = null;
                if (xHttpConnection != null)
                    remote = xHttpConnection.Remote;

                // LOG:
                if ( binaryLogWriter != null && binaryLogWriter[LogCategory.Connection] > 0 )
                {
                    binaryLogWriter.WriteEvent(LogCategory.Connection, "XHttpConnectionManager.ConnectionFailed",
                        LogMessageType.ConnectionFailed, exception, null, remote, null,
                        GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name,
                        null, null,
                        xHttpConnection == null ? -1 : xHttpConnection.DbgConnectionId, 0, 0, 0, null, null, null, null,
                        "XHTTP connection has failed.");
                }

                using (new ReaderAutoLocker(this._disposeLock))
                {
                    if (this._disposed)
                        tryToReestablish = false;
                }

                // close the socket
                if (xHttpPhysicalConnection != null)
                    GenuineThreadPool.QueueUserWorkItem(new WaitCallback(SocketUtility.CloseSocket), xHttpPhysicalConnection.Socket, true);

                switch (xHttpConnection.GenuineConnectionType)
                {
                    case GenuineConnectionType.Persistent:
                        // ignore connections causing conflict
                        if (conflict409Received)
                            break;

                        lock (remote.PersistentConnectionEstablishingLock)
                        {
                            using (new ReaderAutoLocker(this._disposeLock))
                            {
                                if (! tryToReestablish || xHttpConnection.IsDisposed)
                                {
                                    this._persistent.Remove(remote.PrimaryUri, xHttpConnection.ConnectionName);

                                    // release all resources
                                    this.ITransportContext.KnownHosts.ReleaseHostResources(xHttpConnection.Remote, exception);
                                    xHttpConnection.Dispose(exception);

                                    xHttpConnection.SignalState(GenuineEventType.GeneralConnectionClosed, exception, null);
                                    if (exception is OperationException && ((OperationException) exception).OperationErrorMessage.ErrorIdentifier == "GenuineChannels.Exception.Receive.ServerHasBeenRestarted")
                                        xHttpConnection.SignalState(GenuineEventType.GeneralServerRestartDetected, exception, null);
                                    break;
                                }

                                xHttpConnection.SignalState(GenuineEventType.GeneralConnectionReestablishing, exception, null);

                                // start reestablishing
                                if (remote.GenuinePersistentConnectionState == GenuinePersistentConnectionState.Opened)
                                {
                                    // start the reestablishing, if possible
                                    if (xHttpPhysicalConnection != null && xHttpPhysicalConnection.Reestablish_ObtainStatus())
                                        GenuineThreadPool.QueueUserWorkItem(new WaitCallback(this.ReestablishConnection), xHttpPhysicalConnection, true);
                                }

                            }	// using (new ReaderAutoLocker(this._disposeLock))
                        }	// lock (remote.PersistentConnectionEstablishingLock)
                        break;

                    case GenuineConnectionType.Invocation:
                        break;
                }
            }
            catch(Exception ex)
            {
                // LOG:
                if ( binaryLogWriter != null )
                    binaryLogWriter.WriteImplementationWarningEvent("XHttpConnectionManager.ConnectionFailed",
                        LogMessageType.Warning, ex, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name,
                        "An unexpected exception is raised inside XHttpConnectionManager.ConnectionFailed method. Most likely, something must be fixed.");
            }
        }
        /// <summary>
        /// Processes the sending request on the server side.
        /// </summary>
        /// <param name="xHttpConnection">The connection.</param>
        /// <param name="xHttpPhysicalConnection">The physical connection.</param>
        /// <param name="inputStream">The connection.</param>
        private void Pool_Server_ProcessSenderRequest(XHttpConnection xHttpConnection, XHttpPhysicalConnection xHttpPhysicalConnection, Stream inputStream)
        {
            Exception gotException = null;

            try
            {
                this.LowLevel_ParseLabelledStream(inputStream, xHttpPhysicalConnection);
                inputStream.Close();
            }
            catch(Exception ex)
            {
                gotException = ex;

                // LOG:
                BinaryLogWriter binaryLogWriter = this.ITransportContext.BinaryLogWriter;
                if ( binaryLogWriter != null && binaryLogWriter[LogCategory.Connection] > 0 )
                {
                    binaryLogWriter.WriteEvent(LogCategory.Connection, "XHttpConnectionManager.Pool_Server_ProcessSenderRequest",
                        LogMessageType.ReceivingFinished, ex,
                        null, xHttpConnection.Remote, null,
                        GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name,
                        null, null,
                        xHttpConnection.DbgConnectionId, 0, 0, 0, null, null, null, null,
                        "Error occurred while parsing HTTP Sender Request. Sequence No: {0}.",
                        xHttpPhysicalConnection.SequenceNo);
                }
            }

            if (gotException != null)
            {
                gotException = OperationException.WrapException(gotException);
                GenuineChunkedStream outputStream = new GenuineChunkedStream(false);
                BinaryFormatter binaryFormatter = new BinaryFormatter(new RemotingSurrogateSelector(), new StreamingContext(StreamingContextStates.Other));
                binaryFormatter.Serialize(outputStream, gotException);

                this.LowLevel_SendHttpContent(GenuineUtility.GetTimeout(xHttpConnection.CloseConnectionAfterInactivity),
                    null, null, gotException, null, xHttpPhysicalConnection,
                    GenuineConnectionType.Persistent, HttpPacketType.SenderError,
                    false, true, true, false);
            }
            else
            {
                // serialize and send the OK response
                this.LowLevel_SendHttpContent(GenuineUtility.GetTimeout(xHttpConnection.CloseConnectionAfterInactivity),
                    null, null, null, null, xHttpPhysicalConnection, GenuineConnectionType.Persistent,
                    HttpPacketType.SenderResponse, false, true, true, false);
            }
        }
        /// <summary>
        /// Processes the listening request on the server side.
        /// </summary>
        /// <param name="xHttpConnection">The connection.</param>
        /// <param name="xHttpPhysicalConnection">The physical connection.</param>
        private void Pool_Server_ProcessListenerRequest(XHttpConnection xHttpConnection, XHttpPhysicalConnection xHttpPhysicalConnection)
        {
            lock (xHttpConnection.Listener.PhysicalConnectionStateLock)
            {
                try
                {
                    Message message = xHttpConnection.MessageContainer.GetMessage();
                    if (message == null)
                    {
                        // no data is available, postpone the request
            //						xHttpPhysicalConnection.Listener_Opened = GenuineUtility.TickCount;
                        xHttpPhysicalConnection.MarkAsAvailable();
                        return;
                    }

                    // some data is available, gather the stream and send it
                    this.LowLevel_SendHttpContent(GenuineUtility.GetTimeout(xHttpConnection.CloseConnectionAfterInactivity),
                        message, null, null, xHttpConnection.MessageContainer, xHttpPhysicalConnection,
                        xHttpConnection.GenuineConnectionType, HttpPacketType.Usual,
                        false, true, true, true);
                }
                catch(Exception ex)
                {
                    // LOG:
                    BinaryLogWriter binaryLogWriter = this.ITransportContext.BinaryLogWriter;
                    if ( binaryLogWriter != null && binaryLogWriter[LogCategory.Connection] > 0 )
                    {
                        binaryLogWriter.WriteEvent(LogCategory.Connection, "XHttpConnectionManager.Pool_Server_ProcessListenerRequest",
                            LogMessageType.AsynchronousSendingStarted, ex,
                            null, xHttpPhysicalConnection.Remote, null,
                            GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name,
                            null, null,
                            xHttpConnection.DbgConnectionId, 0, 0, 0, null, null, null, null,
                            "Error occurred while sending HTTP Listener Request. Sequence No: {0}.",
                            xHttpPhysicalConnection.SequenceNo);
                    }
                }
            }
        }
        /// <summary>
        /// Creates and registers a logical connection to the specified host.
        /// </summary>
        /// <param name="remote">The remote host.</param>
        /// <param name="primaryUri">The primary uri of the remote host.</param>
        /// <param name="isClient">The type of the behavior applying to the connection.</param>
        /// <param name="connectionName">Connection name.</param>
        /// <returns>The created connection.</returns>
        private XHttpConnection Pool_CreateConnection(HostInformation remote, string primaryUri, bool isClient, string connectionName)
        {
            BinaryLogWriter binaryLogWriter = this.ITransportContext.BinaryLogWriter;

            if (connectionName == null)
                connectionName = this.GetUniqueConnectionName();

            using (new ReaderAutoLocker(this._disposeLock))
            {
                XHttpConnection xHttpConnection = new XHttpConnection(this, isClient, connectionName);
                xHttpConnection.Remote = remote;
                xHttpConnection.CloseConnectionAfterInactivity = GenuineUtility.ConvertToMilliseconds(this.ITransportContext.IParameterProvider[GenuineParameter.ClosePersistentConnectionAfterInactivity]);
                xHttpConnection.GenuineConnectionType = GenuineConnectionType.Persistent;

                xHttpConnection.Sender = new XHttpPhysicalConnection(xHttpConnection, true);
                xHttpConnection.Listener = new XHttpPhysicalConnection(xHttpConnection, false);

                xHttpConnection.MessageContainer = new MessageContainer(this.ITransportContext);

                this._persistent.Set(primaryUri, connectionName, xHttpConnection);

                // and CLSS
                string securitySessionName = this.ITransportContext.IParameterProvider[GenuineParameter.SecuritySessionForPersistentConnections] as string;
                if (securitySessionName != null)
                {
                    xHttpConnection.Sender.ConnectionLevelSecurity = this.ITransportContext.IKeyStore.GetKey(securitySessionName).CreateSecuritySession(securitySessionName, null);
                    xHttpConnection.Listener.ConnectionLevelSecurity = this.ITransportContext.IKeyStore.GetKey(securitySessionName).CreateSecuritySession(securitySessionName, null);
                }

                // LOG:
                if ( binaryLogWriter != null && binaryLogWriter[LogCategory.Connection] > 0 )
                {
                    binaryLogWriter.WriteConnectionParameterEvent(LogCategory.Connection, "XHttpConnectionManager.Pool_CreateConnection",
                        LogMessageType.ConnectionParameters, null, remote, this.ITransportContext.IParameterProvider,
                        GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, xHttpConnection.DbgConnectionId,
                        "An XHTTP connection is being established.");
                }

                return xHttpConnection;
            }
        }
        /// <summary>
        /// Constructs an instance of the XHttpPhysicalConnection class.
        /// </summary>
        /// <param name="xHttpConnection">The physical connection.</param>
        /// <param name="sender">The sender.</param>
        public XHttpPhysicalConnection(XHttpConnection xHttpConnection, bool sender)
        {
            this.XHttpConnection = xHttpConnection;
            this.IsSender = sender;

            this.AsyncSendBuffer = new byte[35000];
            this.AsyncReceiveBuffer = new byte[35000];

            #if DEBUG
            this._connectionNumber = Interlocked.Increment(ref _TotalConnections);
            #endif
        }