protected override void OnOpen(TimeSpan timeout)
        {
            if (!is_service_side)
            {
                NetworkStream ns = client.GetStream();
                frame = new TcpBinaryFrameManager(TcpBinaryFrameManager.DuplexMode, ns, is_service_side)
                {
                    Encoder = this.Encoder,
                    Via     = this.Via
                };
                frame.ProcessPreambleInitiator();
                frame.ProcessPreambleAckInitiator();
                session = new TcpDuplexSession(this);                  // make sure to shutdown the session once it has initiated one.
            }
            else
            {
                // server side
                Stream s = client.GetStream();

                frame = new TcpBinaryFrameManager(TcpBinaryFrameManager.DuplexMode, s, is_service_side)
                {
                    Encoder = this.Encoder
                };

                // FIXME: use retrieved record properties in the request processing.

                frame.ProcessPreambleRecipient();
                frame.ProcessPreambleAckRecipient();
            }
        }
        public override Message Request(Message input, TimeSpan timeout)
        {
            DateTime start = DateTime.Now;

            // FIXME: use timeouts.
            frame.ProcessPreambleInitiator();
            frame.ProcessPreambleAckInitiator();

            if (input.Headers.To == null)
            {
                input.Headers.To = RemoteAddress.Uri;
            }
            if (input.Headers.MessageId == null)
            {
                input.Headers.MessageId = new UniqueId();
            }

            Logger.LogMessage(MessageLogSourceKind.TransportSend, ref input, int.MaxValue);              // It is not a receive buffer

            frame.WriteUnsizedMessage(input, timeout - (DateTime.Now - start));

            // LAMESPEC: it contradicts the protocol described at section 3.1.1.1.1 in [MC-NMF].
            // Moving this WriteEndRecord() after ReadUnsizedMessage() causes TCP connection blocking.
            frame.WriteEndRecord();

            var ret = frame.ReadUnsizedMessage(timeout - (DateTime.Now - start));

            Logger.LogMessage(MessageLogSourceKind.TransportReceive, ref ret, info.BindingElement.MaxReceivedMessageSize);

            frame.ReadEndRecord();              // both
            return(ret);
        }