/// <summary>
        /// Requests asynchronous processing of a method call on the current sink.
        /// </summary>
        /// <param name="sinkStack">A stack of channel sinks that called this sink.</param>
        /// <param name="msg">The message to process.</param>
        /// <param name="headers">The headers to add to the outgoing message heading to the server.</param>
        /// <param name="stream">The stream headed to the transport sink.</param>
        public void AsyncProcessRequest(IClientChannelSinkStack sinkStack, IMessage msg, 
            ITransportHeaders headers, Stream stream)
        {
            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, headers, stream, false);
            message.Recipient = iTransportContext.KnownHosts[this._recipientUri];
            IMethodMessage iMethodMessage = (IMethodMessage) msg;
            message.IsOneWay = RemotingServices.IsOneWay(iMethodMessage.MethodBase);

            // LOG: put down the log record
            BinaryLogWriter binaryLogWriter = this.ITransportContext.BinaryLogWriter;
            if ( binaryLogWriter != null && binaryLogWriter[LogCategory.MessageProcessing] > 0 )
            {
                binaryLogWriter.WriteMessageCreatedEvent("GenuineTcpClientTransportSink.AsyncProcessRequest",
                    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,
                    "Asynchronous .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.AsyncProcessRequest",
                    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 asynchronous invocation is being initiated.");
            }

            // register the response handler
            AsyncSinkStackResponseProcessor asyncSinkStackResponseProcessor = null;
            if (! message.IsOneWay)
            {
                asyncSinkStackResponseProcessor = new AsyncSinkStackResponseProcessor(iTransportContext, message, sinkStack);
                iTransportContext.IIncomingStreamHandler.RegisterResponseProcessor(message.MessageId, asyncSinkStackResponseProcessor);
            }

            try
            {
                // and try to send the message
                iTransportContext.ConnectionManager.Send(message);
            }
            catch(Exception ex)
            {
                asyncSinkStackResponseProcessor.DispatchException(ex);
                throw;
            }
        }
        /// <summary>
        /// Requests asynchronous processing of a method call on the current sink.
        /// </summary>
        /// <param name="sinkStack">A stack of channel sinks that called this sink.</param>
        /// <param name="msg">The message to process.</param>
        /// <param name="headers">The headers to add to the outgoing message heading to the server.</param>
        /// <param name="stream">The stream headed to the transport sink.</param>
        public void AsyncProcessRequest(IClientChannelSinkStack sinkStack, IMessage msg,
                                        ITransportHeaders headers, Stream stream)
        {
            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, headers, stream, false);

            message.Recipient = iTransportContext.KnownHosts[this._recipientUri];
            IMethodMessage iMethodMessage = (IMethodMessage)msg;

            message.IsOneWay = RemotingServices.IsOneWay(iMethodMessage.MethodBase);

            // LOG: put down the log record
            BinaryLogWriter binaryLogWriter = this.ITransportContext.BinaryLogWriter;

            if (binaryLogWriter != null && binaryLogWriter[LogCategory.MessageProcessing] > 0)
            {
                binaryLogWriter.WriteMessageCreatedEvent("GenuineTcpClientTransportSink.AsyncProcessRequest",
                                                         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,
                                                         "Asynchronous .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.AsyncProcessRequest",
                                           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 asynchronous invocation is being initiated.");
            }

            // register the response handler
            AsyncSinkStackResponseProcessor asyncSinkStackResponseProcessor = null;

            if (!message.IsOneWay)
            {
                asyncSinkStackResponseProcessor = new AsyncSinkStackResponseProcessor(iTransportContext, message, sinkStack);
                iTransportContext.IIncomingStreamHandler.RegisterResponseProcessor(message.MessageId, asyncSinkStackResponseProcessor);
            }

            try
            {
                // and try to send the message
                iTransportContext.ConnectionManager.Send(message);
            }
            catch (Exception ex)
            {
                asyncSinkStackResponseProcessor.DispatchException(ex);
                throw;
            }
        }