WsrmMessageInfo.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ WCF / WCF / 3.5.30729.1 / untmp / Orcas / SP / ndp / cdf / src / WCF / ServiceModel / System / ServiceModel / Channels / WsrmMessageInfo.cs / 2 / WsrmMessageInfo.cs

                            //---------------------------------------------------------------------------- 
// Copyright (c) Microsoft Corporation.  All rights reserved.
//---------------------------------------------------------------------------
namespace System.ServiceModel.Channels
{ 
    using System;
    using System.Collections; 
    using System.Collections.Generic; 
    using System.Collections.ObjectModel;
    using System.Diagnostics; 
    using System.Globalization;
    using System.Runtime.Serialization;
    using System.ServiceModel;
    using System.ServiceModel.Diagnostics; 
    using System.ServiceModel.Security;
    using System.Xml; 
 
    sealed class WsrmMessageInfo
    { 
        WsrmAcknowledgmentInfo acknowledgementInfo;
        WsrmAckRequestedInfo ackRequestedInfo;
        string action;
        CloseSequenceInfo closeSequenceInfo; 
        CloseSequenceResponseInfo closeSequenceResponseInfo;
        CreateSequenceInfo createSequenceInfo; 
        CreateSequenceResponseInfo createSequenceResponseInfo; 
        Exception faultException;
        MessageFault faultInfo; 
        Message faultReply;
        Message message;
        Exception parsingException;
        WsrmSequencedMessageInfo sequencedMessageInfo; 
        TerminateSequenceInfo terminateSequenceInfo;
        TerminateSequenceResponseInfo terminateSequenceResponseInfo; 
        WsrmUsesSequenceSSLInfo usesSequenceSSLInfo; 
        WsrmUsesSequenceSTRInfo usesSequenceSTRInfo;
 
        public WsrmMessageInfo()
        {
        }
 
        public WsrmAcknowledgmentInfo AcknowledgementInfo
        { 
            get 
            {
                return acknowledgementInfo; 
            }
        }

        public WsrmAckRequestedInfo AckRequestedInfo 
        {
            get 
            { 
                return this.ackRequestedInfo;
            } 
        }

        public string Action
        { 
            get
            { 
                return this.action; 
            }
        } 

        public CloseSequenceInfo CloseSequenceInfo
        {
            get 
            {
                return this.closeSequenceInfo; 
            } 
        }
 
        public CloseSequenceResponseInfo CloseSequenceResponseInfo
        {
            get
            { 
                return this.closeSequenceResponseInfo;
            } 
        } 

        public CreateSequenceInfo CreateSequenceInfo 
        {
            get
            {
                return this.createSequenceInfo; 
            }
        } 
 
        public CreateSequenceResponseInfo CreateSequenceResponseInfo
        { 
            get
            {
                return this.createSequenceResponseInfo;
            } 
        }
 
        public Exception FaultException 
        {
            get 
            {
                return this.faultException;
            }
            set 
            {
                if (this.faultException != null) 
                { 
                    DiagnosticUtility.DebugAssert("FaultException can only be set once.");
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperInternal(false); 
                }

                this.faultException = value;
            } 
        }
 
        public MessageFault FaultInfo 
        {
            get 
            {
                return this.faultInfo;
            }
        } 

        public Message FaultReply 
        { 
            get
            { 
                return this.faultReply;
            }
            set
            { 
                if (this.faultReply != null)
                { 
                    DiagnosticUtility.DebugAssert("FaultReply can only be set once."); 
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperInternal(false);
                } 

                this.faultReply = value;
            }
        } 

        public Message Message 
        { 
            get
            { 
                return this.message;
            }
        }
 
        public MessageFault MessageFault
        { 
            get 
            {
                return this.faultInfo; 
            }
        }

        public Exception ParsingException 
        {
            get 
            { 
                return this.parsingException;
            } 
        }

        public WsrmSequencedMessageInfo SequencedMessageInfo
        { 
            get
            { 
                return sequencedMessageInfo; 
            }
        } 

        public TerminateSequenceInfo TerminateSequenceInfo
        {
            get 
            {
                return terminateSequenceInfo; 
            } 
        }
 
        public TerminateSequenceResponseInfo TerminateSequenceResponseInfo
        {
            get
            { 
                return terminateSequenceResponseInfo;
            } 
        } 

        public WsrmUsesSequenceSSLInfo UsesSequenceSSLInfo 
        {
            get
            {
                return usesSequenceSSLInfo; 
            }
        } 
 
        public WsrmUsesSequenceSTRInfo UsesSequenceSTRInfo
        { 
            get
            {
                return usesSequenceSTRInfo;
            } 
        }
 
        public WsrmHeaderFault WsrmHeaderFault 
        {
            get 
            {
                return this.faultInfo as WsrmHeaderFault;
            }
        } 

        public static Exception CreateInternalFaultException(Message faultReply, string message, Exception inner) 
        { 
            return new InternalFaultException(faultReply, SR.GetString(SR.WsrmMessageProcessingError, message), inner);
        } 

        static Exception CreateWsrmRequiredException(MessageVersion messageVersion)
        {
            string exceptionReason = SR.GetString(SR.WsrmRequiredExceptionString); 
            string faultReason = SR.GetString(SR.WsrmRequiredFaultString);
            Message faultReply = new WsrmRequiredFault(faultReason).CreateMessage(messageVersion, 
                ReliableMessagingVersion.WSReliableMessaging11); 
            return CreateInternalFaultException(faultReply, exceptionReason, new ProtocolException(exceptionReason));
        } 

        // Caller should check these things:
        // FaultReply and FaultException, FaultInfo and FaultException or ParsingException
        public static WsrmMessageInfo Get(MessageVersion messageVersion, 
            ReliableMessagingVersion reliableMessagingVersion, IChannel channel, ISession session, Message message)
        { 
            return Get(messageVersion, reliableMessagingVersion, channel, session, message, false); 
        }
 
        public static WsrmMessageInfo Get(MessageVersion messageVersion,
            ReliableMessagingVersion reliableMessagingVersion, IChannel channel, ISession session, Message message,
            bool csrOnly)
        { 
            WsrmMessageInfo messageInfo = new WsrmMessageInfo();
            messageInfo.message = message; 
            bool isFault = true; 

            try 
            {
                isFault = message.IsFault;
                MessageHeaders headers = message.Headers;
                string action = headers.Action; 
                messageInfo.action = action;
                bool foundAction = false; 
                bool wsrmFeb2005 = reliableMessagingVersion == ReliableMessagingVersion.WSReliableMessagingFebruary2005; 
                bool wsrm11 = reliableMessagingVersion == ReliableMessagingVersion.WSReliableMessaging11;
                bool csOnly = false; 

                if (action == WsrmIndex.GetCreateSequenceResponseActionString(reliableMessagingVersion))
                {
                    messageInfo.createSequenceResponseInfo = CreateSequenceResponseInfo.ReadMessage(messageVersion, 
                        reliableMessagingVersion, message, headers);
                    ValidateMustUnderstand(messageVersion, message); 
                    return messageInfo; 
                }
 
                if (csrOnly)
                    return messageInfo;

                if (action == WsrmIndex.GetTerminateSequenceActionString(reliableMessagingVersion)) 
                {
                    messageInfo.terminateSequenceInfo = TerminateSequenceInfo.ReadMessage(messageVersion, 
                        reliableMessagingVersion, message, headers); 
                    foundAction = true;
                } 
                else if (action == WsrmIndex.GetCreateSequenceActionString(reliableMessagingVersion))
                {
                    messageInfo.createSequenceInfo = CreateSequenceInfo.ReadMessage(messageVersion,
                        reliableMessagingVersion, session as ISecureConversationSession, message, headers); 

                    if (wsrmFeb2005) 
                    { 
                        ValidateMustUnderstand(messageVersion, message);
                        return messageInfo; 
                    }

                    csOnly = true;
                } 
                else if (wsrm11)
                { 
                    if (action == Wsrm11Strings.CloseSequenceAction) 
                    {
                        messageInfo.closeSequenceInfo = CloseSequenceInfo.ReadMessage(messageVersion, message, 
                            headers);
                        foundAction = true;
                    }
                    else if (action == Wsrm11Strings.CloseSequenceResponseAction) 
                    {
                        messageInfo.closeSequenceResponseInfo = CloseSequenceResponseInfo.ReadMessage(messageVersion, 
                             message, headers); 
                        foundAction = true;
                    } 
                    else if (action == WsrmIndex.GetTerminateSequenceResponseActionString(reliableMessagingVersion))
                    {
                        messageInfo.terminateSequenceResponseInfo = TerminateSequenceResponseInfo.ReadMessage(messageVersion,
                             message, headers); 
                        foundAction = true;
                    } 
                } 

                string wsrmNs = WsrmIndex.GetNamespaceString(reliableMessagingVersion); 
                bool soap11 = messageVersion.Envelope == EnvelopeVersion.Soap11;
                bool foundHeader = false;
                int foundTooManyIndex = -1;
                int sequenceIndex = -1; 
                int ackIndex = -1;
                int ackRequestedIndex = -1; 
                int maxIndex = -1; 
                int minIndex = -1;
                int sequenceFaultIndex = -1; 
                int usesSequenceSSLIndex = -1;
                int usesSequenceSTRIndex = -1;

                for (int index = 0; index < headers.Count; index++) 
                {
                    MessageHeaderInfo header = headers[index]; 
 
                    if (!messageVersion.Envelope.IsUltimateDestinationActor(header.Actor))
                        continue; 

                    if (header.Namespace == wsrmNs)
                    {
                        bool setIndex = true; 

                        if (csOnly) 
                        { 
                            if (wsrm11 && (header.Name == Wsrm11Strings.UsesSequenceSSL))
                            { 
                                if (usesSequenceSSLIndex != -1)
                                {
                                    foundTooManyIndex = index;
                                    break; 
                                }
                                usesSequenceSSLIndex = index; 
                            } 
                            else if (wsrm11 && (header.Name == Wsrm11Strings.UsesSequenceSTR))
                            { 
                                if (usesSequenceSTRIndex != -1)
                                {
                                    foundTooManyIndex = index;
                                    break; 
                                }
                                usesSequenceSTRIndex = index; 
                            } 
                            else
                            { 
                                setIndex = false;
                            }
                        }
                        else 
                        {
                            if (header.Name == WsrmFeb2005Strings.Sequence) 
                            { 
                                if (sequenceIndex != -1)
                                { 
                                    foundTooManyIndex = index;
                                    break;
                                }
                                sequenceIndex = index; 
                            }
                            else if (header.Name == WsrmFeb2005Strings.SequenceAcknowledgement) 
                            { 
                                if (ackIndex != -1)
                                { 
                                    foundTooManyIndex = index;
                                    break;
                                }
                                ackIndex = index; 
                            }
                            else if (header.Name == WsrmFeb2005Strings.AckRequested) 
                            { 
                                if (ackRequestedIndex != -1)
                                { 
                                    foundTooManyIndex = index;
                                    break;
                                }
                                ackRequestedIndex = index; 
                            }
                            else if (soap11 && (header.Name == WsrmFeb2005Strings.SequenceFault)) 
                            { 
                                if (sequenceFaultIndex != -1)
                                { 
                                    foundTooManyIndex = index;
                                    break;
                                }
                                sequenceFaultIndex = index; 
                            }
                            else 
                            { 
                                setIndex = false;
                            } 
                        }

                        if (setIndex)
                        { 
                            if (index > maxIndex)
                                maxIndex = index; 
 
                            if (minIndex == -1)
                                minIndex = index; 
                        }
                    }
                }
 
                if (foundTooManyIndex != -1)
                { 
                    Collection notUnderstoodHeaders = new Collection(); 
                    notUnderstoodHeaders.Add(headers[foundTooManyIndex]);
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( 
                        new MustUnderstandSoapException(notUnderstoodHeaders, messageVersion.Envelope));
                }

                if (maxIndex > -1) 
                {
                    BufferedMessage bufferedMessage = message as BufferedMessage; 
 
                    if (bufferedMessage != null && bufferedMessage.Headers.ContainsOnlyBufferedMessageHeaders)
                    { 
                        foundHeader = true;

                        using (XmlDictionaryReader reader = headers.GetReaderAtHeader(minIndex))
                        { 
                            for (int index = minIndex; index <= maxIndex; index++)
                            { 
                                MessageHeaderInfo header = headers[index]; 

                                if (csOnly) 
                                {
                                    if (wsrm11 && (index == usesSequenceSSLIndex))
                                    {
                                        messageInfo.usesSequenceSSLInfo = WsrmUsesSequenceSSLInfo.ReadHeader( 
                                            reader, header);
                                        headers.UnderstoodHeaders.Add(header); 
                                    } 
                                    else if (wsrm11 && (index == usesSequenceSTRIndex))
                                    { 
                                        messageInfo.usesSequenceSTRInfo = WsrmUsesSequenceSTRInfo.ReadHeader(
                                            reader, header);
                                        headers.UnderstoodHeaders.Add(header);
                                    } 
                                    else
                                    { 
                                        reader.Skip(); 
                                    }
                                } 
                                else
                                {
                                    if (index == sequenceIndex)
                                    { 
                                        messageInfo.sequencedMessageInfo = WsrmSequencedMessageInfo.ReadHeader(
                                            reliableMessagingVersion, reader, header); 
                                        headers.UnderstoodHeaders.Add(header); 
                                    }
                                    else if (index == ackIndex) 
                                    {
                                        messageInfo.acknowledgementInfo = WsrmAcknowledgmentInfo.ReadHeader(
                                            reliableMessagingVersion, reader, header);
                                        headers.UnderstoodHeaders.Add(header); 
                                    }
                                    else if (index == ackRequestedIndex) 
                                    { 
                                        messageInfo.ackRequestedInfo = WsrmAckRequestedInfo.ReadHeader(
                                            reliableMessagingVersion, reader, header); 
                                        headers.UnderstoodHeaders.Add(header);
                                    }
                                    else
                                    { 
                                        reader.Skip();
                                    } 
                                } 
                            }
                        } 
                    }
                }

                if (maxIndex > -1 && !foundHeader) 
                {
                    foundHeader = true; 
 
                    if (csOnly)
                    { 
                        if (usesSequenceSSLIndex != -1)
                        {
                            using (XmlDictionaryReader reader = headers.GetReaderAtHeader(usesSequenceSSLIndex))
                            { 
                                MessageHeaderInfo header = headers[usesSequenceSSLIndex];
                                messageInfo.usesSequenceSSLInfo = WsrmUsesSequenceSSLInfo.ReadHeader( 
                                    reader, header); 
                                headers.UnderstoodHeaders.Add(header);
                            } 
                        }

                        if (usesSequenceSTRIndex != -1)
                        { 
                            using (XmlDictionaryReader reader = headers.GetReaderAtHeader(usesSequenceSTRIndex))
                            { 
                                MessageHeaderInfo header = headers[usesSequenceSTRIndex]; 
                                messageInfo.usesSequenceSTRInfo = WsrmUsesSequenceSTRInfo.ReadHeader(
                                    reader, header); 
                                headers.UnderstoodHeaders.Add(header);
                            }
                        }
                    } 
                    else
                    { 
                        if (sequenceIndex != -1) 
                        {
                            using (XmlDictionaryReader reader = headers.GetReaderAtHeader(sequenceIndex)) 
                            {
                                MessageHeaderInfo header = headers[sequenceIndex];

                                messageInfo.sequencedMessageInfo = WsrmSequencedMessageInfo.ReadHeader( 
                                    reliableMessagingVersion, reader, header);
                                headers.UnderstoodHeaders.Add(header); 
                            } 
                        }
 
                        if (ackIndex != -1)
                        {
                            using (XmlDictionaryReader reader = headers.GetReaderAtHeader(ackIndex))
                            { 
                                MessageHeaderInfo header = headers[ackIndex];
                                messageInfo.acknowledgementInfo = WsrmAcknowledgmentInfo.ReadHeader( 
                                    reliableMessagingVersion, reader, header); 
                                headers.UnderstoodHeaders.Add(header);
                            } 
                        }

                        if (ackRequestedIndex != -1)
                        { 
                            using (XmlDictionaryReader reader = headers.GetReaderAtHeader(ackRequestedIndex))
                            { 
                                MessageHeaderInfo header = headers[ackRequestedIndex]; 
                                messageInfo.ackRequestedInfo = WsrmAckRequestedInfo.ReadHeader(reliableMessagingVersion,
                                    reader, header); 
                                headers.UnderstoodHeaders.Add(header);
                            }
                        }
                    } 
                }
 
                if (csOnly) 
                {
                    CreateSequenceInfo.ValidateCreateSequenceHeaders(messageVersion, 
                        session as ISecureConversationSession, messageInfo);
                    ValidateMustUnderstand(messageVersion, message);
                    return messageInfo;
                } 

                if (messageInfo.sequencedMessageInfo == null && messageInfo.action == null) 
                { 
                    if (wsrmFeb2005)
                    { 
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MessageHeaderException(SR.GetString(SR.NoActionNoSequenceHeaderReason), messageVersion.Addressing.Namespace, AddressingStrings.Action, false));
                    }
                    else
                    { 
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
                            CreateWsrmRequiredException(messageVersion)); 
                    } 
                }
 
                if (messageInfo.sequencedMessageInfo == null && message.IsFault)
                {
                    messageInfo.faultInfo = MessageFault.CreateFault(message, TransportDefaults.MaxRMFaultSize);
                    WsrmHeaderFault wsrmFault; 

                    if (soap11) 
                    { 
                        if (WsrmHeaderFault.TryCreateFault11(reliableMessagingVersion, message, messageInfo.faultInfo, sequenceFaultIndex, out wsrmFault))
                        { 
                            messageInfo.faultInfo = wsrmFault;
                            messageInfo.faultException = WsrmHeaderFault.CreateException(wsrmFault);
                        }
                    } 
                    else
                    { 
                        if (WsrmHeaderFault.TryCreateFault12(reliableMessagingVersion, message, messageInfo.faultInfo, out wsrmFault)) 
                        {
                            messageInfo.faultInfo = wsrmFault; 
                            messageInfo.faultException = WsrmHeaderFault.CreateException(wsrmFault);
                        }
                    }
 
                    // Not a wsrm fault, maybe it is another fault we should understand (i.e. addressing or soap fault).
                    if (wsrmFault == null) 
                    { 
                        FaultConverter faultConverter = channel.GetProperty();
 
                        if (faultConverter == null)
                        {
                            faultConverter = FaultConverter.GetDefaultFaultConverter(messageVersion);
                        } 

                        if (!faultConverter.TryCreateException(message, messageInfo.faultInfo, out messageInfo.faultException)) 
                        { 
                            messageInfo.faultException = new ProtocolException(SR.GetString(SR.UnrecognizedFaultReceived, messageInfo.faultInfo.Code.Namespace, messageInfo.faultInfo.Code.Name, System.ServiceModel.FaultException.GetSafeReasonText(messageInfo.faultInfo)));
                        } 
                    }

                    foundAction = true;
                } 

                if (!foundHeader && !foundAction) 
                { 
                    if (wsrmFeb2005)
                    { 
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
                            new ActionNotSupportedException(SR.GetString(SR.NonWsrmFeb2005ActionNotSupported, action)));
                    }
                    else 
                    {
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( 
                            CreateWsrmRequiredException(messageVersion)); 
                    }
                } 

                if (foundAction || WsrmUtilities.IsWsrmAction(reliableMessagingVersion, action))
                {
                    ValidateMustUnderstand(messageVersion, message); 
                }
            } 
            catch (InternalFaultException exception) 
            {
                if (DiagnosticUtility.ShouldTraceInformation) 
                    DiagnosticUtility.ExceptionUtility.TraceHandledException(exception, TraceEventType.Information);

                messageInfo.FaultReply = exception.FaultReply;
                messageInfo.faultException = exception.InnerException; 
            }
            catch (CommunicationException exception) 
            { 
                if (DiagnosticUtility.ShouldTraceInformation)
                    DiagnosticUtility.ExceptionUtility.TraceHandledException(exception, TraceEventType.Information); 

                if (isFault)
                {
                    messageInfo.parsingException = exception; 
                    return messageInfo;
                } 
 
                FaultConverter faultConverter = channel.GetProperty();
                if (faultConverter == null) 
                    faultConverter = FaultConverter.GetDefaultFaultConverter(messageVersion);

                if (faultConverter.TryCreateFaultMessage(exception, out messageInfo.faultReply))
                { 
                    messageInfo.faultException = new ProtocolException(SR.GetString(SR.MessageExceptionOccurred), exception);
                } 
                else 
                {
                    messageInfo.parsingException = new ProtocolException(SR.GetString(SR.MessageExceptionOccurred), exception); 
                }
            }
            catch (XmlException exception)
            { 
                if (DiagnosticUtility.ShouldTraceInformation)
                    DiagnosticUtility.ExceptionUtility.TraceHandledException(exception, TraceEventType.Information); 
 
                messageInfo.parsingException = new ProtocolException(SR.GetString(SR.MessageExceptionOccurred), exception);
            } 

            return messageInfo;
        }
 
        static void ValidateMustUnderstand(MessageVersion version, Message message)
        { 
            Collection notUnderstoodHeaders = message.Headers.GetHeadersNotUnderstood(); 
            if ((notUnderstoodHeaders != null) && (notUnderstoodHeaders.Count > 0))
            { 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
                    new MustUnderstandSoapException(notUnderstoodHeaders, version.Envelope));
            }
        } 

        [Serializable] 
        class InternalFaultException : ProtocolException 
        {
            Message faultReply; 

            public InternalFaultException()
                : base()
            { 
            }
 
            public InternalFaultException(Message faultReply, string message, Exception inner) 
                : base(message, inner)
            { 
                this.faultReply = faultReply;
            }

            protected InternalFaultException(SerializationInfo info, StreamingContext context) 
                : base(info, context)
            { 
            } 

            public Message FaultReply 
            {
                get
                {
                    return this.faultReply; 
                }
            } 
        } 
    }
 
    sealed class CloseSequenceInfo : WsrmRequestInfo
    {
        UniqueId identifier;
        Int64 lastMsgNumber; 

        public UniqueId Identifier 
        { 
            get
            { 
                return this.identifier;
            }
            set
            { 
                this.identifier = value;
            } 
        } 

        public Int64 LastMsgNumber 
        {
            get
            {
                return this.lastMsgNumber; 
            }
            set 
            { 
                this.lastMsgNumber = value;
            } 
        }

        public override string RequestName
        { 
            get
            { 
                return Wsrm11Strings.CloseSequence; 
            }
        } 

        public static CloseSequenceInfo ReadMessage(MessageVersion messageVersion, Message message,
            MessageHeaders headers)
        { 
            if (message.IsEmpty)
            { 
                string reason = SR.GetString(SR.NonEmptyWsrmMessageIsEmpty, Wsrm11Strings.CloseSequenceAction); 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XmlException(reason));
            } 

            CloseSequenceInfo info;
            using (XmlDictionaryReader reader = message.GetReaderAtBodyContents())
            { 
                info = CloseSequence.Create(reader);
                message.ReadFromBodyContentsToEnd(reader); 
            } 

            info.SetMessageId(messageVersion, headers); 
            info.SetReplyTo(messageVersion, headers);

            return info;
        } 
    }
 
    sealed class CloseSequenceResponseInfo 
    {
        UniqueId identifier; 
        UniqueId relatesTo;

        public UniqueId Identifier
        { 
            get
            { 
                return this.identifier; 
            }
            set 
            {
                this.identifier = value;
            }
        } 

        public UniqueId RelatesTo 
        { 
            get
            { 
                return this.relatesTo;
            }
            set
            { 
                this.relatesTo = value;
            } 
        } 

        public static CloseSequenceResponseInfo ReadMessage(MessageVersion messageVersion, Message message, 
            MessageHeaders headers)
        {
            if (headers.RelatesTo == null)
            { 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
                    new MessageHeaderException(SR.GetString(SR.MissingRelatesToOnWsrmResponseReason, 
                    DXD.Wsrm11Dictionary.CloseSequenceResponse), messageVersion.Addressing.Namespace, 
                    AddressingStrings.RelatesTo, false));
            } 

            if (message.IsEmpty)
            {
                string reason = SR.GetString(SR.NonEmptyWsrmMessageIsEmpty, 
                    Wsrm11Strings.CloseSequenceResponseAction);
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XmlException(reason)); 
            } 

            CloseSequenceResponseInfo info; 
            using (XmlDictionaryReader reader = message.GetReaderAtBodyContents())
            {
                info = CloseSequenceResponse.Create(reader);
                message.ReadFromBodyContentsToEnd(reader); 
            }
 
            info.relatesTo = headers.RelatesTo; 
            return info;
        } 
    }

    sealed class CreateSequenceInfo : WsrmRequestInfo
    { 
        EndpointAddress acksTo = EndpointAddress.AnonymousAddress;
        Nullable expires; 
        Nullable offerExpires; 
        UniqueId offerIdentifier;
        Uri to; 

        public EndpointAddress AcksTo
        {
            get 
            {
                return this.acksTo; 
            } 
            set
            { 
                this.acksTo = value;
            }
        }
 
        public Nullable Expires
        { 
            get 
            {
                return this.expires; 
            }
            set
            {
                this.expires = value; 
            }
        } 
 
        public Nullable OfferExpires
        { 
            get
            {
                return this.offerExpires;
            } 
            set
            { 
                this.offerExpires = value; 
            }
        } 

        public UniqueId OfferIdentifier
        {
            get 
            {
                return this.offerIdentifier; 
            } 
            set
            { 
                this.offerIdentifier = value;
            }
        }
 
        public override string RequestName
        { 
            get 
            {
                return WsrmFeb2005Strings.CreateSequence; 
            }
        }

        public Uri To 
        {
            get 
            { 
                return this.to;
            } 
        }

        public static CreateSequenceInfo ReadMessage(MessageVersion messageVersion,
            ReliableMessagingVersion reliableMessagingVersion, ISecureConversationSession securitySession, 
            Message message, MessageHeaders headers)
        { 
            if (message.IsEmpty) 
            {
                string reason = SR.GetString(SR.NonEmptyWsrmMessageIsEmpty, 
                    WsrmIndex.GetCreateSequenceActionString(reliableMessagingVersion));
                Message faultReply = WsrmUtilities.CreateCSRefusedProtocolFault(messageVersion, reliableMessagingVersion, reason);
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(WsrmMessageInfo.CreateInternalFaultException(faultReply, reason, new ProtocolException(reason)));
            } 

            CreateSequenceInfo info; 
            using (XmlDictionaryReader reader = message.GetReaderAtBodyContents()) 
            {
                info = CreateSequence.Create(messageVersion, reliableMessagingVersion, securitySession, reader); 
                message.ReadFromBodyContentsToEnd(reader);
            }

            info.SetMessageId(messageVersion, headers); 
            info.SetReplyTo(messageVersion, headers);
 
            if (info.AcksTo.Uri != info.ReplyTo.Uri) 
            {
                string reason = SR.GetString(SR.CSRefusedAcksToMustEqualReplyTo); 
                Message faultReply = WsrmUtilities.CreateCSRefusedProtocolFault(messageVersion, reliableMessagingVersion, reason);
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(WsrmMessageInfo.CreateInternalFaultException(faultReply, reason, new ProtocolException(reason)));
            }
 
            info.to = message.Headers.To;
            if (info.to == null && messageVersion.Addressing == AddressingVersion.WSAddressing10) 
                info.to = messageVersion.Addressing.AnonymousUri; 

            return info; 
        }

        public static void ValidateCreateSequenceHeaders(MessageVersion messageVersion,
            ISecureConversationSession securitySession, WsrmMessageInfo info) 
        {
            string reason = null; 
 
            if (info.UsesSequenceSSLInfo != null)
            { 
                reason = SR.GetString(SR.CSRefusedSSLNotSupported);
            }
            else if ((info.UsesSequenceSTRInfo != null) && (securitySession == null))
            { 
                reason = SR.GetString(SR.CSRefusedSTRNoWSSecurity);
            } 
            else if ((info.UsesSequenceSTRInfo == null) && (securitySession != null)) 
            {
                reason = SR.GetString(SR.CSRefusedNoSTRWSSecurity); 
            }

            if (reason != null)
            { 
                Message faultReply = WsrmUtilities.CreateCSRefusedProtocolFault(messageVersion,
                    ReliableMessagingVersion.WSReliableMessaging11, reason); 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(WsrmMessageInfo.CreateInternalFaultException(faultReply, reason, new ProtocolException(reason))); 
            }
        } 
    }

    sealed class CreateSequenceResponseInfo
    { 
        EndpointAddress acceptAcksTo;
        UniqueId identifier; 
        UniqueId relatesTo; 

        public EndpointAddress AcceptAcksTo 
        {
            get
            {
                return this.acceptAcksTo; 
            }
            set 
            { 
                this.acceptAcksTo = value;
            } 
        }

        public UniqueId Identifier
        { 
            get
            { 
                return this.identifier; 
            }
            set 
            {
                this.identifier = value;
            }
        } 

        public UniqueId RelatesTo 
        { 
            get
            { 
                return this.relatesTo;
            }
            set
            { 
                this.relatesTo = value;
            } 
        } 

        public static CreateSequenceResponseInfo ReadMessage(MessageVersion messageVersion, 
            ReliableMessagingVersion reliableMessagingVersion, Message message, MessageHeaders headers)
        {
            if (message.IsEmpty)
            { 
                string reason = SR.GetString(SR.NonEmptyWsrmMessageIsEmpty,
                    WsrmIndex.GetCreateSequenceResponseActionString(reliableMessagingVersion)); 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XmlException(reason)); 
            }
 
            if (headers.RelatesTo == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
                    new MessageHeaderException(SR.GetString(SR.MissingRelatesToOnWsrmResponseReason, 
                    XD.WsrmFeb2005Dictionary.CreateSequenceResponse), messageVersion.Addressing.Namespace,
                    AddressingStrings.RelatesTo, false)); 
            } 

            CreateSequenceResponseInfo info; 
            using (XmlDictionaryReader reader = message.GetReaderAtBodyContents())
            {
                info = CreateSequenceResponse.Create(messageVersion.Addressing, reliableMessagingVersion, reader);
                message.ReadFromBodyContentsToEnd(reader); 
            }
 
            info.RelatesTo = headers.RelatesTo; 
            return info;
        } 
    }

    sealed class TerminateSequenceInfo : WsrmRequestInfo
    { 
        UniqueId identifier;
        Int64 lastMsgNumber; 
 
        public UniqueId Identifier
        { 
            get
            {
                return this.identifier;
            } 
            set
            { 
                this.identifier = value; 
            }
        } 

        public Int64 LastMsgNumber
        {
            get 
            {
                return this.lastMsgNumber; 
            } 
            set
            { 
                this.lastMsgNumber = value;
            }
        }
 
        public override string RequestName
        { 
            get 
            {
                return WsrmFeb2005Strings.TerminateSequence; 
            }
        }

        public static TerminateSequenceInfo ReadMessage(MessageVersion messageVersion, 
            ReliableMessagingVersion reliableMessagingVersion, Message message, MessageHeaders headers)
        { 
            if (message.IsEmpty) 
            {
                string reason = SR.GetString(SR.NonEmptyWsrmMessageIsEmpty, 
                    WsrmIndex.GetTerminateSequenceActionString(reliableMessagingVersion));
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XmlException(reason));
            }
 
            TerminateSequenceInfo info;
            using (XmlDictionaryReader reader = message.GetReaderAtBodyContents()) 
            { 
                info = TerminateSequence.Create(reliableMessagingVersion, reader);
                message.ReadFromBodyContentsToEnd(reader); 
            }

            if (reliableMessagingVersion == ReliableMessagingVersion.WSReliableMessaging11)
            { 
                info.SetMessageId(messageVersion, headers);
                info.SetReplyTo(messageVersion, headers); 
            } 

            return info; 
        }
    }

    sealed class TerminateSequenceResponseInfo 
    {
        UniqueId identifier; 
        UniqueId relatesTo; 

        public UniqueId Identifier 
        {
            get
            {
                return this.identifier; 
            }
            set 
            { 
                this.identifier = value;
            } 
        }

        public UniqueId RelatesTo
        { 
            get
            { 
                return this.relatesTo; 
            }
            set 
            {
                this.relatesTo = value;
            }
        } 

        public static TerminateSequenceResponseInfo ReadMessage(MessageVersion messageVersion, Message message, 
            MessageHeaders headers) 
        {
            if (headers.RelatesTo == null) 
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
                    new MessageHeaderException(SR.GetString(SR.MissingRelatesToOnWsrmResponseReason,
                    DXD.Wsrm11Dictionary.TerminateSequenceResponse), messageVersion.Addressing.Namespace, 
                    AddressingStrings.RelatesTo, false));
            } 
 
            if (message.IsEmpty)
            { 
                string reason = SR.GetString(SR.NonEmptyWsrmMessageIsEmpty,
                    WsrmIndex.GetTerminateSequenceResponseActionString(ReliableMessagingVersion.WSReliableMessaging11));
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XmlException(reason));
            } 

            TerminateSequenceResponseInfo info; 
            using (XmlDictionaryReader reader = message.GetReaderAtBodyContents()) 
            {
                info = TerminateSequenceResponse.Create(reader); 
                message.ReadFromBodyContentsToEnd(reader);
            }

            info.relatesTo = headers.RelatesTo; 
            return info;
        } 
    } 

    internal abstract class WsrmMessageHeader : DictionaryHeader, IMessageHeaderWithSharedNamespace 
    {
        ReliableMessagingVersion reliableMessagingVersion;

        protected WsrmMessageHeader(ReliableMessagingVersion reliableMessagingVersion) 
        {
            this.reliableMessagingVersion = reliableMessagingVersion; 
        } 

        XmlDictionaryString IMessageHeaderWithSharedNamespace.SharedPrefix 
        {
            get { return XD.WsrmFeb2005Dictionary.Prefix; }
        }
 
        XmlDictionaryString IMessageHeaderWithSharedNamespace.SharedNamespace
        { 
            get { return WsrmIndex.GetNamespace(this.reliableMessagingVersion); } 
        }
 
        public override XmlDictionaryString DictionaryNamespace
        {
            get { return WsrmIndex.GetNamespace(this.reliableMessagingVersion); }
        } 

        public override string Namespace 
        { 
            get { return WsrmIndex.GetNamespaceString(this.reliableMessagingVersion); }
        } 

        protected ReliableMessagingVersion ReliableMessagingVersion
        {
            get { return this.reliableMessagingVersion; } 
        }
    } 
 
    abstract class WsrmHeaderInfo
    { 
        MessageHeaderInfo messageHeader;

        protected WsrmHeaderInfo(MessageHeaderInfo messageHeader)
        { 
            this.messageHeader = messageHeader;
        } 
 
        public MessageHeaderInfo MessageHeader
        { 
            get
            {
                return messageHeader;
            } 
        }
    } 
 
    abstract class WsrmRequestInfo
    { 
        UniqueId messageId;
        EndpointAddress replyTo;

        protected WsrmRequestInfo() 
        {
        } 
 
        public UniqueId MessageId
        { 
            get
            {
                return this.messageId;
            } 
        }
 
        public EndpointAddress ReplyTo 
        {
            get 
            {
                return this.replyTo;
            }
        } 

        public abstract string RequestName 
        { 
            get;
        } 

        protected void SetMessageId(MessageVersion messageVersion, MessageHeaders headers)
        {
            this.messageId =  headers.MessageId; 

            if (this.messageId == null) 
            { 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MessageHeaderException(
                    SR.GetString(SR.MissingMessageIdOnWsrmRequest, RequestName), 
                    messageVersion.Addressing.Namespace,
                    AddressingStrings.MessageId,
                    false));
            } 
        }
 
        protected void SetReplyTo(MessageVersion messageVersion, MessageHeaders headers) 
        {
            this.replyTo = headers.ReplyTo; 

            if (messageVersion.Addressing == AddressingVersion.WSAddressing10 && this.replyTo == null)
            {
                this.replyTo = EndpointAddress.AnonymousAddress; 
            }
 
            if (this.replyTo == null) 
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MessageHeaderException( 
                    SR.GetString(SR.MissingReplyToOnWsrmRequest, RequestName),
                    messageVersion.Addressing.Namespace,
                    AddressingStrings.ReplyTo,
                    false)); 
            }
        } 
    } 

    internal sealed class WsrmSequencedMessageInfo : WsrmHeaderInfo 
    {
        UniqueId sequenceID;
        Int64 sequenceNumber;
        bool lastMessage; 

        WsrmSequencedMessageInfo( 
            UniqueId sequenceID, 
            Int64 sequenceNumber,
            bool lastMessage, 
            MessageHeaderInfo header)
            : base(header)
        {
            this.sequenceID = sequenceID; 
            this.sequenceNumber = sequenceNumber;
            this.lastMessage = lastMessage; 
        } 

        public UniqueId SequenceID 
        {
            get
            {
                return sequenceID; 
            }
        } 
 
        public Int64 SequenceNumber
        { 
            get
            {
                return sequenceNumber;
            } 
        }
 
        public bool LastMessage 
        {
            get 
            {
                return lastMessage;
            }
        } 

        public static WsrmSequencedMessageInfo ReadHeader(ReliableMessagingVersion reliableMessagingVersion, 
            XmlDictionaryReader reader, MessageHeaderInfo header) 
        {
            WsrmFeb2005Dictionary wsrmFeb2005Dictionary = XD.WsrmFeb2005Dictionary; 
            XmlDictionaryString wsrmNs = WsrmIndex.GetNamespace(reliableMessagingVersion);

            reader.ReadStartElement();
 
            reader.ReadStartElement(wsrmFeb2005Dictionary.Identifier, wsrmNs);
            UniqueId sequenceID = reader.ReadContentAsUniqueId(); 
            reader.ReadEndElement(); 

            reader.ReadStartElement(wsrmFeb2005Dictionary.MessageNumber, wsrmNs); 
            Int64 sequenceNumber = WsrmUtilities.ReadSequenceNumber(reader);
            reader.ReadEndElement();

            bool lastMessage = false; 

            if (reliableMessagingVersion == ReliableMessagingVersion.WSReliableMessagingFebruary2005) 
            { 
                if (reader.IsStartElement(wsrmFeb2005Dictionary.LastMessage, wsrmNs))
                { 
                    WsrmUtilities.ReadEmptyElement(reader);
                    lastMessage = true;
                }
            } 

            while (reader.IsStartElement()) 
            { 
                reader.Skip();
            } 

            reader.ReadEndElement();

            return new WsrmSequencedMessageInfo(sequenceID, sequenceNumber, lastMessage, header); 
        }
    } 
 
    internal sealed class WsrmSequencedMessageHeader : WsrmMessageHeader
    { 
        bool lastMessage;
        UniqueId sequenceID;
        Int64 sequenceNumber;
 
        public WsrmSequencedMessageHeader(
            ReliableMessagingVersion reliableMessagingVersion, 
            UniqueId sequenceID, 
            Int64 sequenceNumber,
            bool lastMessage) 
            : base(reliableMessagingVersion)
        {
            this.sequenceID = sequenceID;
            this.sequenceNumber = sequenceNumber; 
            this.lastMessage = lastMessage;
        } 
 
        public override XmlDictionaryString DictionaryName
        { 
            get { return XD.WsrmFeb2005Dictionary.Sequence; }
        }

        public override bool MustUnderstand 
        {
            get { return true; } 
        } 

        protected override void OnWriteHeaderContents(XmlDictionaryWriter writer, MessageVersion messageVersion) 
        {
            WsrmFeb2005Dictionary wsrmFeb2005Dictionary = XD.WsrmFeb2005Dictionary;
            XmlDictionaryString wsrmNs = this.DictionaryNamespace;
 
            writer.WriteStartElement(wsrmFeb2005Dictionary.Identifier, wsrmNs);
            writer.WriteValue(this.sequenceID); 
            writer.WriteEndElement(); 

            writer.WriteStartElement(wsrmFeb2005Dictionary.MessageNumber, wsrmNs); 
            writer.WriteValue(this.sequenceNumber);
            writer.WriteEndElement();

            if ((this.ReliableMessagingVersion == ReliableMessagingVersion.WSReliableMessagingFebruary2005) 
                && lastMessage)
            { 
                writer.WriteStartElement(wsrmFeb2005Dictionary.LastMessage, wsrmNs); 
                writer.WriteEndElement();
            } 
        }
    }

    internal sealed class WsrmAcknowledgmentInfo : WsrmHeaderInfo 
    {
        int bufferRemaining; 
        bool final; 
        SequenceRangeCollection ranges;
        UniqueId sequenceID; 

        WsrmAcknowledgmentInfo(
            UniqueId sequenceID,
            SequenceRangeCollection ranges, 
            bool final,
            int bufferRemaining, 
            MessageHeaderInfo header) 
            : base(header)
        { 
            this.sequenceID = sequenceID;
            this.ranges = ranges;
            this.final = final;
            this.bufferRemaining = bufferRemaining; 
        }
 
        public int BufferRemaining 
        {
            get 
            {
                return this.bufferRemaining;
            }
        } 

        public bool Final 
        { 
            get
            { 
                return this.final;
            }
        }
 
        public SequenceRangeCollection Ranges
        { 
            get 
            {
                return this.ranges; 
            }
        }

        public UniqueId SequenceID 
        {
            get 
            { 
                return this.sequenceID;
            } 
        }

        // February 2005 - Reads Identifier, AcknowledgementRange, Nack
        // 1.1 - Reads Identifier, AcknowledgementRange, None, Final, Nack 
        internal static void ReadAck(ReliableMessagingVersion reliableMessagingVersion,
            XmlDictionaryReader reader, out UniqueId sequenceId, out SequenceRangeCollection rangeCollection, 
            out bool final) 
        {
            WsrmFeb2005Dictionary wsrmFeb2005Dictionary = XD.WsrmFeb2005Dictionary; 
            XmlDictionaryString wsrmNs = WsrmIndex.GetNamespace(reliableMessagingVersion);

            reader.ReadStartElement(wsrmFeb2005Dictionary.SequenceAcknowledgement, wsrmNs);
            reader.ReadStartElement(wsrmFeb2005Dictionary.Identifier, wsrmNs); 
            sequenceId = reader.ReadContentAsUniqueId();
            reader.ReadEndElement(); 
            bool allowZero = reliableMessagingVersion == ReliableMessagingVersion.WSReliableMessagingFebruary2005; 

            rangeCollection = SequenceRangeCollection.Empty; 
            while (reader.IsStartElement(wsrmFeb2005Dictionary.AcknowledgementRange, wsrmNs))
            {
                reader.MoveToAttribute(WsrmFeb2005Strings.Lower);
                Int64 lower = WsrmUtilities.ReadSequenceNumber(reader, allowZero); 

                reader.MoveToAttribute(WsrmFeb2005Strings.Upper); 
                Int64 upper = WsrmUtilities.ReadSequenceNumber(reader, allowZero); 

                if (lower < 0 || lower > upper 
                    || ((reliableMessagingVersion == ReliableMessagingVersion.WSReliableMessagingFebruary2005) && (lower == 0 && upper > 0))
                    || ((reliableMessagingVersion == ReliableMessagingVersion.WSReliableMessaging11) && (lower == 0)))
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( 
                        new XmlException(SR.GetString(SR.InvalidSequenceRange, lower, upper)));
                } 
 
                rangeCollection = rangeCollection.MergeWith(new SequenceRange(lower, upper));
 
                reader.MoveToElement();

                WsrmUtilities.ReadEmptyElement(reader);
            } 

            bool validAck = rangeCollection.Count > 0; 
            final = false; 
            bool wsrm11 = reliableMessagingVersion == ReliableMessagingVersion.WSReliableMessaging11;
 
            if (wsrm11)
            {
                Wsrm11Dictionary wsrm11Dictionary = DXD.Wsrm11Dictionary;
 
                if (reader.IsStartElement(wsrm11Dictionary.None, wsrmNs))
                { 
                    if (validAck) 
                    {
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XmlException( 
                            SR.GetString(SR.UnexpectedXmlChildNode, reader.Name, reader.NodeType,
                            wsrmFeb2005Dictionary.SequenceAcknowledgement)));
                    }
 
                    WsrmUtilities.ReadEmptyElement(reader);
                    validAck = true; 
                } 

                if (reader.IsStartElement(wsrm11Dictionary.Final, wsrmNs)) 
                {
                    if (!validAck)
                    {
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XmlException( 
                            SR.GetString(SR.UnexpectedXmlChildNode, reader.Name, reader.NodeType,
                            wsrmFeb2005Dictionary.SequenceAcknowledgement))); 
                    } 

                    WsrmUtilities.ReadEmptyElement(reader); 
                    final = true;
                }
            }
 
            bool foundNack = false;
            while (reader.IsStartElement(wsrmFeb2005Dictionary.Nack, wsrmNs)) 
            { 
                if (validAck)
                { 
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XmlException(
                        SR.GetString(SR.UnexpectedXmlChildNode, reader.Name, reader.NodeType,
                        MessageStrings.Body)));
                } 

                reader.ReadStartElement(); 
                WsrmUtilities.ReadSequenceNumber(reader, true); 
                reader.ReadEndElement();
                foundNack = true; 
            }

            if (!validAck && !foundNack)
            { 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XmlException(
                    SR.GetString(SR.UnexpectedXmlChildNode, reader.Name, reader.NodeType, 
                    MessageStrings.Body))); 
            }
        } 

        public static WsrmAcknowledgmentInfo ReadHeader(ReliableMessagingVersion reliableMessagingVersion,
            XmlDictionaryReader reader, MessageHeaderInfo header)
        { 
            WsrmFeb2005Dictionary wsrmFeb2005Dictionary = XD.WsrmFeb2005Dictionary;
            XmlDictionaryString wsrmNs = WsrmIndex.GetNamespace(reliableMessagingVersion); 
 
            UniqueId sequenceID;
            SequenceRangeCollection rangeCollection; 
            bool final;
            ReadAck(reliableMessagingVersion, reader, out sequenceID, out rangeCollection, out final);

            int bufferRemaining = -1; 

            // Parse the extensibility section. 
            while (reader.IsStartElement()) 
            {
                if (reader.IsStartElement(wsrmFeb2005Dictionary.BufferRemaining, 
                    XD.WsrmFeb2005Dictionary.NETNamespace))
                {
                    if (bufferRemaining != -1)
                    { 
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XmlException(
                            SR.GetString(SR.UnexpectedXmlChildNode, reader.Name, reader.NodeType, 
                            MessageStrings.Body))); 
                    }
 
                    reader.ReadStartElement();
                    bufferRemaining = reader.ReadContentAsInt();
                    reader.ReadEndElement();
 
                    if (bufferRemaining < 0)
                    { 
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XmlException( 
                            SR.GetString(SR.InvalidBufferRemaining, bufferRemaining)));
                    } 

                    // Found BufferRemaining, continue parsing.
                    continue;
                } 

                if (reader.IsStartElement(wsrmFeb2005Dictionary.AcknowledgementRange, wsrmNs)) 
                { 
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XmlException(
                        SR.GetString(SR.UnexpectedXmlChildNode, reader.Name, reader.NodeType, 
                        MessageStrings.Body)));
                }
                else if (reader.IsStartElement(wsrmFeb2005Dictionary.Nack, wsrmNs))
                { 
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XmlException(
                        SR.GetString(SR.UnexpectedXmlChildNode, reader.Name, reader.NodeType, 
                        MessageStrings.Body))); 
                }
                else if (reliableMessagingVersion == ReliableMessagingVersion.WSReliableMessaging11) 
                {
                    Wsrm11Dictionary wsrm11Dictionary = DXD.Wsrm11Dictionary;

                    if (reader.IsStartElement(wsrm11Dictionary.None, wsrmNs) 
                        || reader.IsStartElement(wsrm11Dictionary.Final, wsrmNs))
                    { 
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XmlException( 
                            SR.GetString(SR.UnexpectedXmlChildNode, reader.Name, reader.NodeType,
                            wsrmFeb2005Dictionary.SequenceAcknowledgement))); 
                    }
                }

                // Advance the reader in all cases. 
                reader.Skip();
            } 
 
            reader.ReadEndElement();
 
            return new WsrmAcknowledgmentInfo(sequenceID, rangeCollection, final, bufferRemaining, header);
        }
    }
 
    internal sealed class WsrmAcknowledgmentHeader : WsrmMessageHeader
    { 
        int bufferRemaining; 
        bool final;
        SequenceRangeCollection ranges; 
        UniqueId sequenceID;

        public WsrmAcknowledgmentHeader(
            ReliableMessagingVersion reliableMessagingVersion, 
            UniqueId sequenceID,
            SequenceRangeCollection ranges, 
            bool final, 
            int bufferRemaining)
            : base(reliableMessagingVersion) 
        {
            this.sequenceID = sequenceID;
            this.ranges = ranges;
            this.final = final; 
            this.bufferRemaining = bufferRemaining;
        } 
 
        public override XmlDictionaryString DictionaryName
        { 
            get { return XD.WsrmFeb2005Dictionary.SequenceAcknowledgement; }
        }

        protected override void OnWriteHeaderContents(XmlDictionaryWriter writer, MessageVersion messageVersion) 
        {
            WsrmFeb2005Dictionary wsrmFeb2005Dictionary = XD.WsrmFeb2005Dictionary; 
            XmlDictionaryString wsrmNs = this.DictionaryNamespace; 

            WriteAckRanges(writer, this.ReliableMessagingVersion, this.sequenceID, this.ranges); 

            if ((this.ReliableMessagingVersion == ReliableMessagingVersion.WSReliableMessaging11) && this.final)
            {
                writer.WriteStartElement(DXD.Wsrm11Dictionary.Final, wsrmNs); 
                writer.WriteEndElement();
            } 
 
            if (this.bufferRemaining != -1)
            { 
                writer.WriteStartElement(WsrmFeb2005Strings.NETPrefix, wsrmFeb2005Dictionary.BufferRemaining,
                    XD.WsrmFeb2005Dictionary.NETNamespace);
                writer.WriteValue(this.bufferRemaining);
                writer.WriteEndElement(); 
            }
        } 
 
        // February 2005 - Writes Identifier, AcknowledgementRange
        // 1.1 - Writes Identifier, AcknowledgementRange | None 
        internal static void WriteAckRanges(XmlDictionaryWriter writer,
            ReliableMessagingVersion reliableMessagingVersion, UniqueId sequenceId, SequenceRangeCollection ranges)
        {
            WsrmFeb2005Dictionary wsrmFeb2005Dictionary = XD.WsrmFeb2005Dictionary; 
            XmlDictionaryString wsrmNs = WsrmIndex.GetNamespace(reliableMessagingVersion);
 
            writer.WriteStartElement(wsrmFeb2005Dictionary.Identifier, wsrmNs); 
            writer.WriteValue(sequenceId);
            writer.WriteEndElement(); 

            if (ranges.Count == 0)
            {
                if (reliableMessagingVersion == ReliableMessagingVersion.WSReliableMessagingFebruary2005) 
                {
                    ranges = ranges.MergeWith(0); 
                } 
                else if (reliableMessagingVersion == ReliableMessagingVersion.WSReliableMessaging11)
                { 
                    writer.WriteStartElement(DXD.Wsrm11Dictionary.None, wsrmNs);
                    writer.WriteEndElement();
                }
            } 

            for (int index = 0; index < ranges.Count; index++) 
            { 
                writer.WriteStartElement(wsrmFeb2005Dictionary.AcknowledgementRange, wsrmNs);
                writer.WriteStartAttribute(wsrmFeb2005Dictionary.Lower, null); 
                writer.WriteValue(ranges[index].Lower);
                writer.WriteEndAttribute();
                writer.WriteStartAttribute(wsrmFeb2005Dictionary.Upper, null);
                writer.WriteValue(ranges[index].Upper); 
                writer.WriteEndAttribute();
                writer.WriteEndElement(); 
            } 
        }
    } 

    internal sealed class WsrmAckRequestedInfo : WsrmHeaderInfo
    {
        UniqueId sequenceID; 

        public WsrmAckRequestedInfo(UniqueId sequenceID, MessageHeaderInfo header) 
            : base(header) 
        {
            this.sequenceID = sequenceID; 
        }

        public UniqueId SequenceID
        { 
            get
            { 
                return this.sequenceID; 
            }
        } 

        public static WsrmAckRequestedInfo ReadHeader(ReliableMessagingVersion reliableMessagingVersion,
            XmlDictionaryReader reader, MessageHeaderInfo header)
        { 
            WsrmFeb2005Dictionary wsrmFeb2005Dictionary = XD.WsrmFeb2005Dictionary;
            XmlDictionaryString wsrmNs = WsrmIndex.GetNamespace(reliableMessagingVersion); 
 
            reader.ReadStartElement();
 
            reader.ReadStartElement(wsrmFeb2005Dictionary.Identifier, wsrmNs);
            UniqueId sequenceID = reader.ReadContentAsUniqueId();
            reader.ReadEndElement();
 
            if (reliableMessagingVersion == ReliableMessagingVersion.WSReliableMessagingFebruary2005)
            { 
                if (reader.IsStartElement(wsrmFeb2005Dictionary.MessageNumber, wsrmNs)) 
                {
                    reader.ReadStartElement(); 
                    WsrmUtilities.ReadSequenceNumber(reader, true);
                    reader.ReadEndElement();
                }
            } 

            while (reader.IsStartElement()) 
            { 
                reader.Skip();
            } 

            reader.ReadEndElement();

            return new WsrmAckRequestedInfo(sequenceID, header); 
        }
    } 
 
    internal sealed class WsrmAckRequestedHeader : WsrmMessageHeader
    { 
        UniqueId sequenceID;

        public WsrmAckRequestedHeader(ReliableMessagingVersion reliableMessagingVersion, UniqueId sequenceID)
            : base(reliableMessagingVersion) 
        {
            this.sequenceID = sequenceID; 
        } 

        public override XmlDictionaryString DictionaryName 
        {
            get { return XD.WsrmFeb2005Dictionary.AckRequested; }
        }
 
        protected override void OnWriteHeaderContents(XmlDictionaryWriter writer, MessageVersion messageVersion)
        { 
            WsrmFeb2005Dictionary wsrmFeb2005Dictionary = XD.WsrmFeb2005Dictionary; 
            XmlDictionaryString wsrmNs = this.DictionaryNamespace;
 
            writer.WriteStartElement(wsrmFeb2005Dictionary.Identifier, wsrmNs);
            writer.WriteValue(this.sequenceID);
            writer.WriteEndElement();
        } 
    }
 
    // We do not generate the UsesSequenceSSL header. Thus, there is an info, but no header. 
    internal sealed class WsrmUsesSequenceSSLInfo : WsrmHeaderInfo
    { 
        WsrmUsesSequenceSSLInfo(MessageHeaderInfo header)
            : base(header)
        {
        } 

        public static WsrmUsesSequenceSSLInfo ReadHeader(XmlDictionaryReader reader, MessageHeaderInfo header) 
        { 
            WsrmUtilities.ReadEmptyElement(reader);
            return new WsrmUsesSequenceSSLInfo(header); 
        }
    }

    internal sealed class WsrmUsesSequenceSTRHeader : WsrmMessageHeader 
    {
        public WsrmUsesSequenceSTRHeader() 
            : base(ReliableMessagingVersion.WSReliableMessaging11) 
        {
        } 

        public override XmlDictionaryString DictionaryName
        {
            get { return DXD.Wsrm11Dictionary.UsesSequenceSTR; } 
        }
 
        protected override void OnWriteHeaderContents(XmlDictionaryWriter writer, MessageVersion messageVersion) 
        {
        } 

        public override bool MustUnderstand
        {
            get { return true; } 
        }
    } 
 
    internal sealed class WsrmUsesSequenceSTRInfo : WsrmHeaderInfo
    { 
        WsrmUsesSequenceSTRInfo(MessageHeaderInfo header)
            : base(header)
        {
        } 

        public static WsrmUsesSequenceSTRInfo ReadHeader(XmlDictionaryReader reader, MessageHeaderInfo header) 
        { 
            WsrmUtilities.ReadEmptyElement(reader);
            return new WsrmUsesSequenceSTRInfo(header); 
        }
    }
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK