private void ProcessCloseOrTerminateReply(bool close, Message reply)
        {
            if (reply == null)
            {
                // In the close case, the requestor is configured to throw TimeoutException instead of returning null.
                // In the terminate case, this value can be null, but the caller should not call this method.
                throw Fx.AssertAndThrow("Argument reply cannot be null.");
            }

            ReliableRequestor requestor = close ? _closeRequestor : _terminateRequestor;
            WsrmMessageInfo   info      = requestor.GetInfo();

            // Some other thread has verified and cleaned up the reply, no more work to do.
            if (info != null)
            {
                return;
            }

            try
            {
                info = WsrmMessageInfo.Get(Settings.MessageVersion, Settings.ReliableMessagingVersion,
                                           _binder.Channel, _binder.GetInnerSession(), reply);
                ReliableSession.ProcessInfo(info, null, true);
                ReliableSession.VerifyDuplexProtocolElements(info, null, true);

                WsrmFault fault = close
                    ? WsrmUtilities.ValidateCloseSequenceResponse(_session, requestor.MessageId, info,
                                                                  Connection.Last)
                    : WsrmUtilities.ValidateTerminateSequenceResponse(_session, requestor.MessageId, info,
                                                                      Connection.Last);

                if (fault != null)
                {
                    ReliableSession.OnLocalFault(null, fault, null);
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(fault.CreateException());
                }
            }
            finally
            {
                reply.Close();
            }
        }
        protected override void OnWriteBodyContents(XmlDictionaryWriter writer)
        {
            WsrmFeb2005Dictionary wsrmFeb2005Dictionary = XD.WsrmFeb2005Dictionary;
            XmlDictionaryString   wsrmNs = WsrmIndex.GetNamespace(_reliableMessagingVersion);

            writer.WriteStartElement(wsrmFeb2005Dictionary.CreateSequence, wsrmNs);

            EndpointAddress localAddress = _binder.LocalAddress;

            localAddress.WriteTo(_addressingVersion, writer, wsrmFeb2005Dictionary.AcksTo, wsrmNs);

            if (_offerIdentifier != null)
            {
                writer.WriteStartElement(wsrmFeb2005Dictionary.Offer, wsrmNs);
                writer.WriteStartElement(wsrmFeb2005Dictionary.Identifier, wsrmNs);
                writer.WriteValue(_offerIdentifier);
                writer.WriteEndElement();

                if (_reliableMessagingVersion == ReliableMessagingVersion.WSReliableMessaging11)
                {
                    Wsrm11Dictionary wsrm11Dictionary = DXD.Wsrm11Dictionary;
                    localAddress.WriteTo(_addressingVersion, writer, wsrm11Dictionary.Endpoint, wsrmNs);

                    writer.WriteStartElement(wsrm11Dictionary.IncompleteSequenceBehavior, wsrmNs);
                    writer.WriteValue(
                        _ordered ? wsrm11Dictionary.DiscardFollowingFirstGap : wsrm11Dictionary.NoDiscard);
                    writer.WriteEndElement();
                }

                writer.WriteEndElement();
            }

            ISecureConversationSession securitySession = _binder.GetInnerSession() as ISecureConversationSession;

            if (securitySession != null)
            {
                securitySession.WriteSessionTokenIdentifier(writer);
            }

            writer.WriteEndElement();
        }