/// <summary>
        /// Requests message processing from the current sink.
        /// </summary>
        /// <param name="msg">The message to process.</param>
        /// <param name="requestHeaders">The headers to add to the outgoing message heading to the server.</param>
        /// <param name="requestStream">The stream headed to the transport sink.</param>
        /// <param name="responseHeaders">When this method returns, contains an ITransportHeaders interface that holds the headers that the server returned. This parameter is passed uninitialized.</param>
        /// <param name="responseStream">When this method returns, contains a Stream coming back from the transport sink. This parameter is passed uninitialized.</param>
        public void ProcessMessage(IMessage msg, ITransportHeaders requestHeaders, Stream requestStream,
            out ITransportHeaders responseHeaders, out Stream responseStream)
        {
            BinaryLogWriter binaryLogWriter = this.ITransportContext.BinaryLogWriter;
            ITransportContext iTransportContext = this.ITransportContext;

            if (! GenuineUtility.CheckUrlOnConnectivity(this._recipientUri))
            {
                // get the transport context from the Uri Storage
                iTransportContext = UriStorage.GetTransportContext(this._recipientUri);
                if (iTransportContext == null)
                    iTransportContext = this.ITransportContext;
            }

            Message message = Message.CreateOutcomingMessage(iTransportContext, msg, requestHeaders, requestStream, true);

            try
            {
                message.Recipient = iTransportContext.KnownHosts[this._recipientUri];

                // LOG: put down the log record
                if ( binaryLogWriter != null && binaryLogWriter[LogCategory.MessageProcessing] > 0 )
                {
                    binaryLogWriter.WriteMessageCreatedEvent("GenuineTcpClientTransportSink.ProcessMessage",
                        LogMessageType.MessageCreated, null, message, true, message.Recipient,
                        this.ITransportContext.BinaryLogWriter[LogCategory.MessageProcessing] > 1 ? message.Stream : null,
                        msg.Properties["__Uri"] as string, BinaryLogWriter.ParseInvocationMethod(msg.Properties["__MethodName"] as string, msg.Properties["__TypeName"] as string),
                        GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, null, -1, -1, null, -1, null,
                        "Synchronous .NET Remoting invocaiton is being initiated.");

                    message.ITransportHeaders[Message.TransportHeadersInvocationTarget] = msg.Properties["__Uri"] as string;
                    message.ITransportHeaders[Message.TransportHeadersMethodName] = BinaryLogWriter.ParseInvocationMethod(msg.Properties["__MethodName"] as string, msg.Properties["__TypeName"] as string);

                    binaryLogWriter.WriteEvent(LogCategory.MessageProcessing, "GenuineTcpClientTransportSink.ProcessMessage",
                        LogMessageType.MessageRequestInvoking, null, message, message.Recipient,
                        null,
                        GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name,
                        null, null, -1, GenuineUtility.TickCount, 0, 0, null, null, null, null,
                        "The .NET Remoting synchronous invocation has been made.");
                }

                SyncSinkStackResponseProcessor syncSinkStackResponseProcessor = new SyncSinkStackResponseProcessor(iTransportContext, message);
                iTransportContext.IIncomingStreamHandler.RegisterResponseProcessor(message.MessageId, syncSinkStackResponseProcessor);
                message.CancelSending = syncSinkStackResponseProcessor.IsReceivedEvent;

                try
                {
                    // send the message or initiate the sending
                    iTransportContext.ConnectionManager.Send(message);
                }
                catch(Exception ex)
                {
                    // if it's a response processor's problem, force its exception to be fired
                    if (syncSinkStackResponseProcessor.DispatchedException != null)
                        throw OperationException.WrapException(syncSinkStackResponseProcessor.DispatchedException);

                    syncSinkStackResponseProcessor.DispatchException(ex);
                    throw;
                }

                if (! GenuineUtility.WaitOne(syncSinkStackResponseProcessor.IsReceivedEvent, GenuineUtility.GetMillisecondsLeft(message.FinishTime)) )
                    throw GenuineExceptions.Get_Send_ServerDidNotReply();
                if (syncSinkStackResponseProcessor.DispatchedException != null)
                    throw OperationException.WrapException(syncSinkStackResponseProcessor.DispatchedException);

                // LOG: put down the log record
                if ( binaryLogWriter != null && binaryLogWriter[LogCategory.MessageProcessing] > 0 )
                {
                    binaryLogWriter.WriteEvent(LogCategory.MessageProcessing, "GenuineTcpClientTransportSink.ProcessMessage",
                        LogMessageType.MessageDispatched, null, syncSinkStackResponseProcessor.Response, syncSinkStackResponseProcessor.Response.Sender,
                        null,
                        GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name,
                        null, null, -1,
                        GenuineUtility.TickCount, 0, message.SeqNo, null, null, null, null,
                        "The .NET Remoting synchronous invocation has been completed.");

                }

                responseHeaders = syncSinkStackResponseProcessor.Response.ITransportHeaders;
                responseStream = syncSinkStackResponseProcessor.Response.Stream;
            }
            catch(Exception ex)
            {
                // LOG: put down the log record
                if ( binaryLogWriter != null && binaryLogWriter[LogCategory.MessageProcessing] > 0 )
                    binaryLogWriter.WriteEvent(LogCategory.MessageProcessing, "GenuineTcpClientTransportSink.ProcessMessage",
                        LogMessageType.MessageDispatched, ex, message, message.Recipient, null,
                        GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, null, null, -1,
                        GenuineUtility.TickCount, 0, message.SeqNo, null, null, null, null,
                        "The exception is dispatched to the caller context.");

                throw;
            }
        }
        /// <summary>
        /// Requests message processing from the current sink.
        /// </summary>
        /// <param name="msg">The message to process.</param>
        /// <param name="requestHeaders">The headers to add to the outgoing message heading to the server.</param>
        /// <param name="requestStream">The stream headed to the transport sink.</param>
        /// <param name="responseHeaders">When this method returns, contains an ITransportHeaders interface that holds the headers that the server returned. This parameter is passed uninitialized.</param>
        /// <param name="responseStream">When this method returns, contains a Stream coming back from the transport sink. This parameter is passed uninitialized.</param>
        public void ProcessMessage(IMessage msg, ITransportHeaders requestHeaders, Stream requestStream,
                                   out ITransportHeaders responseHeaders, out Stream responseStream)
        {
            BinaryLogWriter   binaryLogWriter   = this.ITransportContext.BinaryLogWriter;
            ITransportContext iTransportContext = this.ITransportContext;

            if (!GenuineUtility.CheckUrlOnConnectivity(this._recipientUri))
            {
                // get the transport context from the Uri Storage
                iTransportContext = UriStorage.GetTransportContext(this._recipientUri);
                if (iTransportContext == null)
                {
                    iTransportContext = this.ITransportContext;
                }
            }

            Message message = Message.CreateOutcomingMessage(iTransportContext, msg, requestHeaders, requestStream, true);

            try
            {
                message.Recipient = iTransportContext.KnownHosts[this._recipientUri];

                // LOG: put down the log record
                if (binaryLogWriter != null && binaryLogWriter[LogCategory.MessageProcessing] > 0)
                {
                    binaryLogWriter.WriteMessageCreatedEvent("GenuineTcpClientTransportSink.ProcessMessage",
                                                             LogMessageType.MessageCreated, null, message, true, message.Recipient,
                                                             this.ITransportContext.BinaryLogWriter[LogCategory.MessageProcessing] > 1 ? message.Stream : null,
                                                             msg.Properties["__Uri"] as string, BinaryLogWriter.ParseInvocationMethod(msg.Properties["__MethodName"] as string, msg.Properties["__TypeName"] as string),
                                                             GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, null, -1, -1, null, -1, null,
                                                             "Synchronous .NET Remoting invocaiton is being initiated.");

                    message.ITransportHeaders[Message.TransportHeadersInvocationTarget] = msg.Properties["__Uri"] as string;
                    message.ITransportHeaders[Message.TransportHeadersMethodName]       = BinaryLogWriter.ParseInvocationMethod(msg.Properties["__MethodName"] as string, msg.Properties["__TypeName"] as string);

                    binaryLogWriter.WriteEvent(LogCategory.MessageProcessing, "GenuineTcpClientTransportSink.ProcessMessage",
                                               LogMessageType.MessageRequestInvoking, null, message, message.Recipient,
                                               null,
                                               GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name,
                                               null, null, -1, GenuineUtility.TickCount, 0, 0, null, null, null, null,
                                               "The .NET Remoting synchronous invocation has been made.");
                }

                SyncSinkStackResponseProcessor syncSinkStackResponseProcessor = new SyncSinkStackResponseProcessor(iTransportContext, message);
                iTransportContext.IIncomingStreamHandler.RegisterResponseProcessor(message.MessageId, syncSinkStackResponseProcessor);
                message.CancelSending = syncSinkStackResponseProcessor.IsReceivedEvent;

                try
                {
                    // send the message or initiate the sending
                    iTransportContext.ConnectionManager.Send(message);
                }
                catch (Exception ex)
                {
                    // if it's a response processor's problem, force its exception to be fired
                    if (syncSinkStackResponseProcessor.DispatchedException != null)
                    {
                        throw OperationException.WrapException(syncSinkStackResponseProcessor.DispatchedException);
                    }

                    syncSinkStackResponseProcessor.DispatchException(ex);
                    throw;
                }

                if (!GenuineUtility.WaitOne(syncSinkStackResponseProcessor.IsReceivedEvent, GenuineUtility.GetMillisecondsLeft(message.FinishTime)))
                {
                    throw GenuineExceptions.Get_Send_ServerDidNotReply();
                }
                if (syncSinkStackResponseProcessor.DispatchedException != null)
                {
                    throw OperationException.WrapException(syncSinkStackResponseProcessor.DispatchedException);
                }

                // LOG: put down the log record
                if (binaryLogWriter != null && binaryLogWriter[LogCategory.MessageProcessing] > 0)
                {
                    binaryLogWriter.WriteEvent(LogCategory.MessageProcessing, "GenuineTcpClientTransportSink.ProcessMessage",
                                               LogMessageType.MessageDispatched, null, syncSinkStackResponseProcessor.Response, syncSinkStackResponseProcessor.Response.Sender,
                                               null,
                                               GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name,
                                               null, null, -1,
                                               GenuineUtility.TickCount, 0, message.SeqNo, null, null, null, null,
                                               "The .NET Remoting synchronous invocation has been completed.");
                }

                responseHeaders = syncSinkStackResponseProcessor.Response.ITransportHeaders;
                responseStream  = syncSinkStackResponseProcessor.Response.Stream;
            }
            catch (Exception ex)
            {
                // LOG: put down the log record
                if (binaryLogWriter != null && binaryLogWriter[LogCategory.MessageProcessing] > 0)
                {
                    binaryLogWriter.WriteEvent(LogCategory.MessageProcessing, "GenuineTcpClientTransportSink.ProcessMessage",
                                               LogMessageType.MessageDispatched, ex, message, message.Recipient, null,
                                               GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, null, null, -1,
                                               GenuineUtility.TickCount, 0, message.SeqNo, null, null, null, null,
                                               "The exception is dispatched to the caller context.");
                }

                throw;
            }
        }