SecurityBindingElement.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 / SecurityBindingElement.cs / 1 / SecurityBindingElement.cs

                            //------------------------------------------------------------------------------ 
// Copyright (c) Microsoft Corporation.  All rights reserved.
//-----------------------------------------------------------------------------
namespace System.ServiceModel.Channels
{ 
    using System;
    using System.ServiceModel; 
    using System.ServiceModel.Description; 
    using System.ServiceModel.Dispatcher;
    using System.Xml; 
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.Globalization;
    using System.IdentityModel.Selectors; 
    using System.IdentityModel.Tokens;
    using System.Runtime.Serialization; 
    using System.ServiceModel.Security; 

    using System.Net.Security; 
    using System.ServiceModel.Security.Tokens;
    using System.Text;
    using System.ServiceModel.Configuration;
    using System.ServiceModel.Diagnostics; 

    public abstract class SecurityBindingElement : BindingElement 
    { 
        internal const string defaultAlgorithmSuiteString = System.ServiceModel.Configuration.ConfigurationStrings.Default;
        internal static readonly SecurityAlgorithmSuite defaultDefaultAlgorithmSuite = SecurityAlgorithmSuite.Default; 
        internal const bool defaultIncludeTimestamp = true;
        internal const MessageProtectionOrder defaultMessageProtectionOrder = MessageProtectionOrder.SignBeforeEncryptAndEncryptSignature;
        internal const bool defaultRequireSignatureConfirmation = false;
 
        SecurityAlgorithmSuite defaultAlgorithmSuite;
        SupportingTokenParameters endpointSupportingTokenParameters; 
        SupportingTokenParameters optionalEndpointSupportingTokenParameters; 
        bool includeTimestamp;
        SecurityKeyEntropyMode keyEntropyMode; 
        Dictionary operationSupportingTokenParameters;
        Dictionary optionalOperationSupportingTokenParameters;
        LocalClientSecuritySettings localClientSettings;
        LocalServiceSecuritySettings localServiceSettings; 
        MessageSecurityVersion messageSecurityVersion;
        SecurityHeaderLayout securityHeaderLayout; 
        InternalDuplexBindingElement internalDuplexBindingElement; 
        long maxReceivedMessageSize = TransportDefaults.MaxReceivedMessageSize;
        XmlDictionaryReaderQuotas readerQuotas; 
        bool doNotEmitTrust = false; // true if user create a basic http standard binding, the custombinding equivalent will not set this flag

        internal SecurityBindingElement()
            : base() 
        {
            this.messageSecurityVersion = MessageSecurityVersion.Default; 
            this.keyEntropyMode = AcceleratedTokenProvider.defaultKeyEntropyMode; 
            this.includeTimestamp = defaultIncludeTimestamp;
            this.defaultAlgorithmSuite = defaultDefaultAlgorithmSuite; 
            this.localClientSettings = new LocalClientSecuritySettings();
            this.localServiceSettings = new LocalServiceSecuritySettings();
            this.endpointSupportingTokenParameters = new SupportingTokenParameters();
            this.optionalEndpointSupportingTokenParameters = new SupportingTokenParameters(); 
            this.operationSupportingTokenParameters = new Dictionary();
            this.optionalOperationSupportingTokenParameters = new Dictionary(); 
            this.securityHeaderLayout = SecurityProtocolFactory.defaultSecurityHeaderLayout; 
        }
 
        internal SecurityBindingElement(SecurityBindingElement elementToBeCloned)
            : base(elementToBeCloned)
        {
            if (elementToBeCloned == null) 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("elementToBeCloned");
 
            this.defaultAlgorithmSuite = elementToBeCloned.defaultAlgorithmSuite; 
            this.includeTimestamp = elementToBeCloned.includeTimestamp;
            this.keyEntropyMode = elementToBeCloned.keyEntropyMode; 
            this.messageSecurityVersion = elementToBeCloned.messageSecurityVersion;
            this.securityHeaderLayout = elementToBeCloned.securityHeaderLayout;
            this.endpointSupportingTokenParameters = (SupportingTokenParameters)elementToBeCloned.endpointSupportingTokenParameters.Clone();
            this.optionalEndpointSupportingTokenParameters = (SupportingTokenParameters)elementToBeCloned.optionalEndpointSupportingTokenParameters.Clone(); 
            this.operationSupportingTokenParameters = new Dictionary();
            foreach (string key in elementToBeCloned.operationSupportingTokenParameters.Keys) 
                this.operationSupportingTokenParameters[key] = (SupportingTokenParameters)elementToBeCloned.operationSupportingTokenParameters[key].Clone(); 
            this.optionalOperationSupportingTokenParameters = new Dictionary();
            foreach (string key in elementToBeCloned.optionalOperationSupportingTokenParameters.Keys) 
                this.optionalOperationSupportingTokenParameters[key] = (SupportingTokenParameters)elementToBeCloned.optionalOperationSupportingTokenParameters[key].Clone();
            this.localClientSettings = (LocalClientSecuritySettings)elementToBeCloned.localClientSettings.Clone();
            this.localServiceSettings = (LocalServiceSecuritySettings)elementToBeCloned.localServiceSettings.Clone();
            this.internalDuplexBindingElement = elementToBeCloned.internalDuplexBindingElement; 
            this.maxReceivedMessageSize = elementToBeCloned.maxReceivedMessageSize;
            this.readerQuotas = elementToBeCloned.readerQuotas; 
            this.doNotEmitTrust = elementToBeCloned.doNotEmitTrust; 
        }
 
        public SupportingTokenParameters EndpointSupportingTokenParameters
        {
            get
            { 
                return this.endpointSupportingTokenParameters;
            } 
        } 

        public SupportingTokenParameters OptionalEndpointSupportingTokenParameters 
        {
            get
            {
                return this.optionalEndpointSupportingTokenParameters; 
            }
        } 
 

        public IDictionary OperationSupportingTokenParameters 
        {
            get
            {
                return this.operationSupportingTokenParameters; 
            }
        } 
 
        public IDictionary OptionalOperationSupportingTokenParameters
        { 
            get
            {
                return this.optionalOperationSupportingTokenParameters;
            } 
        }
 
        public SecurityHeaderLayout SecurityHeaderLayout 
        {
            get 
            {
                return this.securityHeaderLayout;
            }
            set 
            {
                if (!SecurityHeaderLayoutHelper.IsDefined(value)) 
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("value")); 

                this.securityHeaderLayout = value; 
            }
        }

        public MessageSecurityVersion MessageSecurityVersion 
        {
            get 
            { 
                return this.messageSecurityVersion;
            } 
            set
            {
                if (value == null)
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("value")); 
                this.messageSecurityVersion = value;
            } 
        } 

        public bool IncludeTimestamp 
        {
            get
            {
                return this.includeTimestamp; 
            }
            set 
            { 
                this.includeTimestamp = value;
            } 
        }

        public SecurityAlgorithmSuite DefaultAlgorithmSuite
        { 
            get
            { 
                return this.defaultAlgorithmSuite; 
            }
            set 
            {
                if (value == null)
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("value"));
                this.defaultAlgorithmSuite = value; 
            }
        } 
 
        public LocalClientSecuritySettings LocalClientSettings
        { 
            get
            {
                return this.localClientSettings;
            } 
        }
 
        public LocalServiceSecuritySettings LocalServiceSettings 
        {
            get 
            {
                return this.localServiceSettings;
            }
        } 

        public SecurityKeyEntropyMode KeyEntropyMode 
        { 
            get
            { 
                return this.keyEntropyMode;
            }
            set
            { 
                if (!SecurityKeyEntropyModeHelper.IsDefined(value))
                { 
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("value")); 
                }
                this.keyEntropyMode = value; 
            }
        }

        internal virtual bool SessionMode 
        {
            get { return false; } 
        } 

        internal virtual bool SupportsDuplex 
        {
            get { return false; }
        }
 
        internal virtual bool SupportsRequestReply
        { 
            get { return false; } 
        }
 
        internal long MaxReceivedMessageSize
        {
            get { return this.maxReceivedMessageSize; }
            set { this.maxReceivedMessageSize = value; } 
        }
 
        internal bool DoNotEmitTrust 
        {
            get { return this.doNotEmitTrust; } 
            set { this.doNotEmitTrust = value; }
        }

        internal XmlDictionaryReaderQuotas ReaderQuotas 
        {
            get { return this.readerQuotas; } 
            set { this.readerQuotas = value; } 
        }
 
        void GetSupportingTokensCapabilities(ICollection parameters, out bool supportsClientAuth, out bool supportsWindowsIdentity)
        {
            supportsClientAuth = false;
            supportsWindowsIdentity = false; 
            foreach (SecurityTokenParameters p in parameters)
            { 
                if (p.SupportsClientAuthentication) 
                    supportsClientAuth = true;
                if (p.SupportsClientWindowsIdentity) 
                    supportsWindowsIdentity = true;
            }
        }
 
        void GetSupportingTokensCapabilities(SupportingTokenParameters requirements, out bool supportsClientAuth, out bool supportsWindowsIdentity)
        { 
            supportsClientAuth = false; 
            supportsWindowsIdentity = false;
            bool tmpSupportsClientAuth; 
            bool tmpSupportsWindowsIdentity;
            this.GetSupportingTokensCapabilities(requirements.Endorsing, out tmpSupportsClientAuth, out tmpSupportsWindowsIdentity);
            supportsClientAuth = supportsClientAuth || tmpSupportsClientAuth;
            supportsWindowsIdentity = supportsWindowsIdentity || tmpSupportsWindowsIdentity; 

            this.GetSupportingTokensCapabilities(requirements.SignedEndorsing, out tmpSupportsClientAuth, out tmpSupportsWindowsIdentity); 
            supportsClientAuth = supportsClientAuth || tmpSupportsClientAuth; 
            supportsWindowsIdentity = supportsWindowsIdentity || tmpSupportsWindowsIdentity;
 
            this.GetSupportingTokensCapabilities(requirements.SignedEncrypted, out tmpSupportsClientAuth, out tmpSupportsWindowsIdentity);
            supportsClientAuth = supportsClientAuth || tmpSupportsClientAuth;
            supportsWindowsIdentity = supportsWindowsIdentity || tmpSupportsWindowsIdentity;
        } 

        internal void GetSupportingTokensCapabilities(out bool supportsClientAuth, out bool supportsWindowsIdentity) 
        { 
            this.GetSupportingTokensCapabilities(this.EndpointSupportingTokenParameters, out supportsClientAuth, out supportsWindowsIdentity);
        } 

        // SecureConversation needs a demuxer below security to 1) demux between the security sessions and 2) demux the SCT issue and renewal messages
        // to the authenticator
        internal static void AddDemuxerForSecureConversation(ChannelBuilder builder, BindingContext secureConversationBindingContext) 
        {
            // add a demuxer element  right below security unless there's a demuxer already present below and the only 
            // binding elements between security and the demuxer are "ancillary" binding elements like message encoding element and 
            // stream-security upgrade element. We could always add the channel demuxer below security but not doing so in the ancillary
            // binding elements case improves perf 
            int numChannelDemuxersBelowSecurity = 0;
            bool doesBindingHaveShapeChangingElements = false;
            for (int i = 0; i < builder.Binding.Elements.Count; ++i)
            { 
                if ((builder.Binding.Elements[i] is MessageEncodingBindingElement) || (builder.Binding.Elements[i] is StreamUpgradeBindingElement))
                { 
                    continue; 
                }
                if (builder.Binding.Elements[i] is ChannelDemuxerBindingElement) 
                {
                    ++numChannelDemuxersBelowSecurity;
                }
                else if (builder.Binding.Elements[i] is TransportBindingElement) 
                {
                    break; 
                } 
                else
                { 
                    doesBindingHaveShapeChangingElements = true;
                }
            }
            if (numChannelDemuxersBelowSecurity == 1 && !doesBindingHaveShapeChangingElements) 
            {
                return; 
            } 
            ChannelDemuxerBindingElement demuxer = new ChannelDemuxerBindingElement(false);
            builder.Binding.Elements.Insert(0, demuxer); 
            secureConversationBindingContext.RemainingBindingElements.Insert(0, demuxer);
        }

        static BindingContext CreateIssuerBindingContextForNegotiation(BindingContext issuerBindingContext) 
        {
            TransportBindingElement transport = issuerBindingContext.RemainingBindingElements.Find(); 
            if (transport == null) 
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.TransportBindingElementNotFound))); 
            }
            ChannelDemuxerBindingElement demuxer = null;
            // pick the demuxer above transport (i.e. the last demuxer in the array)
            for (int i = 0; i < issuerBindingContext.RemainingBindingElements.Count; ++i) 
            {
                if (issuerBindingContext.RemainingBindingElements[i] is ChannelDemuxerBindingElement) 
                { 
                    demuxer = (ChannelDemuxerBindingElement) issuerBindingContext.RemainingBindingElements[i];
                } 
            }
            if (demuxer == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.ChannelDemuxerBindingElementNotFound))); 
            }
            BindingElementCollection negotiationBindingElements = new BindingElementCollection(); 
            negotiationBindingElements.Add(demuxer.Clone()); 
            negotiationBindingElements.Add(transport.Clone());
            CustomBinding binding = new CustomBinding(negotiationBindingElements); 
            binding.OpenTimeout = issuerBindingContext.Binding.OpenTimeout;
            binding.CloseTimeout = issuerBindingContext.Binding.CloseTimeout;
            binding.SendTimeout = issuerBindingContext.Binding.SendTimeout;
            binding.ReceiveTimeout = issuerBindingContext.Binding.ReceiveTimeout; 
            if (issuerBindingContext.ListenUriBaseAddress != null)
            { 
                return new BindingContext(binding, new BindingParameterCollection(issuerBindingContext.BindingParameters), issuerBindingContext.ListenUriBaseAddress, 
                    issuerBindingContext.ListenUriRelativeAddress, issuerBindingContext.ListenUriMode);
            } 
            else
            {
                return new BindingContext(binding, new BindingParameterCollection(issuerBindingContext.BindingParameters));
            } 
        }
 
        protected static void SetIssuerBindingContextIfRequired(SecurityTokenParameters parameters, BindingContext issuerBindingContext) 
        {
            if (parameters is SslSecurityTokenParameters) 
            {
                ((SslSecurityTokenParameters)parameters).IssuerBindingContext = CreateIssuerBindingContextForNegotiation(issuerBindingContext);
            }
            else if (parameters is SspiSecurityTokenParameters) 
            {
                ((SspiSecurityTokenParameters)parameters).IssuerBindingContext = CreateIssuerBindingContextForNegotiation(issuerBindingContext); 
            } 
        }
 
        static void SetIssuerBindingContextIfRequired(SupportingTokenParameters supportingParameters, BindingContext issuerBindingContext)
        {
            for (int i = 0; i < supportingParameters.Endorsing.Count; ++i)
            { 
                SetIssuerBindingContextIfRequired(supportingParameters.Endorsing[i], issuerBindingContext);
            } 
            for (int i = 0; i < supportingParameters.SignedEndorsing.Count; ++i) 
            {
                SetIssuerBindingContextIfRequired(supportingParameters.SignedEndorsing[i], issuerBindingContext); 
            }
            for (int i = 0; i < supportingParameters.Signed.Count; ++i)
            {
                SetIssuerBindingContextIfRequired(supportingParameters.Signed[i], issuerBindingContext); 
            }
            for (int i = 0; i < supportingParameters.SignedEncrypted.Count; ++i) 
            { 
                SetIssuerBindingContextIfRequired(supportingParameters.SignedEncrypted[i], issuerBindingContext);
            } 
        }

        void SetIssuerBindingContextIfRequired(BindingContext issuerBindingContext)
        { 
            SetIssuerBindingContextIfRequired(this.EndpointSupportingTokenParameters, issuerBindingContext);
            SetIssuerBindingContextIfRequired(this.OptionalEndpointSupportingTokenParameters, issuerBindingContext); 
            foreach (SupportingTokenParameters parameters in this.OperationSupportingTokenParameters.Values) 
            {
                SetIssuerBindingContextIfRequired(parameters, issuerBindingContext); 
            }
            foreach (SupportingTokenParameters parameters in this.OptionalOperationSupportingTokenParameters.Values)
            {
                SetIssuerBindingContextIfRequired(parameters, issuerBindingContext); 
            }
        } 
 
        internal bool RequiresChannelDemuxer(SecurityTokenParameters parameters)
        { 
            return ((parameters is SecureConversationSecurityTokenParameters)
                    || (parameters is SslSecurityTokenParameters)
                    || (parameters is SspiSecurityTokenParameters));
        } 

        internal virtual bool RequiresChannelDemuxer() 
        { 
            foreach (SecurityTokenParameters parameters in EndpointSupportingTokenParameters.Endorsing)
            { 
                if (RequiresChannelDemuxer(parameters))
                {
                    return true;
                } 
            }
            foreach (SecurityTokenParameters parameters in EndpointSupportingTokenParameters.SignedEndorsing) 
            { 
                if (RequiresChannelDemuxer(parameters))
                { 
                    return true;
                }
            }
            foreach (SecurityTokenParameters parameters in OptionalEndpointSupportingTokenParameters.Endorsing) 
            {
                if (RequiresChannelDemuxer(parameters)) 
                { 
                    return true;
                } 
            }
            foreach (SecurityTokenParameters parameters in OptionalEndpointSupportingTokenParameters.SignedEndorsing)
            {
                if (RequiresChannelDemuxer(parameters)) 
                {
                    return true; 
                } 
            }
            foreach (SupportingTokenParameters supportingParameters in OperationSupportingTokenParameters.Values) 
            {
                foreach (SecurityTokenParameters parameters in supportingParameters.Endorsing)
                {
                    if (RequiresChannelDemuxer(parameters)) 
                    {
                        return true; 
                    } 
                }
                foreach (SecurityTokenParameters parameters in supportingParameters.SignedEndorsing) 
                {
                    if (RequiresChannelDemuxer(parameters))
                    {
                        return true; 
                    }
                } 
            } 
            foreach (SupportingTokenParameters supportingParameters in OptionalOperationSupportingTokenParameters.Values)
            { 
                foreach (SecurityTokenParameters parameters in supportingParameters.Endorsing)
                {
                    if (RequiresChannelDemuxer(parameters))
                    { 
                        return true;
                    } 
                } 
                foreach (SecurityTokenParameters parameters in supportingParameters.SignedEndorsing)
                { 
                    if (RequiresChannelDemuxer(parameters))
                    {
                        return true;
                    } 
                }
            } 
            return false; 
        }
 
        internal bool IsUnderlyingListenerDuplex(BindingContext context)
        {
            return ((typeof(TChannel) == typeof(IDuplexSessionChannel)) && context.CanBuildInnerChannelListener()
                && !context.CanBuildInnerChannelListener()); 
        }
 
        void SetPrivacyNoticeUriIfRequired(SecurityProtocolFactory factory, Binding binding) 
        {
            PrivacyNoticeBindingElement privacyElement = binding.CreateBindingElements().Find(); 
            if (privacyElement != null)
            {
                factory.PrivacyNoticeUri = privacyElement.Url;
                factory.PrivacyNoticeVersion = privacyElement.Version; 
            }
        } 
 
        internal void ConfigureProtocolFactory(SecurityProtocolFactory factory, SecurityCredentialsManager credentialsManager, bool isForService, BindingContext issuerBindingContext, Binding binding)
        { 
            if (factory == null)
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("factory"));
            if (credentialsManager == null)
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("credentialsManager")); 

            factory.AddTimestamp = this.IncludeTimestamp; 
            factory.IncomingAlgorithmSuite = this.DefaultAlgorithmSuite; 
            factory.OutgoingAlgorithmSuite = this.DefaultAlgorithmSuite;
            factory.SecurityHeaderLayout = this.SecurityHeaderLayout; 
            if (!isForService)
            {
                factory.TimestampValidityDuration = this.LocalClientSettings.TimestampValidityDuration;
                factory.DetectReplays = this.LocalClientSettings.DetectReplays; 
                factory.MaxCachedNonces = this.LocalClientSettings.ReplayCacheSize;
                factory.MaxClockSkew = this.LocalClientSettings.MaxClockSkew; 
                factory.ReplayWindow = this.LocalClientSettings.ReplayWindow; 
            }
            else 
            {
                factory.TimestampValidityDuration = this.LocalServiceSettings.TimestampValidityDuration;
                factory.DetectReplays = this.LocalServiceSettings.DetectReplays;
                factory.MaxCachedNonces = this.LocalServiceSettings.ReplayCacheSize; 
                factory.MaxClockSkew = this.LocalServiceSettings.MaxClockSkew;
                factory.ReplayWindow = this.LocalServiceSettings.ReplayWindow; 
            } 

            factory.SecurityBindingElement = (SecurityBindingElement) this.Clone(); 
            factory.SecurityBindingElement.SetIssuerBindingContextIfRequired(issuerBindingContext);
            factory.SecurityTokenManager = credentialsManager.CreateSecurityTokenManager();
            SecurityTokenSerializer tokenSerializer = factory.SecurityTokenManager.CreateSecurityTokenSerializer(this.messageSecurityVersion.SecurityTokenVersion);
            factory.StandardsManager = new SecurityStandardsManager(this.messageSecurityVersion, tokenSerializer); 
            if (!isForService)
            { 
                SetPrivacyNoticeUriIfRequired(factory, binding); 
            }
        } 

        internal abstract SecurityProtocolFactory CreateSecurityProtocolFactory(BindingContext context, SecurityCredentialsManager credentialsManager,
        bool isForService, BindingContext issuanceBindingContext);
 
        public override IChannelFactory BuildChannelFactory(BindingContext context)
        { 
            if (context == null) 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("context");
 
            if (!this.CanBuildChannelFactory(context))
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.GetString(SR.ChannelTypeNotSupported, typeof(TChannel)), "TChannel"));
            } 

            this.readerQuotas = context.GetInnerProperty(); 
            if (readerQuotas == null) 
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.EncodingBindingElementDoesNotHandleReaderQuotas))); 
            }

            TransportBindingElement transportBindingElement = null;
 
            if (context.RemainingBindingElements != null)
                transportBindingElement = context.RemainingBindingElements.Find(); 
 
            if (transportBindingElement != null)
                this.maxReceivedMessageSize = transportBindingElement.MaxReceivedMessageSize; 

            return this.BuildChannelFactoryCore(context);
        }
 
        protected abstract IChannelFactory BuildChannelFactoryCore(BindingContext context);
 
        public override bool CanBuildChannelFactory(BindingContext context) 
        {
            if (context == null) 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("context");

            InternalDuplexBindingElement.AddDuplexFactorySupport(context, ref this.internalDuplexBindingElement);
 
            if (this.SessionMode)
            { 
                return this.CanBuildSessionChannelFactory(context); 
            }
 
            if (!context.CanBuildInnerChannelFactory())
            {
                return false;
            } 

            return typeof(TChannel) == typeof(IOutputChannel) || typeof(TChannel) == typeof(IOutputSessionChannel) || 
                (this.SupportsDuplex && (typeof(TChannel) == typeof(IDuplexChannel) || typeof(TChannel) == typeof(IDuplexSessionChannel))) || 
                (this.SupportsRequestReply && (typeof(TChannel) == typeof(IRequestChannel) || typeof(TChannel) == typeof(IRequestSessionChannel)));
        } 

        bool CanBuildSessionChannelFactory(BindingContext context)
        {
            if (!(context.CanBuildInnerChannelFactory() 
                || context.CanBuildInnerChannelFactory()
                || context.CanBuildInnerChannelFactory() 
                || context.CanBuildInnerChannelFactory())) 
            {
                return false; 
            }

            if (typeof(TChannel) == typeof(IRequestSessionChannel))
            { 
                return (context.CanBuildInnerChannelFactory() || context.CanBuildInnerChannelFactory());
            } 
            else if (typeof(TChannel) == typeof(IDuplexSessionChannel)) 
            {
                return (context.CanBuildInnerChannelFactory() || context.CanBuildInnerChannelFactory()); 
            }
            else
            {
                return false; 
            }
        } 
 
        public override IChannelListener BuildChannelListener(BindingContext context)
        { 
            if (context == null)
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("context");

            if (!this.CanBuildChannelListener(context)) 
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.GetString(SR.ChannelTypeNotSupported, typeof(TChannel)), "TChannel")); 
            } 

            this.readerQuotas = context.GetInnerProperty(); 
            if (readerQuotas == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.EncodingBindingElementDoesNotHandleReaderQuotas)));
            } 

            TransportBindingElement transportBindingElement = null; 
            if (context.RemainingBindingElements != null) 
                transportBindingElement = context.RemainingBindingElements.Find();
 
            if (transportBindingElement != null)
                this.maxReceivedMessageSize = transportBindingElement.MaxReceivedMessageSize;

            return this.BuildChannelListenerCore(context); 
        }
 
        protected abstract IChannelListener BuildChannelListenerCore(BindingContext context) 
            where TChannel : class, IChannel;
 
        public override bool CanBuildChannelListener(BindingContext context)
        {
            if (context == null)
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("context"); 

            InternalDuplexBindingElement.AddDuplexListenerSupport(context, ref this.internalDuplexBindingElement); 
 
            if (this.SessionMode)
            { 
                return this.CanBuildSessionChannelListener(context);
            }

            if (!context.CanBuildInnerChannelListener()) 
            {
                return false; 
            } 

            return typeof(TChannel) == typeof(IInputChannel) || typeof(TChannel) == typeof(IInputSessionChannel) || 
                (this.SupportsDuplex && (typeof(TChannel) == typeof(IDuplexChannel) || typeof(TChannel) == typeof(IDuplexSessionChannel))) ||
                (this.SupportsRequestReply && (typeof(TChannel) == typeof(IReplyChannel) || typeof(TChannel) == typeof(IReplySessionChannel)));
        }
 
        bool CanBuildSessionChannelListener(BindingContext context)
            where TChannel : class, IChannel 
        { 
            if (!(context.CanBuildInnerChannelListener()
                || context.CanBuildInnerChannelListener() 
                || context.CanBuildInnerChannelListener()
                || context.CanBuildInnerChannelListener()))
            {
                return false; 
            }
 
            if (typeof(TChannel) == typeof(IReplySessionChannel)) 
            {
                return (context.CanBuildInnerChannelListener() || context.CanBuildInnerChannelListener()); 
            }
            else if (typeof(TChannel) == typeof(IDuplexSessionChannel))
            {
                return (context.CanBuildInnerChannelListener() || context.CanBuildInnerChannelListener()); 
            }
            else 
            { 
                return false;
            } 
        }

        public virtual void SetKeyDerivation(bool requireDerivedKeys)
        { 
            this.EndpointSupportingTokenParameters.SetKeyDerivation(requireDerivedKeys);
            this.OptionalEndpointSupportingTokenParameters.SetKeyDerivation(requireDerivedKeys); 
            foreach (SupportingTokenParameters t in this.OperationSupportingTokenParameters.Values) 
                t.SetKeyDerivation(requireDerivedKeys);
            foreach (SupportingTokenParameters t in this.OptionalOperationSupportingTokenParameters.Values) 
            {
                t.SetKeyDerivation(requireDerivedKeys);
            }
        } 

        internal virtual bool IsSetKeyDerivation(bool requireDerivedKeys) 
        { 
            if (!this.EndpointSupportingTokenParameters.IsSetKeyDerivation(requireDerivedKeys))
                return false; 

            if (!this.OptionalEndpointSupportingTokenParameters.IsSetKeyDerivation(requireDerivedKeys))
                return false;
 
            foreach (SupportingTokenParameters t in this.OperationSupportingTokenParameters.Values)
            { 
                if (!t.IsSetKeyDerivation(requireDerivedKeys)) 
                    return false;
            } 
            foreach (SupportingTokenParameters t in this.OptionalOperationSupportingTokenParameters.Values)
            {
                if (!t.IsSetKeyDerivation(requireDerivedKeys))
                    return false; 
            }
            return true; 
        } 

        internal ChannelProtectionRequirements GetProtectionRequirements(AddressingVersion addressing, ProtectionLevel defaultProtectionLevel) 
        {
            if (addressing == null)
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("addressing");
 
            ChannelProtectionRequirements result = new ChannelProtectionRequirements();
            ProtectionLevel supportedRequestProtectionLevel = this.GetIndividualProperty().SupportedRequestProtectionLevel; 
            ProtectionLevel supportedResponseProtectionLevel = this.GetIndividualProperty().SupportedResponseProtectionLevel; 

            bool canSupportMoreThanTheDefault = 
                (ProtectionLevelHelper.IsStrongerOrEqual(supportedRequestProtectionLevel, defaultProtectionLevel)
                && ProtectionLevelHelper.IsStrongerOrEqual(supportedResponseProtectionLevel, defaultProtectionLevel));
            if (canSupportMoreThanTheDefault)
            { 
                MessagePartSpecification signedParts = new MessagePartSpecification();
                MessagePartSpecification encryptedParts = new MessagePartSpecification(); 
                if (defaultProtectionLevel != ProtectionLevel.None) 
                {
                    signedParts.IsBodyIncluded = true; 
                    if (defaultProtectionLevel == ProtectionLevel.EncryptAndSign)
                    {
                        encryptedParts.IsBodyIncluded = true;
                    } 
                }
                signedParts.MakeReadOnly(); 
                encryptedParts.MakeReadOnly(); 
                if (addressing.FaultAction != null)
                { 
                    // Addressing faults
                    result.IncomingSignatureParts.AddParts(signedParts, addressing.FaultAction);
                    result.OutgoingSignatureParts.AddParts(signedParts, addressing.FaultAction);
                    result.IncomingEncryptionParts.AddParts(encryptedParts, addressing.FaultAction); 
                    result.OutgoingEncryptionParts.AddParts(encryptedParts, addressing.FaultAction);
                } 
                if (addressing.DefaultFaultAction != null) 
                {
                    // Faults that do not specify a particular action 
                    result.IncomingSignatureParts.AddParts(signedParts, addressing.DefaultFaultAction);
                    result.OutgoingSignatureParts.AddParts(signedParts, addressing.DefaultFaultAction);
                    result.IncomingEncryptionParts.AddParts(encryptedParts, addressing.DefaultFaultAction);
                    result.OutgoingEncryptionParts.AddParts(encryptedParts, addressing.DefaultFaultAction); 
                }
                // Infrastructure faults 
                result.IncomingSignatureParts.AddParts(signedParts, FaultCodeConstants.Actions.NetDispatcher); 
                result.OutgoingSignatureParts.AddParts(signedParts, FaultCodeConstants.Actions.NetDispatcher);
                result.IncomingEncryptionParts.AddParts(encryptedParts, FaultCodeConstants.Actions.NetDispatcher); 
                result.OutgoingEncryptionParts.AddParts(encryptedParts, FaultCodeConstants.Actions.NetDispatcher);
            }

            return result; 
        }
 
        public override T GetProperty(BindingContext context) 
        {
            if (context == null) 
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("context");
            }
            if (typeof(T) == typeof(ISecurityCapabilities)) 
            {
                return (T)(object)GetSecurityCapabilities(context); 
            } 
            else if (typeof(T) == typeof(IdentityVerifier))
            { 
                return (T)(object)this.localClientSettings.IdentityVerifier;
            }
            else
            { 
                return context.GetInnerProperty();
            } 
        } 

        internal abstract ISecurityCapabilities GetIndividualISecurityCapabilities(); 

        ISecurityCapabilities GetSecurityCapabilities(BindingContext context)
        {
            ISecurityCapabilities thisSecurityCapability = this.GetIndividualISecurityCapabilities(); 
            ISecurityCapabilities lowerSecurityCapability = context.GetInnerProperty();
            if (lowerSecurityCapability == null) 
            { 
                return thisSecurityCapability;
            } 
            else
            {
                bool supportsClientAuth = thisSecurityCapability.SupportsClientAuthentication;
                bool supportsClientWindowsIdentity = thisSecurityCapability.SupportsClientWindowsIdentity; 
                bool supportsServerAuth = thisSecurityCapability.SupportsServerAuthentication || lowerSecurityCapability.SupportsServerAuthentication;
                ProtectionLevel requestProtectionLevel = ProtectionLevelHelper.Max(thisSecurityCapability.SupportedRequestProtectionLevel, lowerSecurityCapability.SupportedRequestProtectionLevel); 
                ProtectionLevel responseProtectionLevel = ProtectionLevelHelper.Max(thisSecurityCapability.SupportedResponseProtectionLevel, lowerSecurityCapability.SupportedResponseProtectionLevel); 
                return new SecurityCapabilities(supportsClientAuth, supportsServerAuth, supportsClientWindowsIdentity, requestProtectionLevel, responseProtectionLevel);
            } 
        }

        // If any changes are made to this method, please make sure that they are
        // reflected in the corresponding IsMutualCertificateBinding() method. 
        static public SecurityBindingElement CreateMutualCertificateBindingElement()
        { 
            return CreateMutualCertificateBindingElement(MessageSecurityVersion.WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11); 
        }
 
        // this method reverses CreateMutualCertificateBindingElement() logic
        internal static bool IsMutualCertificateBinding(SecurityBindingElement sbe)
        {
            return IsMutualCertificateBinding(sbe, false); 
        }
 
        static public AsymmetricSecurityBindingElement CreateCertificateSignatureBindingElement() 
        {
            AsymmetricSecurityBindingElement result; 

            result = new AsymmetricSecurityBindingElement(
                new X509SecurityTokenParameters( // recipient
                    X509KeyIdentifierClauseType.Any, 
                    SecurityTokenInclusionMode.Never, false),
                new X509SecurityTokenParameters( // initiator 
                    X509KeyIdentifierClauseType.Any, 
                    SecurityTokenInclusionMode.AlwaysToRecipient, false));
 
            // this is a one way binding so the client cannot detect replays
            result.IsCertificateSignatureBinding = true;
            result.LocalClientSettings.DetectReplays = false;
            result.MessageProtectionOrder = MessageProtectionOrder.SignBeforeEncrypt; 

            return result; 
        } 

        // If any changes are made to this method, please make sure that they are 
        // reflected in the corresponding IsMutualCertificateBinding() method.
        static public SecurityBindingElement CreateMutualCertificateBindingElement(MessageSecurityVersion version)
        {
            return CreateMutualCertificateBindingElement(version, false); 
        }
 
        // If any changes are made to this method, please make sure that they are 
        // reflected in the corresponding IsMutualCertificateBinding() method.
        static public SecurityBindingElement CreateMutualCertificateBindingElement(MessageSecurityVersion version, bool allowSerializedSigningTokenOnReply) 
        {
            if (version == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("version"); 
            }
            SecurityBindingElement result; 
 
            if (version.SecurityVersion == SecurityVersion.WSSecurity10)
            { 
                result = new AsymmetricSecurityBindingElement(
                    new X509SecurityTokenParameters( // recipient
                        X509KeyIdentifierClauseType.Any,
                        SecurityTokenInclusionMode.Never, 
                        false),
                    new X509SecurityTokenParameters( // initiator 
                        X509KeyIdentifierClauseType.Any, 
                        SecurityTokenInclusionMode.AlwaysToRecipient, false),
                    allowSerializedSigningTokenOnReply); 
            }
            else
            {
                result = new SymmetricSecurityBindingElement( 
                    new X509SecurityTokenParameters( // protection
                        X509KeyIdentifierClauseType.Thumbprint, 
                        SecurityTokenInclusionMode.Never)); 
                result.EndpointSupportingTokenParameters.Endorsing.Add(
                    new X509SecurityTokenParameters( 
                        X509KeyIdentifierClauseType.Thumbprint,
                        SecurityTokenInclusionMode.AlwaysToRecipient,
                        false));
                ((SymmetricSecurityBindingElement)result).RequireSignatureConfirmation = true; 
            }
 
            result.MessageSecurityVersion = version; 

            return result; 
        }

        // this method reverses CreateMutualCertificateDuplexBindingElement() logic
 
        internal static bool IsMutualCertificateDuplexBinding(SecurityBindingElement sbe)
        { 
 
            // Do not check MessageSecurityVersion: it maybe changed by the wrapper element and gets checked later in the SecuritySection.AreBindingsMatching()
 
            AsymmetricSecurityBindingElement asbe = sbe as AsymmetricSecurityBindingElement;
            if (asbe != null)
            {
                X509SecurityTokenParameters recipient = asbe.RecipientTokenParameters as X509SecurityTokenParameters; 
                if (recipient == null || (recipient.X509ReferenceStyle != X509KeyIdentifierClauseType.Any  && recipient.X509ReferenceStyle != X509KeyIdentifierClauseType.Thumbprint)|| recipient.InclusionMode != SecurityTokenInclusionMode.AlwaysToInitiator)
                    return false; 
 
                X509SecurityTokenParameters initiator = asbe.InitiatorTokenParameters as X509SecurityTokenParameters;
                if (initiator == null || (initiator.X509ReferenceStyle != X509KeyIdentifierClauseType.Any && initiator.X509ReferenceStyle != X509KeyIdentifierClauseType.Thumbprint) || initiator.InclusionMode != SecurityTokenInclusionMode.AlwaysToRecipient) 
                    return false;

                if (!sbe.EndpointSupportingTokenParameters.IsEmpty())
                    return false; 

                return true; 
            } 
            else
            { 
                return false;
            }
        }
 
        // this method reverses CreateMutualCertificateBindingElement() logic
        internal static bool IsMutualCertificateBinding(SecurityBindingElement sbe, bool allowSerializedSigningTokenOnReply) 
        { 

            // Do not check MessageSecurityVersion: it maybe changed by the wrapper element and gets checked later in the SecuritySection.AreBindingsMatching() 

            AsymmetricSecurityBindingElement asbe = sbe as AsymmetricSecurityBindingElement;
            if (asbe != null)
            { 
                X509SecurityTokenParameters recipient = asbe.RecipientTokenParameters as X509SecurityTokenParameters;
                if (recipient == null || recipient.X509ReferenceStyle != X509KeyIdentifierClauseType.Any || recipient.InclusionMode != SecurityTokenInclusionMode.Never) 
                    return false; 

                X509SecurityTokenParameters initiator = asbe.InitiatorTokenParameters as X509SecurityTokenParameters; 
                if (initiator == null || initiator.X509ReferenceStyle != X509KeyIdentifierClauseType.Any || initiator.InclusionMode != SecurityTokenInclusionMode.AlwaysToRecipient)
                    return false;

                if (!sbe.EndpointSupportingTokenParameters.IsEmpty()) 
                    return false;
            } 
            else 
            {
                SymmetricSecurityBindingElement ssbe = sbe as SymmetricSecurityBindingElement; 
                if (ssbe == null)
                    return false;

                X509SecurityTokenParameters x509Parameters = ssbe.ProtectionTokenParameters as X509SecurityTokenParameters; 
                if (x509Parameters == null || x509Parameters.X509ReferenceStyle != X509KeyIdentifierClauseType.Thumbprint || x509Parameters.InclusionMode != SecurityTokenInclusionMode.Never)
                    return false; 
 
                SupportingTokenParameters parameters = sbe.EndpointSupportingTokenParameters;
                if (parameters.Signed.Count != 0 || parameters.SignedEncrypted.Count != 0 || parameters.Endorsing.Count != 1 || parameters.SignedEndorsing.Count != 0) 
                    return false;

                x509Parameters = parameters.Endorsing[0] as X509SecurityTokenParameters;
                if (x509Parameters == null || x509Parameters.X509ReferenceStyle != X509KeyIdentifierClauseType.Thumbprint || x509Parameters.InclusionMode != SecurityTokenInclusionMode.AlwaysToRecipient) 
                    return false;
 
                if (!ssbe.RequireSignatureConfirmation) 
                    return false;
 
            }
            return true;
        }
 
        // If any changes are made to this method, please make sure that they are
        // reflected in the corresponding IsAnonymousForCertificateBinding() method. 
        static public SymmetricSecurityBindingElement CreateAnonymousForCertificateBindingElement() 
        {
            SymmetricSecurityBindingElement result; 

            result = new SymmetricSecurityBindingElement(
                new X509SecurityTokenParameters( // protection
                    X509KeyIdentifierClauseType.Thumbprint, 
                    SecurityTokenInclusionMode.Never));
            result.MessageSecurityVersion = MessageSecurityVersion.WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11; 
            result.RequireSignatureConfirmation = true; 

            return result; 
        }

        // this method reverses CreateAnonymousForCertificateBindingElement() logic
        internal static bool IsAnonymousForCertificateBinding(SecurityBindingElement sbe) 
        {
            SymmetricSecurityBindingElement ssbe = sbe as SymmetricSecurityBindingElement; 
            if (ssbe == null) 
                return false;
 
            if (!ssbe.RequireSignatureConfirmation)
                return false;

            // Do not check MessageSecurityVersion: it maybe changed by the wrapper element and gets checked later in the SecuritySection.AreBindingsMatching() 

            X509SecurityTokenParameters x509Parameters = ssbe.ProtectionTokenParameters as X509SecurityTokenParameters; 
            if (x509Parameters == null || x509Parameters.X509ReferenceStyle != X509KeyIdentifierClauseType.Thumbprint || x509Parameters.InclusionMode != SecurityTokenInclusionMode.Never) 
                return false;
 
            if (!sbe.EndpointSupportingTokenParameters.IsEmpty())
                return false;

            return true; 
        }
 
        static public AsymmetricSecurityBindingElement CreateMutualCertificateDuplexBindingElement() 
        {
            return CreateMutualCertificateDuplexBindingElement(MessageSecurityVersion.WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11); 
        }

        static public AsymmetricSecurityBindingElement CreateMutualCertificateDuplexBindingElement(MessageSecurityVersion version)
        { 
            if (version == null)
            { 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("version"); 
            }
            AsymmetricSecurityBindingElement result; 

            if (version.SecurityVersion == SecurityVersion.WSSecurity10)
            {
                result = new AsymmetricSecurityBindingElement( 
                    new X509SecurityTokenParameters( // recipient
                        X509KeyIdentifierClauseType.Any, 
                        SecurityTokenInclusionMode.AlwaysToInitiator, 
                        false),
                    new X509SecurityTokenParameters( // initiator 
                        X509KeyIdentifierClauseType.Any,
                        SecurityTokenInclusionMode.AlwaysToRecipient,
                        false));
            } 
            else
            { 
                result = new AsymmetricSecurityBindingElement( 
                    new X509SecurityTokenParameters( // recipient
                        X509KeyIdentifierClauseType.Thumbprint, 
                        SecurityTokenInclusionMode.AlwaysToInitiator,
                        false),
                    new X509SecurityTokenParameters( // initiator
                        X509KeyIdentifierClauseType.Thumbprint, 
                        SecurityTokenInclusionMode.AlwaysToRecipient,
                        false)); 
            } 

            result.MessageSecurityVersion = version; 

            return result;
        }
 
        // If any changes are made to this method, please make sure that they are
        // reflected in the corresponding IsUserNameForCertificateBinding() method. 
        static public SymmetricSecurityBindingElement CreateUserNameForCertificateBindingElement() 
        {
            SymmetricSecurityBindingElement result = new SymmetricSecurityBindingElement( 
                new X509SecurityTokenParameters(
                    X509KeyIdentifierClauseType.Thumbprint,
                    SecurityTokenInclusionMode.Never));
            result.EndpointSupportingTokenParameters.SignedEncrypted.Add( 
                new UserNameSecurityTokenParameters());
            result.MessageSecurityVersion = MessageSecurityVersion.WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11; 
 
            return result;
        } 

        // this method reverses CreateMutualCertificateBindingElement() logic
        internal static bool IsUserNameForCertificateBinding(SecurityBindingElement sbe)
        { 
            // Do not check MessageSecurityVersion: it maybe changed by the wrapper element and gets checked later in the SecuritySection.AreBindingsMatching()
 
            SymmetricSecurityBindingElement ssbe = sbe as SymmetricSecurityBindingElement; 
            if (ssbe == null)
                return false; 

            X509SecurityTokenParameters x509Parameters = ssbe.ProtectionTokenParameters as X509SecurityTokenParameters;
            if (x509Parameters == null || x509Parameters.X509ReferenceStyle != X509KeyIdentifierClauseType.Thumbprint || x509Parameters.InclusionMode != SecurityTokenInclusionMode.Never)
                return false; 

            SupportingTokenParameters parameters = sbe.EndpointSupportingTokenParameters; 
            if (parameters.Signed.Count != 0 || parameters.SignedEncrypted.Count != 1 || parameters.Endorsing.Count != 0 || parameters.SignedEndorsing.Count != 0) 
                return false;
 
            UserNameSecurityTokenParameters userNameParameters = parameters.SignedEncrypted[0] as UserNameSecurityTokenParameters;
            if (userNameParameters == null)
                return false;
 
            return true;
        } 
 
        // If any changes are made to this method, please make sure that they are
        // reflected in the corresponding IsKerberosBinding() method. 
        static public SymmetricSecurityBindingElement CreateKerberosBindingElement()
        {
            SymmetricSecurityBindingElement result = new SymmetricSecurityBindingElement(
                new KerberosSecurityTokenParameters()); 
            result.DefaultAlgorithmSuite = SecurityAlgorithmSuite.KerberosDefault;
            return result; 
        } 

        // this method reverses CreateMutualCertificateBindingElement() logic 
        internal static bool IsKerberosBinding(SecurityBindingElement sbe)
        {
            // do not check DefaultAlgorithmSuite match: it is often changed by the caller of CreateKerberosBindingElement
            SymmetricSecurityBindingElement ssbe = sbe as SymmetricSecurityBindingElement; 
            if (ssbe == null)
                return false; 
 
            KerberosSecurityTokenParameters parameters = ssbe.ProtectionTokenParameters as KerberosSecurityTokenParameters;
            if (parameters == null) 
                return false;

            if (!sbe.EndpointSupportingTokenParameters.IsEmpty())
                return false; 

            return true; 
        } 

        static public SymmetricSecurityBindingElement CreateSspiNegotiationBindingElement() 
        {
            return CreateSspiNegotiationBindingElement(SspiSecurityTokenParameters.defaultRequireCancellation);
        }
 
        // If any changes are made to this method, please make sure that they are
        // reflected in the corresponding IsSspiNegotiationBinding() method. 
        static public SymmetricSecurityBindingElement CreateSspiNegotiationBindingElement(bool requireCancellation) 
        {
            SymmetricSecurityBindingElement result = new SymmetricSecurityBindingElement( 
                new SspiSecurityTokenParameters(requireCancellation));
            return result;
        }
 
        // this method reverses CreateMutualCertificateBindingElement() logic
        internal static bool IsSspiNegotiationBinding(SecurityBindingElement sbe, bool requireCancellation) 
        { 
            SymmetricSecurityBindingElement ssbe  = sbe as SymmetricSecurityBindingElement;
 
            if (ssbe == null)
                return false;

            if (!sbe.EndpointSupportingTokenParameters.IsEmpty()) 
                return false;
 
            SspiSecurityTokenParameters sspiParameters = ssbe.ProtectionTokenParameters as SspiSecurityTokenParameters; 
            if (sspiParameters == null)
                return false; 

            return sspiParameters.RequireCancellation == requireCancellation;
        }
 

        static public SymmetricSecurityBindingElement CreateSslNegotiationBindingElement(bool requireClientCertificate) 
        { 
            return CreateSslNegotiationBindingElement(requireClientCertificate, SslSecurityTokenParameters.defaultRequireCancellation);
        } 

        // If any changes are made to this method, please make sure that they are
        // reflected in the corresponding IsSslNegotiationBinding() method.
        static public SymmetricSecurityBindingElement CreateSslNegotiationBindingElement(bool requireClientCertificate, bool requireCancellation) 
        {
            SymmetricSecurityBindingElement result = new SymmetricSecurityBindingElement( 
                new SslSecurityTokenParameters(requireClientCertificate, requireCancellation)); 
            return result;
        } 

        // this method reverses CreateMutualCertificateBindingElement() logic
        internal static bool IsSslNegotiationBinding(SecurityBindingElement sbe, bool requireClientCertificate, bool requireCancellation)
        { 
            SymmetricSecurityBindingElement ssbe = sbe as SymmetricSecurityBindingElement;
            if (ssbe == null) 
                return false; 

            if (!sbe.EndpointSupportingTokenParameters.IsEmpty()) 
                return false;

            SslSecurityTokenParameters sslParameters = ssbe.ProtectionTokenParameters as SslSecurityTokenParameters;
            if (sslParameters == null) 
                return false;
 
            return sslParameters.RequireClientCertificate == requireClientCertificate && sslParameters.RequireCancellation == requireCancellation; 

        } 
        static public SymmetricSecurityBindingElement CreateIssuedTokenBindingElement(IssuedSecurityTokenParameters issuedTokenParameters)
        {
            if (issuedTokenParameters == null)
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("issuedTokenParameters"); 
            if (issuedTokenParameters.KeyType != SecurityKeyType.SymmetricKey)
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument(SR.GetString(SR.IssuedTokenAuthenticationModeRequiresSymmetricIssuedKey)); 
            SymmetricSecurityBindingElement result = new SymmetricSecurityBindingElement(issuedTokenParameters); 
            return result;
        } 

        // If any changes are made to this method, please make sure that they are
        // reflected in the corresponding IsIssuedTokenForCertificateBinding() method.
        static public SymmetricSecurityBindingElement CreateIssuedTokenForCertificateBindingElement(IssuedSecurityTokenParameters issuedTokenParameters) 
        {
            if (issuedTokenParameters == null) 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("issuedTokenParameters"); 

            SymmetricSecurityBindingElement result = new SymmetricSecurityBindingElement( 
                new X509SecurityTokenParameters(
                    X509KeyIdentifierClauseType.Thumbprint,
                    SecurityTokenInclusionMode.Never));
            if (issuedTokenParameters.KeyType == SecurityKeyType.BearerKey) 
            {
                result.EndpointSupportingTokenParameters.SignedEncrypted.Add(issuedTokenParameters); 
                result.MessageSecurityVersion = MessageSecurityVersion.WSSXDefault; 
            }
            else 
            {
                result.EndpointSupportingTokenParameters.Endorsing.Add(issuedTokenParameters);
                result.MessageSecurityVersion = MessageSecurityVersion.Default;
            } 
            result.RequireSignatureConfirmation = true;
            return result; 
        } 

        // this method reverses CreateMutualCertificateBindingElement() logic 
        internal static bool IsIssuedTokenForCertificateBinding(SecurityBindingElement sbe, out IssuedSecurityTokenParameters issuedTokenParameters)
        {
            issuedTokenParameters = null;
            SymmetricSecurityBindingElement ssbe = sbe as SymmetricSecurityBindingElement; 
            if (ssbe == null)
                return false; 
 
            if (!ssbe.RequireSignatureConfirmation)
                return false; 

            // Do not check MessageSecurityVersion: it maybe changed by the wrapper element and gets checked later in the SecuritySection.AreBindingsMatching()

            X509SecurityTokenParameters x509Parameters = ssbe.ProtectionTokenParameters as X509SecurityTokenParameters; 
            if (x509Parameters == null || x509Parameters.X509ReferenceStyle != X509KeyIdentifierClauseType.Thumbprint || x509Parameters.InclusionMode != SecurityTokenInclusionMode.Never)
                return false; 
 
            SupportingTokenParameters parameters = ssbe.EndpointSupportingTokenParameters;
            if (parameters.Signed.Count != 0 || (parameters.SignedEncrypted.Count == 0 && parameters.Endorsing.Count == 0) || parameters.SignedEndorsing.Count != 0) 
                return false;

            if ((parameters.SignedEncrypted.Count == 1) && (parameters.Endorsing.Count == 0))
            { 
                issuedTokenParameters = parameters.SignedEncrypted[0] as IssuedSecurityTokenParameters;
                if (issuedTokenParameters != null && issuedTokenParameters.KeyType != SecurityKeyType.BearerKey) 
                    return false; 
            }
            else if ((parameters.Endorsing.Count == 1) && (parameters.SignedEncrypted.Count == 0)) 
            {
                issuedTokenParameters = parameters.Endorsing[0] as IssuedSecurityTokenParameters;
                if (issuedTokenParameters != null && (issuedTokenParameters.KeyType != SecurityKeyType.SymmetricKey && issuedTokenParameters.KeyType != SecurityKeyType.AsymmetricKey))
                    return false; 
            }
            return (issuedTokenParameters != null); 
        } 

        // If any changes are made to this method, please make sure that they are 
        // reflected in the corresponding IsIssuedTokenForSslBinding() method.
        static public SymmetricSecurityBindingElement CreateIssuedTokenForSslBindingElement(IssuedSecurityTokenParameters issuedTokenParameters)
        {
            return CreateIssuedTokenForSslBindingElement(issuedTokenParameters, SslSecurityTokenParameters.defaultRequireCancellation); 
        }
 
        // this method reverses CreateMutualCertificateBindingElement() logic 
        internal static bool IsIssuedTokenForSslBinding(SecurityBindingElement sbe, out IssuedSecurityTokenParameters issuedTokenParameters)
        { 
            return IsIssuedTokenForSslBinding(sbe, SslSecurityTokenParameters.defaultRequireCancellation, out issuedTokenParameters);
        }

        // If any changes are made to this method, please make sure that they are 
        // reflected in the corresponding IsIssuedTokenForSslBinding() method.
        static public SymmetricSecurityBindingElement CreateIssuedTokenForSslBindingElement(IssuedSecurityTokenParameters issuedTokenParameters, bool requireCancellation) 
        { 
            if (issuedTokenParameters == null)
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("issuedTokenParameters"); 

            SymmetricSecurityBindingElement result = new SymmetricSecurityBindingElement(
                new SslSecurityTokenParameters(false, requireCancellation));
            if (issuedTokenParameters.KeyType == SecurityKeyType.BearerKey) 
            {
                result.EndpointSupportingTokenParameters.SignedEncrypted.Add(issuedTokenParameters); 
                result.MessageSecurityVersion = MessageSecurityVersion.WSSXDefault; 
            }
            else 
            {
                result.EndpointSupportingTokenParameters.Endorsing.Add(issuedTokenParameters);
                result.MessageSecurityVersion = MessageSecurityVersion.Default;
            } 
            result.RequireSignatureConfirmation = true;
            return result; 
        } 

        // this method reverses CreateMutualCertificateBindingElement() logic 
        internal static bool IsIssuedTokenForSslBinding(SecurityBindingElement sbe, bool requireCancellation, out IssuedSecurityTokenParameters issuedTokenParameters)
        {
            issuedTokenParameters = null;
            SymmetricSecurityBindingElement ssbe = sbe as SymmetricSecurityBindingElement; 
            if (ssbe == null)
                return false; 
 
            if (!ssbe.RequireSignatureConfirmation)
                return false; 

            // Do not check MessageSecurityVersion: it maybe changed by the wrapper element and gets checked later in the SecuritySection.AreBindingsMatching()

            SslSecurityTokenParameters sslParameters = ssbe.ProtectionTokenParameters as SslSecurityTokenParameters; 
            if (sslParameters == null)
                return false; 
 
            if (sslParameters.RequireClientCertificate || sslParameters.RequireCancellation != requireCancellation)
                return false; 

            SupportingTokenParameters parameters = ssbe.EndpointSupportingTokenParameters;
            if (parameters.Signed.Count != 0 || (parameters.SignedEncrypted.Count == 0 && parameters.Endorsing.Count == 0) || parameters.SignedEndorsing.Count != 0)
                return false; 

            if ((parameters.SignedEncrypted.Count == 1) && (parameters.Endorsing.Count == 0)) 
            { 
                issuedTokenParameters = parameters.SignedEncrypted[0] as IssuedSecurityTokenParameters;
                if (issuedTokenParameters != null && issuedTokenParameters.KeyType != SecurityKeyType.BearerKey) 
                    return false;
            }
            else if ((parameters.Endorsing.Count == 1) && (parameters.SignedEncrypted.Count == 0))
            { 
                issuedTokenParameters = parameters.Endorsing[0] as IssuedSecurityTokenParameters;
                if (issuedTokenParameters != null && (issuedTokenParameters.KeyType != SecurityKeyType.SymmetricKey && issuedTokenParameters.KeyType != SecurityKeyType.AsymmetricKey)) 
                    return false; 
            }
            return (issuedTokenParameters != null); 
        }

        static public SymmetricSecurityBindingElement CreateUserNameForSslBindingElement()
        { 
            return CreateUserNameForSslBindingElement(SslSecurityTokenParameters.defaultRequireCancellation);
        } 
 
        // If any changes are made to this method, please make sure that they are
        // reflected in the corresponding IsUserNameForSslBinding() method. 
        static public SymmetricSecurityBindingElement CreateUserNameForSslBindingElement(bool requireCancellation)
        {
            SymmetricSecurityBindingElement result = new SymmetricSecurityBindingElement(
                new SslSecurityTokenParameters(false, requireCancellation)); 
            result.EndpointSupportingTokenParameters.SignedEncrypted.Add(
                new UserNameSecurityTokenParameters()); 
            result.MessageSecurityVersion = MessageSecurityVersion.WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11; 

            return result; 
        }

        // this method reverses CreateMutualCertificateBindingElement() logic
        internal static bool IsUserNameForSslBinding(SecurityBindingElement sbe, bool requireCancellation) 
        {
            // Do not check MessageSecurityVersion: it maybe changed by the wrapper element and gets checked later in the SecuritySection.AreBindingsMatching() 
 
            SymmetricSecurityBindingElement ssbe = sbe as SymmetricSecurityBindingElement;
            if (ssbe == null) 
                return false;

            SupportingTokenParameters parameters = sbe.EndpointSupportingTokenParameters;
            if (parameters.Signed.Count != 0 || parameters.SignedEncrypted.Count != 1 || parameters.Endorsing.Count != 0 || parameters.SignedEndorsing.Count != 0) 
                return false;
 
            if (!(parameters.SignedEncrypted[0] is UserNameSecurityTokenParameters)) 
                return false;
 
            SslSecurityTokenParameters sslParameters = ssbe.ProtectionTokenParameters as SslSecurityTokenParameters;
            if (sslParameters == null)
                return false;
 
            return sslParameters.RequireCancellation == requireCancellation && !sslParameters.RequireClientCertificate;
        } 
 
        // If any changes are made to this method, please make sure that they are
        // reflected in the corresponding IsUserNameOverTransportBinding() method. 
        static public TransportSecurityBindingElement CreateUserNameOverTransportBindingElement()
        {
            TransportSecurityBindingElement result = new TransportSecurityBindingElement();
            result.EndpointSupportingTokenParameters.SignedEncrypted.Add( 
                new UserNameSecurityTokenParameters());
            result.IncludeTimestamp = true; 
            result.LocalClientSettings.DetectReplays = false; 
            result.LocalServiceSettings.DetectReplays = false;
            return result; 
        }

        // this method reverses CreateMutualCertificateBindingElement() logic
        internal static bool IsUserNameOverTransportBinding(SecurityBindingElement sbe) 
        {
            // do not check local settings: sbe.LocalServiceSettings and sbe.LocalClientSettings 
            if (!sbe.IncludeTimestamp) 
                return false;
 
            if (!(sbe is TransportSecurityBindingElement))
                return false;

            SupportingTokenParameters parameters = sbe.EndpointSupportingTokenParameters; 
            if (parameters.Signed.Count != 0 || parameters.SignedEncrypted.Count != 1 || parameters.Endorsing.Count != 0 || parameters.SignedEndorsing.Count != 0)
                return false; 
 
            UserNameSecurityTokenParameters userNameParameters = parameters.SignedEncrypted[0] as UserNameSecurityTokenParameters;
            if (userNameParameters == null) 
                return false;

            return true;
        } 

        // If any changes are made to this method, please make sure that they are 
        // reflected in the corresponding IsCertificateOverTransportBinding() method. 
        static public TransportSecurityBindingElement CreateCertificateOverTransportBindingElement()
        { 
            return CreateCertificateOverTransportBindingElement(MessageSecurityVersion.Default);
        }

        // If any changes are made to this method, please make sure that they are 
        // reflected in the corresponding IsCertificateOverTransportBinding() method.
        static public TransportSecurityBindingElement CreateCertificateOverTransportBindingElement(MessageSecurityVersion version) 
        { 
            if (version == null)
            { 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("version");
            }
            X509KeyIdentifierClauseType x509ReferenceType;
 
            if (version.SecurityVersion == SecurityVersion.WSSecurity10)
            { 
                x509ReferenceType = X509KeyIdentifierClauseType.Any; 
            }
            else 
            {
                x509ReferenceType = X509KeyIdentifierClauseType.Thumbprint;
            }
 
            TransportSecurityBindingElement result = new TransportSecurityBindingElement();
            X509SecurityTokenParameters x509Parameters = new X509SecurityTokenParameters( 
                    x509ReferenceType, 
                    SecurityTokenInclusionMode.AlwaysToRecipient,
                    false); 
            result.EndpointSupportingTokenParameters.Endorsing.Add(
                x509Parameters
                );
            result.IncludeTimestamp = true; 
            result.LocalClientSettings.DetectReplays = false;
            result.LocalServiceSettings.DetectReplays = false; 
            result.MessageSecurityVersion = version; 

            return result; 
        }

        // this method reverses CreateMutualCertificateBindingElement() logic
        internal static bool IsCertificateOverTransportBinding(SecurityBindingElement sbe) 
        {
            // do not check local settings: sbe.LocalServiceSettings and sbe.LocalClientSettings 
            if (!sbe.IncludeTimestamp) 
                return false;
 
            if (!(sbe is TransportSecurityBindingElement))
                return false;

            SupportingTokenParameters parameters = sbe.EndpointSupportingTokenParameters; 
            if (parameters.Signed.Count != 0 || parameters.SignedEncrypted.Count != 0 || parameters.Endorsing.Count != 1 || parameters.SignedEndorsing.Count != 0)
                return false; 
 
            X509SecurityTokenParameters x509Parameters = parameters.Endorsing[0] as X509SecurityTokenParameters;
            if (x509Parameters == null) 
                return false;

            if (x509Parameters.InclusionMode != SecurityTokenInclusionMode.AlwaysToRecipient)
                return false; 

            return x509Parameters.X509ReferenceStyle == X509KeyIdentifierClauseType.Any || x509Parameters.X509ReferenceStyle == X509KeyIdentifierClauseType.Thumbprint; 
        } 

        static public TransportSecurityBindingElement CreateKerberosOverTransportBindingElement() 
        {
            TransportSecurityBindingElement result = new TransportSecurityBindingElement();
            KerberosSecurityTokenParameters kerberosParameters = new KerberosSecurityTokenParameters();
            kerberosParameters.RequireDerivedKeys = false; 
            result.EndpointSupportingTokenParameters.Endorsing.Add(
                kerberosParameters); 
            result.IncludeTimestamp = true; 
            result.LocalClientSettings.DetectReplays = false;
            result.LocalServiceSettings.DetectReplays = false; 
            result.DefaultAlgorithmSuite = SecurityAlgorithmSuite.KerberosDefault;

            return result;
        } 
#if NO
        // this is reversing of the CreateKerberosOverTransportBindingElement() logic 
        static bool IsKerberosOverTransportBinding(SecurityBindingElement sbe) 
        {
            if (sbe.DefaultAlgorithmSuite != SecurityAlgorithmSuite.KerberosDefault) 
                return false;

            // do not check local settings: sbe.LocalServiceSettings and sbe.LocalClientSettings
 
            if (!sbe.IncludeTimestamp)
                return false; 
 
            if (!(sbe is TransportSecurityBindingElement))
                return false; 

            SupportingTokenParameters parameters = sbe.EndpointSupportingTokenParameters;
            if (parameters.Signed.Count != 0 || parameters.SignedEncrypted.Count != 0 || parameters.Endorsing.Count != 1 || parameters.SignedEndorsing.Count != 0)
                return false; 

            KerberosSecurityTokenParameters kerberosParameters = parameters.Endorsing[0] as KerberosSecurityTokenParameters; 
            if (kerberosParameters == null) 
                return false;
 
            if (kerberosParameters.RequireDerivedKeys)
                return false;

            return true; 
        }
#endif 
        static public TransportSecurityBindingElement CreateSspiNegotiationOverTransportBindingElement() 
        {
            return CreateSspiNegotiationOverTransportBindingElement(true); 
        }

        // If any changes are made to this method, please make sure that they are
        // reflected in the corresponding IsSspiNegotiationOverTransportBinding() method. 
        static public TransportSecurityBindingElement CreateSspiNegotiationOverTransportBindingElement(bool requireCancellation)
        { 
            TransportSecurityBindingElement result = new TransportSecurityBindingElement(); 
            SspiSecurityTokenParameters sspiParameters = new SspiSecurityTokenParameters(requireCancellation);
            sspiParameters.RequireDerivedKeys = false; 
            result.EndpointSupportingTokenParameters.Endorsing.Add(
                sspiParameters);
            result.IncludeTimestamp = true;
            result.LocalClientSettings.DetectReplays = false; 
            result.LocalServiceSettings.DetectReplays = false;
 
            return result; 
        }
 
        // this method reverses CreateSspiNegotiationOverTransportBindingElement() logic
        internal static bool IsSspiNegotiationOverTransportBinding(SecurityBindingElement sbe, bool requireCancellation)
        {
            // do not check local settings: sbe.LocalServiceSettings and sbe.LocalClientSettings 

            if (!sbe.IncludeTimestamp) 
                return false; 

            SupportingTokenParameters parameters = sbe.EndpointSupportingTokenParameters; 
            if (parameters.Signed.Count != 0 || parameters.SignedEncrypted.Count != 0 || parameters.Endorsing.Count != 1 || parameters.SignedEndorsing.Count != 0)
                return false;
            SspiSecurityTokenParameters sspiParameters = parameters.Endorsing[0] as SspiSecurityTokenParameters;
            if (sspiParameters == null) 
                return false;
 
            if (sspiParameters.RequireDerivedKeys) 
                return false;
 
            if (sspiParameters.RequireCancellation != requireCancellation)
                return false;

            if (!(sbe is TransportSecurityBindingElement)) 
                return false;
 
            return true; 
        }
 
        // If any changes are made to this method, please make sure that they are
        // reflected in the corresponding IsIssuedTokenOverTransportBinding() method.
        static public TransportSecurityBindingElement CreateIssuedTokenOverTransportBindingElement(IssuedSecurityTokenParameters issuedTokenParameters)
        { 
            if (issuedTokenParameters == null)
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("issuedTokenParameters"); 
 
            issuedTokenParameters.RequireDerivedKeys = false;
            TransportSecurityBindingElement result = new TransportSecurityBindingElement(); 
            if (issuedTokenParameters.KeyType == SecurityKeyType.BearerKey)
            {
                result.EndpointSupportingTokenParameters.Signed.Add(issuedTokenParameters);
                result.MessageSecurityVersion = MessageSecurityVersion.WSSXDefault; 
            }
            else 
            { 
                result.EndpointSupportingTokenParameters.Endorsing.Add(issuedTokenParameters);
                result.MessageSecurityVersion = MessageSecurityVersion.Default; 
            }
            result.LocalClientSettings.DetectReplays = false;
            result.LocalServiceSettings.DetectReplays = false;
            result.IncludeTimestamp = true; 

            return result; 
        } 

        // this method reverses CreateIssuedTokenOverTransportBindingElement() logic 
        internal static bool IsIssuedTokenOverTransportBinding(SecurityBindingElement sbe, out IssuedSecurityTokenParameters issuedTokenParameters)
        {
            issuedTokenParameters = null;
            if (!(sbe is TransportSecurityBindingElement)) 
                return false;
 
            if (!sbe.IncludeTimestamp) 
                return false;
 
            // do not check local settings: sbe.LocalServiceSettings and sbe.LocalClientSettings

            SupportingTokenParameters parameters = sbe.EndpointSupportingTokenParameters;
            if (parameters.SignedEncrypted.Count != 0 || (parameters.Signed.Count == 0 && parameters.Endorsing.Count == 0) || parameters.SignedEndorsing.Count != 0) 
                return false;
            if ((parameters.Signed.Count == 1) && (parameters.Endorsing.Count == 0)) 
            { 
                issuedTokenParameters = parameters.Signed[0] as IssuedSecurityTokenParameters;
                if (issuedTokenParameters != null && issuedTokenParameters.KeyType != SecurityKeyType.BearerKey) 
                    return false;
            }
            else if ((parameters.Endorsing.Count == 1) && (parameters.Signed.Count == 0))
            { 
                issuedTokenParameters = parameters.Endorsing[0] as IssuedSecurityTokenParameters;
                if (issuedTokenParameters != null && (issuedTokenParameters.KeyType != SecurityKeyType.SymmetricKey && issuedTokenParameters.KeyType != SecurityKeyType.AsymmetricKey)) 
                    return false; 
            }
            if (issuedTokenParameters == null) 
                return false;
            if (issuedTokenParameters.RequireDerivedKeys)
                return false;
 
            return true;
        } 
 
        // If any changes are made to this method, please make sure that they are
        // reflected in the corresponding IsSecureConversationBinding() method. 
        static public SecurityBindingElement CreateSecureConversationBindingElement(SecurityBindingElement bootstrapSecurity)
        {
            return CreateSecureConversationBindingElement(bootstrapSecurity, SecureConversationSecurityTokenParameters.defaultRequireCancellation, null);
        } 

        // this method reverses CreateSecureConversationBindingElement() logic 
        internal static bool IsSecureConversationBinding(SecurityBindingElement sbe, out SecurityBindingElement bootstrapSecurity) 
        {
            return IsSecureConversationBinding(sbe, SecureConversationSecurityTokenParameters.defaultRequireCancellation, out bootstrapSecurity); 
        }

        static public SecurityBindingElement CreateSecureConversationBindingElement(SecurityBindingElement bootstrapSecurity, bool requireCancellation)
        { 
            return CreateSecureConversationBindingElement(bootstrapSecurity, requireCancellation, null);
        } 
 
        // If any changes are made to this method, please make sure that they are
        // reflected in the corresponding IsSecureConversationBinding() method. 
        static public SecurityBindingElement CreateSecureConversationBindingElement(SecurityBindingElement bootstrapSecurity, bool requireCancellation, ChannelProtectionRequirements bootstrapProtectionRequirements)
        {
            if (bootstrapSecurity == null)
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("bootstrapBinding"); 

            SecurityBindingElement result; 
 
            if (bootstrapSecurity is TransportSecurityBindingElement)
            { 
                // there is no need to do replay detection or key derivation for transport bindings
                TransportSecurityBindingElement primary = new TransportSecurityBindingElement();
                SecureConversationSecurityTokenParameters scParameters = new SecureConversationSecurityTokenParameters(
                        bootstrapSecurity, 
                        requireCancellation,
                        bootstrapProtectionRequirements); 
                scParameters.RequireDerivedKeys = false; 
                primary.EndpointSupportingTokenParameters.Endorsing.Add(
                    scParameters); 
                primary.LocalClientSettings.DetectReplays = false;
                primary.LocalServiceSettings.DetectReplays = false;
                primary.IncludeTimestamp = true;
                result = primary; 
            }
            else // Symmetric- or AsymmetricSecurityBindingElement 
            { 
                SymmetricSecurityBindingElement primary = new SymmetricSecurityBindingElement(
                    new SecureConversationSecurityTokenParameters( 
                        bootstrapSecurity,
                        requireCancellation,
                        bootstrapProtectionRequirements));
                // there is no need for signature confirmation on the steady state binding 
                primary.RequireSignatureConfirmation = false;
                result = primary; 
            } 

            return result; 
        }

        // this method reverses CreateSecureConversationBindingElement() logic
        internal static bool IsSecureConversationBinding(SecurityBindingElement sbe, bool requireCancellation, out SecurityBindingElement bootstrapSecurity) 
        {
            bootstrapSecurity = null; 
            SymmetricSecurityBindingElement ssbe = sbe as SymmetricSecurityBindingElement; 
            if (ssbe != null)
            { 
                if (ssbe.RequireSignatureConfirmation)
                    return false;

                SecureConversationSecurityTokenParameters parameters = ssbe.ProtectionTokenParameters as SecureConversationSecurityTokenParameters; 
                if (parameters == null)
                    return false; 
                if (parameters.RequireCancellation != requireCancellation) 
                    return false;
                bootstrapSecurity = parameters.BootstrapSecurityBindingElement; 
            }
            else
            {
                if (!sbe.IncludeTimestamp) 
                    return false;
 
                // do not check local settings: sbe.LocalServiceSettings and sbe.LocalClientSettings 

                if (!(sbe is TransportSecurityBindingElement)) 
                    return false;

                SupportingTokenParameters parameters = sbe.EndpointSupportingTokenParameters;
                if (parameters.Signed.Count != 0 || parameters.SignedEncrypted.Count != 0 || parameters.Endorsing.Count != 1 || parameters.SignedEndorsing.Count != 0) 
                    return false;
                SecureConversationSecurityTokenParameters scParameters = parameters.Endorsing[0] as SecureConversationSecurityTokenParameters; 
                if (scParameters == null) 
                    return false;
 
                if (scParameters.RequireCancellation != requireCancellation)
                    return false;

                bootstrapSecurity = scParameters.BootstrapSecurityBindingElement; 

            } 
 
            if (bootstrapSecurity != null && bootstrapSecurity.SecurityHeaderLayout != SecurityProtocolFactory.defaultSecurityHeaderLayout)
                return false; 

            return bootstrapSecurity != null;
        }
 
        public override string ToString()
        { 
            StringBuilder sb = new StringBuilder(); 

            sb.AppendLine(String.Format(CultureInfo.InvariantCulture, "{0}:", this.GetType().ToString())); 
            sb.AppendLine(String.Format(CultureInfo.InvariantCulture, "DefaultAlgorithmSuite: {0}", this.defaultAlgorithmSuite.ToString()));
            sb.AppendLine(String.Format(CultureInfo.InvariantCulture, "IncludeTimestamp: {0}", this.includeTimestamp.ToString()));
            sb.AppendLine(String.Format(CultureInfo.InvariantCulture, "KeyEntropyMode: {0}", this.keyEntropyMode.ToString()));
            sb.AppendLine(String.Format(CultureInfo.InvariantCulture, "MessageSecurityVersion: {0}", this.MessageSecurityVersion.ToString())); 
            sb.AppendLine(String.Format(CultureInfo.InvariantCulture, "SecurityHeaderLayout: {0}", this.securityHeaderLayout.ToString()));
            sb.AppendLine("EndpointSupportingTokenParameters:"); 
            sb.AppendLine("  " + this.EndpointSupportingTokenParameters.ToString().Trim().Replace("\n", "\n  ")); 
            sb.AppendLine("OptionalEndpointSupportingTokenParameters:");
            sb.AppendLine("  " + this.OptionalEndpointSupportingTokenParameters.ToString().Trim().Replace("\n", "\n  ")); 
            if (this.operationSupportingTokenParameters.Count == 0)
            {
                sb.AppendLine(String.Format(CultureInfo.InvariantCulture, "OperationSupportingTokenParameters: none"));
            } 
            else
            { 
                foreach (string requestAction in this.OperationSupportingTokenParameters.Keys) 
                {
                    sb.AppendLine(String.Format(CultureInfo.InvariantCulture, "OperationSupportingTokenParameters[\"{0}\"]:", requestAction)); 
                    sb.AppendLine("  " + this.OperationSupportingTokenParameters[requestAction].ToString().Trim().Replace("\n", "\n  "));
                }
            }
            if (this.optionalOperationSupportingTokenParameters.Count == 0) 
            {
                sb.AppendLine(String.Format(CultureInfo.InvariantCulture, "OptionalOperationSupportingTokenParameters: none")); 
            } 
            else
            { 
                foreach (string requestAction in this.OptionalOperationSupportingTokenParameters.Keys)
                {
                    sb.AppendLine(String.Format(CultureInfo.InvariantCulture, "OptionalOperationSupportingTokenParameters[\"{0}\"]:", requestAction));
                    sb.AppendLine("  " + this.OptionalOperationSupportingTokenParameters[requestAction].ToString().Trim().Replace("\n", "\n  ")); 
                }
            } 
 
            return sb.ToString().Trim();
        } 


        internal static ChannelProtectionRequirements ComputeProtectionRequirements(SecurityBindingElement security, BindingParameterCollection parameterCollection, BindingElementCollection bindingElements, bool isForService)
        { 
            if (parameterCollection == null)
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("parameterCollection"); 
            if (bindingElements == null) 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("bindingElements");
            if (security == null) 
            {
                return null;
            }
 
            ChannelProtectionRequirements result = null;
            if ((security is SymmetricSecurityBindingElement) || (security is AsymmetricSecurityBindingElement)) 
            { 
                result = new ChannelProtectionRequirements();
                ChannelProtectionRequirements contractRequirements = parameterCollection.Find(); 

                if (contractRequirements != null)
                    result.Add(contractRequirements);
 
                AddBindingProtectionRequirements(result, bindingElements, !isForService);
            } 
 
            return result;
        } 

        static void AddBindingProtectionRequirements(ChannelProtectionRequirements requirements, BindingElementCollection bindingElements, bool isForChannel)
        {
            // Gather custom requirements from bindingElements 
            CustomBinding binding = new CustomBinding(bindingElements);
            BindingContext context = new BindingContext(binding, new BindingParameterCollection()); 
            // In theory, we can just do 
            //     context.GetInnerProperty()
            // but that relies on each binding element to correctly union-up its own requirements with 
            // those of the rest of the stack.  So instead, we ask each BE individually, and we do the
            // work of combining the results.  This protects us against this scenario: someone authors "FooBE"
            // with a a GetProperty implementation that always returns null (oops), and puts FooBE on the
            // top of the stack, and so FooBE "hides" important protection requirements that inner BEs 
            // require, resulting in an insecure binding.
            foreach (BindingElement bindingElement in bindingElements) 
            { 
                if (bindingElement != null)
                { 
                    // ask each element individually for its requirements
                    context.RemainingBindingElements.Clear();
                    context.RemainingBindingElements.Add(bindingElement);
                    ChannelProtectionRequirements s = context.GetInnerProperty(); 
                    if (s != null)
                    { 
                        //if (isForChannel) 
                        //{
                        //    requirements.Add(s.CreateInverse()); 
                        //}
                        //else
                        //{
                            requirements.Add(s); 
                        //}
                    } 
                } 
            }
        } 

        internal void ApplyAuditBehaviorSettings(BindingContext context, SecurityProtocolFactory factory)
        {
            ServiceSecurityAuditBehavior auditBehavior = context.BindingParameters.Find(); 
            if (auditBehavior != null)
            { 
                factory.AuditLogLocation = auditBehavior.AuditLogLocation; 
                factory.SuppressAuditFailure = auditBehavior.SuppressAuditFailure;
                factory.ServiceAuthorizationAuditLevel = auditBehavior.ServiceAuthorizationAuditLevel; 
                factory.MessageAuthenticationAuditLevel = auditBehavior.MessageAuthenticationAuditLevel;
            }
            else
            { 
                factory.AuditLogLocation = ServiceSecurityAuditBehavior.defaultAuditLogLocation;
                factory.SuppressAuditFailure = ServiceSecurityAuditBehavior.defaultSuppressAuditFailure; 
                factory.ServiceAuthorizationAuditLevel = ServiceSecurityAuditBehavior.defaultServiceAuthorizationAuditLevel; 
                factory.MessageAuthenticationAuditLevel = ServiceSecurityAuditBehavior.defaultMessageAuthenticationAuditLevel;
            } 
        }

        internal override bool IsMatch(BindingElement b)
        { 
            if (b == null)
                return false; 
 
            SecurityBindingElement security = b as SecurityBindingElement;
            if (security == null) 
                return false;
            return SecurityElement.AreBindingsMatching(this, security);
        }
 
        static void AddAssertionIfNotNull(PolicyConversionContext policyContext, XmlElement assertion)
        { 
            if (policyContext != null && assertion != null) 
            {
                policyContext.GetBindingAssertions().Add(assertion); 
            }
        }

        static void AddAssertionIfNotNull(PolicyConversionContext policyContext, Collection assertions) 
        {
            if (policyContext != null && assertions != null) 
            { 
                PolicyAssertionCollection existingAssertions = policyContext.GetBindingAssertions();
                for (int i = 0 ; i < assertions.Count; ++i) 
                    existingAssertions.Add(assertions[i]);
            }
        }
 
        static void AddAssertionIfNotNull(PolicyConversionContext policyContext, OperationDescription operation, XmlElement assertion)
        { 
            if (policyContext != null && assertion != null) 
            {
                policyContext.GetOperationBindingAssertions(operation).Add(assertion); 
            }
        }

        static void AddAssertionIfNotNull(PolicyConversionContext policyContext, OperationDescription operation, Collection assertions) 
        {
            if (policyContext != null && assertions != null) 
            { 
                PolicyAssertionCollection existingAssertions = policyContext.GetOperationBindingAssertions(operation);
                for (int i = 0; i < assertions.Count; ++i) 
                    existingAssertions.Add(assertions[i]);
            }
        }
 
        static void AddAssertionIfNotNull(PolicyConversionContext policyContext, MessageDescription message, XmlElement assertion)
        { 
            if (policyContext != null && assertion != null) 
            {
                policyContext.GetMessageBindingAssertions(message).Add(assertion); 
            }
        }

        static void AddAssertionIfNotNull(PolicyConversionContext policyContext, FaultDescription message, XmlElement assertion) 
        {
            if (policyContext != null && assertion != null) 
            { 
                policyContext.GetFaultBindingAssertions(message).Add(assertion);
            } 
        }

        internal static void ExportPolicy(MetadataExporter exporter, PolicyConversionContext context)
        { 
            if (exporter == null)
            { 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("exporter"); 
            }
 
            if (context == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("context");
            } 

            SecurityTraceRecordHelper.TraceExportChannelBindingEntry(); 
 
            SecurityBindingElement binding = null;
            ITransportTokenAssertionProvider transportTokenAssertionProvider = null; 
            BindingElementCollection bindingElementsBelowSecurity = new BindingElementCollection();
            if ((context != null) && (context.BindingElements != null))
            {
                foreach (BindingElement be in context.BindingElements) 
                {
                    if (be is SecurityBindingElement) 
                    { 
                        binding = (SecurityBindingElement)be;
                    } 
                    else
                    {
                        if (binding != null || be is MessageEncodingBindingElement || be is ITransportTokenAssertionProvider)
                        { 
                            bindingElementsBelowSecurity.Add(be);
                        } 
                        if (be is ITransportTokenAssertionProvider) 
                        {
                            transportTokenAssertionProvider = (ITransportTokenAssertionProvider)be; 
                        }
                    }
                }
            } 

            // this is used when exporting bootstrap policy for secure conversation in SecurityPolicy11.CreateWsspBootstrapPolicyAssertion 
            exporter.State[SecurityPolicyStrings.SecureConversationBootstrapBindingElementsBelowSecurityKey] = bindingElementsBelowSecurity; 

            bool hasCompletedSuccessfuly = false; 
            try
            {
                if (binding is SymmetricSecurityBindingElement)
                { 
                    if (transportTokenAssertionProvider != null)
                    { 
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.ExportOfBindingWithSymmetricAndTransportSecurityNotSupported))); 
                    }
 
                    ExportSymmetricSecurityBindingElement((SymmetricSecurityBindingElement)binding, exporter, context);
                    ExportOperationScopeSupportingTokensPolicy(binding, exporter, context);
                    ExportMessageScopeProtectionPolicy(binding, exporter, context);
                } 
                else if (binding is AsymmetricSecurityBindingElement)
                { 
                    if (transportTokenAssertionProvider != null) 
                    {
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.ExportOfBindingWithAsymmetricAndTransportSecurityNotSupported))); 
                    }

                    ExportAsymmetricSecurityBindingElement((AsymmetricSecurityBindingElement)binding, exporter, context);
                    ExportOperationScopeSupportingTokensPolicy(binding, exporter, context); 
                    ExportMessageScopeProtectionPolicy(binding, exporter, context);
                } 
                else if (binding is TransportSecurityBindingElement) 
                {
                    if (transportTokenAssertionProvider == null) 
                    {
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.ExportOfBindingWithTransportSecurityBindingElementAndNoTransportSecurityNotSupported)));
                    }
 
                    ExportTransportSecurityBindingElement((TransportSecurityBindingElement)binding, transportTokenAssertionProvider, exporter, context);
                    ExportOperationScopeSupportingTokensPolicy(binding, exporter, context); 
                } 
                else if (binding == null && transportTokenAssertionProvider != null)
                { 
                    TransportSecurityBindingElement dummyTransportBindingElement = new TransportSecurityBindingElement();
                    dummyTransportBindingElement.IncludeTimestamp = false;

                    // In order to generate the right sp assertion without SBE. 
                    // scenario: WSxHttpBinding with SecurityMode.Transport.
                    // See CSD 3105 for detail 
                    HttpsTransportBindingElement httpsBinding = transportTokenAssertionProvider as HttpsTransportBindingElement; 
                    if (httpsBinding != null && httpsBinding.MessageSecurityVersion != null)
                    { 
                        dummyTransportBindingElement.MessageSecurityVersion = httpsBinding.MessageSecurityVersion;
                    }

                    ExportTransportSecurityBindingElement(dummyTransportBindingElement, transportTokenAssertionProvider, exporter, context); 
                }
                hasCompletedSuccessfuly = true; 
            } 
            finally
            { 
                try
                {
                    exporter.State.Remove(SecurityPolicyStrings.SecureConversationBootstrapBindingElementsBelowSecurityKey);
                } 
                catch (Exception e)
                { 
                    // Always immediately rethrow fatal exceptions. 
                    if (hasCompletedSuccessfuly || DiagnosticUtility.IsFatal(e)) throw;
                } 
            }
        }

        // 
        // We will emit the wssp trust 10 assertion for all the case except for the basic http binding
        // created through the BasicHttpBinding class.  The reason for this exception is to allow better 
        // interop with third party when the third party doesn't understand the trust asserion 
        //
        static bool RequiresWsspTrust(SecurityBindingElement sbe) 
        {
            if (sbe == null)
                return false;
 
            return !(sbe.doNotEmitTrust);
        } 
 
        static void ExportAsymmetricSecurityBindingElement(AsymmetricSecurityBindingElement binding, MetadataExporter exporter, PolicyConversionContext policyContext)
        { 
            WSSecurityPolicy sp = WSSecurityPolicy.GetSecurityPolicyDriver(binding.MessageSecurityVersion);

            AddAssertionIfNotNull(policyContext, sp.CreateWsspAsymmetricBindingAssertion(exporter, policyContext, binding));
 
            AddAssertionIfNotNull(policyContext, sp.CreateWsspSupportingTokensAssertion(
                exporter, 
                binding.EndpointSupportingTokenParameters.Signed, 
                binding.EndpointSupportingTokenParameters.SignedEncrypted,
                binding.EndpointSupportingTokenParameters.Endorsing, 
                binding.EndpointSupportingTokenParameters.SignedEndorsing,
                binding.OptionalEndpointSupportingTokenParameters.Signed,
                binding.OptionalEndpointSupportingTokenParameters.SignedEncrypted,
                binding.OptionalEndpointSupportingTokenParameters.Endorsing, 
                binding.OptionalEndpointSupportingTokenParameters.SignedEndorsing));
 
            AddAssertionIfNotNull(policyContext, sp.CreateWsspWssAssertion(exporter, binding)); 

            if (RequiresWsspTrust(binding)) 
            {
                AddAssertionIfNotNull(policyContext, sp.CreateWsspTrustAssertion(exporter, binding.KeyEntropyMode));
            }
        } 

        static void ExportTransportSecurityBindingElement(TransportSecurityBindingElement binding, ITransportTokenAssertionProvider transportTokenAssertionProvider, MetadataExporter exporter, PolicyConversionContext policyContext) 
        { 
            WSSecurityPolicy sp = WSSecurityPolicy.GetSecurityPolicyDriver(binding.MessageSecurityVersion);
 
            XmlElement transportTokenAssertion = transportTokenAssertionProvider.GetTransportTokenAssertion();

            if (transportTokenAssertion == null)
            { 
                if (transportTokenAssertionProvider is HttpsTransportBindingElement)
                { 
                    transportTokenAssertion = sp.CreateWsspHttpsTokenAssertion(exporter, (HttpsTransportBindingElement)transportTokenAssertionProvider); 
                }
 
                if (transportTokenAssertion == null)
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.NoTransportTokenAssertionProvided, transportTokenAssertionProvider.GetType().ToString())));
            }
 
            AddressingVersion addressingVersion = AddressingVersion.WSAddressing10;
            MessageEncodingBindingElement messageEncoderBindingElement = policyContext.BindingElements.Find(); 
            if (messageEncoderBindingElement != null) 
            {
                addressingVersion = messageEncoderBindingElement.MessageVersion.Addressing; 
            }

            AddAssertionIfNotNull(policyContext, sp.CreateWsspTransportBindingAssertion(exporter, binding, transportTokenAssertion));
 
            Collection supportingTokenAssertions = sp.CreateWsspSupportingTokensAssertion(
                exporter, 
                binding.EndpointSupportingTokenParameters.Signed, 
                binding.EndpointSupportingTokenParameters.SignedEncrypted,
                binding.EndpointSupportingTokenParameters.Endorsing, 
                binding.EndpointSupportingTokenParameters.SignedEndorsing,
                binding.OptionalEndpointSupportingTokenParameters.Signed,
                binding.OptionalEndpointSupportingTokenParameters.SignedEncrypted,
                binding.OptionalEndpointSupportingTokenParameters.Endorsing, 
                binding.OptionalEndpointSupportingTokenParameters.SignedEndorsing,
                addressingVersion); 
 
            AddAssertionIfNotNull(policyContext, supportingTokenAssertions);
 
            if (supportingTokenAssertions.Count > 0
                || HasEndorsingSupportingTokensAtOperationScope(binding))
            {
                AddAssertionIfNotNull(policyContext, sp.CreateWsspWssAssertion(exporter, binding)); 
                if (RequiresWsspTrust(binding))
                { 
                    AddAssertionIfNotNull(policyContext, sp.CreateWsspTrustAssertion(exporter, binding.KeyEntropyMode)); 
                }
            } 
        }

        static bool HasEndorsingSupportingTokensAtOperationScope(SecurityBindingElement binding)
        { 
            foreach (SupportingTokenParameters r in binding.OperationSupportingTokenParameters.Values)
            { 
                if (r.Endorsing.Count > 0 || r.SignedEndorsing.Count > 0) 
                {
                    return true; 
                }
            }

            return false; 
        }
 
        static void ExportSymmetricSecurityBindingElement(SymmetricSecurityBindingElement binding, MetadataExporter exporter, PolicyConversionContext policyContext) 
        {
            WSSecurityPolicy sp = WSSecurityPolicy.GetSecurityPolicyDriver(binding.MessageSecurityVersion); 

            AddAssertionIfNotNull(policyContext, sp.CreateWsspSymmetricBindingAssertion(exporter, policyContext, binding));

            AddAssertionIfNotNull(policyContext, sp.CreateWsspSupportingTokensAssertion( 
                exporter,
                binding.EndpointSupportingTokenParameters.Signed, 
                binding.EndpointSupportingTokenParameters.SignedEncrypted, 
                binding.EndpointSupportingTokenParameters.Endorsing,
                binding.EndpointSupportingTokenParameters.SignedEndorsing, 
                binding.OptionalEndpointSupportingTokenParameters.Signed,
                binding.OptionalEndpointSupportingTokenParameters.SignedEncrypted,
                binding.OptionalEndpointSupportingTokenParameters.Endorsing,
                binding.OptionalEndpointSupportingTokenParameters.SignedEndorsing)); 

            AddAssertionIfNotNull(policyContext, sp.CreateWsspWssAssertion(exporter, binding)); 
 
            if (RequiresWsspTrust(binding))
            { 
                AddAssertionIfNotNull(policyContext, sp.CreateWsspTrustAssertion(exporter, binding.KeyEntropyMode));
            }
        }
 
        static void ExportMessageScopeProtectionPolicy(SecurityBindingElement security, MetadataExporter exporter, PolicyConversionContext policyContext)
        { 
            BindingParameterCollection bindingParameters = new BindingParameterCollection(); 
            bindingParameters.Add(ChannelProtectionRequirements.CreateFromContract(policyContext.Contract, policyContext.BindingElements.Find().GetIndividualProperty(), false));
            ChannelProtectionRequirements protectionRequirements = SecurityBindingElement.ComputeProtectionRequirements(security, bindingParameters, policyContext.BindingElements, true); 
            protectionRequirements.MakeReadOnly();

            WSSecurityPolicy sp = WSSecurityPolicy.GetSecurityPolicyDriver(security.MessageSecurityVersion);
 
            foreach (OperationDescription operation in policyContext.Contract.Operations)
            { 
                // export policy for application messages 
                foreach (MessageDescription message in operation.Messages)
                { 
                    MessagePartSpecification parts;
                    ScopedMessagePartSpecification scopedParts;

                    // integrity 
                    if (message.Direction == MessageDirection.Input)
                    { 
                        scopedParts = protectionRequirements.IncomingSignatureParts; 
                    }
                    else 
                    {
                        scopedParts = protectionRequirements.OutgoingSignatureParts;
                    }
 
                    if (scopedParts.TryGetParts(message.Action, out parts))
                    { 
                        AddAssertionIfNotNull(policyContext, message, sp.CreateWsspSignedPartsAssertion(parts)); 
                    }
 
                    // confidentiality
                    if (message.Direction == MessageDirection.Input)
                    {
                        scopedParts = protectionRequirements.IncomingEncryptionParts; 
                    }
                    else 
                    { 
                        scopedParts = protectionRequirements.OutgoingEncryptionParts;
                    } 

                    if (scopedParts.TryGetParts(message.Action, out parts))
                    {
                        AddAssertionIfNotNull(policyContext, message, sp.CreateWsspEncryptedPartsAssertion(parts)); 
                    }
                } 
 
                // export policy for faults
                foreach (FaultDescription fault in operation.Faults) 
                {
                    MessagePartSpecification parts;

                    // integrity 
                    if (protectionRequirements.OutgoingSignatureParts.TryGetParts(fault.Action, out parts))
                    { 
                        AddAssertionIfNotNull(policyContext, fault, sp.CreateWsspSignedPartsAssertion(parts)); 
                    }
 
                    // confidentiality
                    if (protectionRequirements.OutgoingEncryptionParts.TryGetParts(fault.Action, out parts))
                    {
                        AddAssertionIfNotNull(policyContext, fault, sp.CreateWsspEncryptedPartsAssertion(parts)); 
                    }
                } 
            } 
        }
 
        static void ExportOperationScopeSupportingTokensPolicy(SecurityBindingElement binding, MetadataExporter exporter, PolicyConversionContext policyContext)
        {
            WSSecurityPolicy sp = WSSecurityPolicy.GetSecurityPolicyDriver(binding.MessageSecurityVersion);
 
            if (binding.OperationSupportingTokenParameters.Count == 0 && binding.OptionalOperationSupportingTokenParameters.Count == 0)
            { 
                return; 
            }
 
            foreach (OperationDescription operation in policyContext.Contract.Operations)
            {
                foreach (MessageDescription message in operation.Messages)
                { 

                    if (message.Direction == MessageDirection.Input) 
                    { 
                        SupportingTokenParameters requirements = null;
                        SupportingTokenParameters optionalRequirements = null; 

                        if (binding.OperationSupportingTokenParameters.ContainsKey(message.Action))
                        {
                            requirements = binding.OperationSupportingTokenParameters[message.Action]; 
                        }
                        if (binding.OptionalOperationSupportingTokenParameters.ContainsKey(message.Action)) 
                        { 
                            optionalRequirements = binding.OptionalOperationSupportingTokenParameters[message.Action];
                        } 

                        if (requirements == null && optionalRequirements == null)
                        {
                            continue; 
                        }
 
                        AddAssertionIfNotNull(policyContext, operation, sp.CreateWsspSupportingTokensAssertion( 
                            exporter,
                            requirements == null ? null : requirements.Signed, 
                            requirements == null ? null : requirements.SignedEncrypted,
                            requirements == null ? null : requirements.Endorsing,
                            requirements == null ? null : requirements.SignedEndorsing,
                            optionalRequirements == null ? null : optionalRequirements.Signed, 
                            optionalRequirements == null ? null : optionalRequirements.SignedEncrypted,
                            optionalRequirements == null ? null : optionalRequirements.Endorsing, 
                            optionalRequirements == null ? null : optionalRequirements.SignedEndorsing)); 
                    }
                } 
            }
        }
    }
} 

// 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