File: System\ServiceModel\Description\SoapHelper.cs
Project: ndp\cdf\src\WCF\ServiceModel\System.ServiceModel.csproj (System.ServiceModel)
//----------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation.  All rights reserved.
//----------------------------------------------------------------------------
namespace System.ServiceModel.Description
{
    using System.Collections.Generic;
    using System.Runtime;
    using System.ServiceModel.Dispatcher;
    using System.Xml;
    using WsdlNS = System.Web.Services.Description;
 
    static class SoapHelper
    {
        static object SoapVersionStateKey = new object();
        static XmlDocument xmlDocument;
 
        static XmlDocument Document
        {
            get
            {
                if (xmlDocument == null)
                    xmlDocument = new XmlDocument();
                return xmlDocument;
            }
        }
 
        static XmlAttribute CreateLocalAttribute(string name, string value)
        {
            XmlAttribute attribute = Document.CreateAttribute(name);
            attribute.Value = value;
            return attribute;
        }
        // -----------------------------------------------------------------------------------------------------------------------
        // Developers Note: We go through a little song an dance here to Get or Create an exsisting SoapBinding from the WSDL
        // Extensions for a number of reasons:
        //      1. Multiple Extensions may contribute to the settings in the soap binding and so to make this work without
        //          relying on ordering, we need the GetOrCreate method.
        //      2. There are diffrent classes for diffrent SOAP versions and the extensions that determines the version is
        //          also un-ordered so when we finally figure out the version we may need to recreate the BindingExtension and
        //          clone it.
 
        internal static WsdlNS.SoapAddressBinding GetOrCreateSoapAddressBinding(WsdlNS.Binding wsdlBinding, WsdlNS.Port wsdlPort, WsdlExporter exporter)
        {
            if (GetSoapVersionState(wsdlBinding, exporter) == EnvelopeVersion.None)
                return null;
 
            WsdlNS.SoapAddressBinding existingSoapAddressBinding = GetSoapAddressBinding(wsdlPort);
            EnvelopeVersion version = GetSoapVersion(wsdlBinding);
 
            if (existingSoapAddressBinding != null)
                return existingSoapAddressBinding;
 
            WsdlNS.SoapAddressBinding soapAddressBinding = CreateSoapAddressBinding(version, wsdlPort);
            return soapAddressBinding;
        }
 
        internal static WsdlNS.SoapBinding GetOrCreateSoapBinding(WsdlEndpointConversionContext endpointContext, WsdlExporter exporter)
        {
            if (GetSoapVersionState(endpointContext.WsdlBinding, exporter) == EnvelopeVersion.None)
                return null;
 
            WsdlNS.SoapBinding existingSoapBinding = GetSoapBinding(endpointContext);
            if (existingSoapBinding != null)
            {
                return existingSoapBinding;
            }
 
            EnvelopeVersion version = GetSoapVersion(endpointContext.WsdlBinding);
            WsdlNS.SoapBinding soapBinding = CreateSoapBinding(version, endpointContext.WsdlBinding);
            return soapBinding;
        }
 
        internal static WsdlNS.SoapOperationBinding GetOrCreateSoapOperationBinding(WsdlEndpointConversionContext endpointContext, OperationDescription operation, WsdlExporter exporter)
        {
            if (GetSoapVersionState(endpointContext.WsdlBinding, exporter) == EnvelopeVersion.None)
                return null;
 
            WsdlNS.SoapOperationBinding existingSoapOperationBinding = GetSoapOperationBinding(endpointContext, operation);
            WsdlNS.OperationBinding wsdlOperationBinding = endpointContext.GetOperationBinding(operation);
            EnvelopeVersion version = GetSoapVersion(endpointContext.WsdlBinding);
 
            if (existingSoapOperationBinding != null)
                return existingSoapOperationBinding;
 
            WsdlNS.SoapOperationBinding soapOperationBinding = CreateSoapOperationBinding(version, wsdlOperationBinding);
            return soapOperationBinding;
        }
 
        internal static WsdlNS.SoapBodyBinding GetOrCreateSoapBodyBinding(WsdlEndpointConversionContext endpointContext, WsdlNS.MessageBinding wsdlMessageBinding, WsdlExporter exporter)
        {
            if (GetSoapVersionState(endpointContext.WsdlBinding, exporter) == EnvelopeVersion.None)
                return null;
 
            WsdlNS.SoapBodyBinding existingSoapBodyBinding = GetSoapBodyBinding(endpointContext, wsdlMessageBinding);
            EnvelopeVersion version = GetSoapVersion(endpointContext.WsdlBinding);
 
            if (existingSoapBodyBinding != null)
                return existingSoapBodyBinding;
 
            WsdlNS.SoapBodyBinding soapBodyBinding = CreateSoapBodyBinding(version, wsdlMessageBinding);
            return soapBodyBinding;
        }
 
        internal static WsdlNS.SoapHeaderBinding CreateSoapHeaderBinding(WsdlEndpointConversionContext endpointContext, WsdlNS.MessageBinding wsdlMessageBinding)
        {
            EnvelopeVersion version = GetSoapVersion(endpointContext.WsdlBinding);
 
            WsdlNS.SoapHeaderBinding soapHeaderBinding = CreateSoapHeaderBinding(version, wsdlMessageBinding);
            return soapHeaderBinding;
        }
 
        internal static void CreateSoapFaultBinding(string name, WsdlEndpointConversionContext endpointContext, WsdlNS.FaultBinding wsdlFaultBinding, bool isEncoded)
        {
            EnvelopeVersion version = GetSoapVersion(endpointContext.WsdlBinding);
            XmlElement fault = CreateSoapFaultBinding(version);
            fault.Attributes.Append(CreateLocalAttribute("name", name));
            fault.Attributes.Append(CreateLocalAttribute("use", isEncoded ? "encoded" : "literal"));
            wsdlFaultBinding.Extensions.Add(fault);
        }
 
        internal static void SetSoapVersion(WsdlEndpointConversionContext endpointContext, WsdlExporter exporter, EnvelopeVersion version)
        {
            SetSoapVersionState(endpointContext.WsdlBinding, exporter, version);
 
            //Convert all SOAP extensions to the right version.
            if (endpointContext.WsdlPort != null)
                SoapConverter.ConvertExtensions(endpointContext.WsdlPort.Extensions, version, SoapConverter.ConvertSoapAddressBinding);
 
            SoapConverter.ConvertExtensions(endpointContext.WsdlBinding.Extensions, version, SoapConverter.ConvertSoapBinding);
 
            foreach (WsdlNS.OperationBinding operationBinding in endpointContext.WsdlBinding.Operations)
            {
                SoapConverter.ConvertExtensions(operationBinding.Extensions, version, SoapConverter.ConvertSoapOperationBinding);
 
                //Messages
                {
                    if (operationBinding.Input != null)
                        SoapConverter.ConvertExtensions(operationBinding.Input.Extensions, version, SoapConverter.ConvertSoapMessageBinding);
                    if (operationBinding.Output != null)
                        SoapConverter.ConvertExtensions(operationBinding.Output.Extensions, version, SoapConverter.ConvertSoapMessageBinding);
 
                    foreach (WsdlNS.MessageBinding faultBinding in operationBinding.Faults)
                        SoapConverter.ConvertExtensions(faultBinding.Extensions, version, SoapConverter.ConvertSoapMessageBinding);
                }
            }
 
        }
 
        internal static EnvelopeVersion GetSoapVersion(WsdlNS.Binding wsdlBinding)
        {
            foreach (object o in wsdlBinding.Extensions)
            {
                if (o is WsdlNS.SoapBinding)
                    return o is WsdlNS.Soap12Binding ? EnvelopeVersion.Soap12 : EnvelopeVersion.Soap11;
            }
            return EnvelopeVersion.Soap12;
        }
 
        private static void SetSoapVersionState(WsdlNS.Binding wsdlBinding, WsdlExporter exporter, EnvelopeVersion version)
        {
            object versions = null;
 
            if (!exporter.State.TryGetValue(SoapVersionStateKey, out versions))
            {
                versions = new Dictionary<WsdlNS.Binding, EnvelopeVersion>();
                exporter.State[SoapVersionStateKey] = versions;
            }
 
            ((Dictionary<WsdlNS.Binding, EnvelopeVersion>)versions)[wsdlBinding] = version;
        }
 
        private static EnvelopeVersion GetSoapVersionState(WsdlNS.Binding wsdlBinding, WsdlExporter exporter)
        {
            object versions = null;
 
            if (exporter.State.TryGetValue(SoapVersionStateKey, out versions))
            {
                if (versions != null && ((Dictionary<WsdlNS.Binding, EnvelopeVersion>)versions).ContainsKey(wsdlBinding))
                {
                    return ((Dictionary<WsdlNS.Binding, EnvelopeVersion>)versions)[wsdlBinding];
                }
            }
            return null;
        }
 
        static class SoapConverter
        {
 
            // Microsoft, this could be simplified if we used generics.
            internal static void ConvertExtensions(WsdlNS.ServiceDescriptionFormatExtensionCollection extensions, EnvelopeVersion version, ConvertExtension conversionMethod)
            {
                bool foundOne = false;
                for (int i = extensions.Count - 1; i >= 0; i--)
                {
                    object o = extensions[i];
                    if (conversionMethod(ref o, version))
                    {
                        if (o == null)
                            extensions.Remove(extensions[i]);
                        else
                            extensions[i] = o;
                        foundOne = true;
                    }
                }
 
                if (!foundOne)
                {
                    object o = null;
                    conversionMethod(ref o, version);
                    if (o != null)
                        extensions.Add(o);
                }
 
            }
 
            // This is the delegate implemented by the 4 methods below. It is expected to:
            // If given a null reference for src, a new instance of the extension can be set.
            internal delegate bool ConvertExtension(ref object src, EnvelopeVersion version);
 
            internal static bool ConvertSoapBinding(ref object src, EnvelopeVersion version)
            {
                WsdlNS.SoapBinding binding = src as WsdlNS.SoapBinding;
 
                if (src != null)
                {
                    if (binding == null)
                        return false; // not a soap object
                    else if (GetBindingVersion<WsdlNS.Soap12Binding>(src) == version)
                        return true; // matched but same version; no change
                }
 
                if (version == EnvelopeVersion.None)
                {
                    src = null;
                    return true;
                }
 
                WsdlNS.SoapBinding dest = version == EnvelopeVersion.Soap12 ? new WsdlNS.Soap12Binding() : new WsdlNS.SoapBinding();
                if (binding != null)
                {
                    dest.Required = binding.Required;
                    dest.Style = binding.Style;
                    dest.Transport = binding.Transport;
                }
 
                src = dest;
                return true;
            }
 
            internal static bool ConvertSoapAddressBinding(ref object src, EnvelopeVersion version)
            {
                WsdlNS.SoapAddressBinding binding = src as WsdlNS.SoapAddressBinding;
 
                if (src != null)
                {
                    if (binding == null)
                        return false; // no match
                    else if (GetBindingVersion<WsdlNS.Soap12AddressBinding>(src) == version)
                        return true; // matched but same version; no change
                }
 
                if (version == EnvelopeVersion.None)
                {
                    src = null;
                    return true;
                }
 
                WsdlNS.SoapAddressBinding dest = version == EnvelopeVersion.Soap12 ? new WsdlNS.Soap12AddressBinding() : new WsdlNS.SoapAddressBinding();
                if (binding != null)
                {
                    dest.Required = binding.Required;
                    dest.Location = binding.Location;
                }
 
                src = dest;
                return true;
            }
 
 
            // returns true if src is an expected type; updates src in place; should handle null
            internal static bool ConvertSoapOperationBinding(ref object src, EnvelopeVersion version)
            {
                WsdlNS.SoapOperationBinding binding = src as WsdlNS.SoapOperationBinding;
 
                if (src != null)
                {
                    if (binding == null)
                        return false; // no match
                    else if (GetBindingVersion<WsdlNS.Soap12OperationBinding>(src) == version)
                        return true; // matched but same version
                }
 
                if (version == EnvelopeVersion.None)
                {
                    src = null;
                    return true;
                }
 
                WsdlNS.SoapOperationBinding dest = version == EnvelopeVersion.Soap12 ? new WsdlNS.Soap12OperationBinding() : new WsdlNS.SoapOperationBinding();
                if (src != null)
                {
                    dest.Required = binding.Required;
                    dest.Style = binding.Style;
                    dest.SoapAction = binding.SoapAction;
                }
 
                src = dest;
                return true;
            }
 
            internal static bool ConvertSoapMessageBinding(ref object src, EnvelopeVersion version)
            {
                WsdlNS.SoapBodyBinding body = src as WsdlNS.SoapBodyBinding;
                if (body != null)
                {
                    src = ConvertSoapBodyBinding(body, version);
                    return true;
                }
 
                WsdlNS.SoapHeaderBinding header = src as WsdlNS.SoapHeaderBinding;
                if (header != null)
                {
                    src = ConvertSoapHeaderBinding(header, version);
                    return true;
                }
 
                WsdlNS.SoapFaultBinding fault = src as WsdlNS.SoapFaultBinding;
                if (fault != null)
                {
                    src = ConvertSoapFaultBinding(fault, version);
                    return true;
                }
 
                XmlElement element = src as XmlElement;
                if (element != null)
                {
                    if (IsSoapFaultBinding(element))
                    {
                        src = ConvertSoapFaultBinding(element, version);
                        return true;
                    }
                }
 
                return src == null; // "match" only if nothing passed in
            }
 
            static WsdlNS.SoapBodyBinding ConvertSoapBodyBinding(WsdlNS.SoapBodyBinding src, EnvelopeVersion version)
            {
                if (version == EnvelopeVersion.None)
                    return null;
 
                EnvelopeVersion srcVersion = GetBindingVersion<WsdlNS.Soap12BodyBinding>(src);
                if (srcVersion == version)
                    return src;
 
                WsdlNS.SoapBodyBinding dest = version == EnvelopeVersion.Soap12 ? new WsdlNS.Soap12BodyBinding() : new WsdlNS.SoapBodyBinding();
                if (src != null)
                {
                    if (XmlSerializerOperationFormatter.GetEncoding(srcVersion) == src.Encoding)
                        dest.Encoding = XmlSerializerOperationFormatter.GetEncoding(version);
                    dest.Encoding = XmlSerializerOperationFormatter.GetEncoding(version);
                    dest.Namespace = src.Namespace;
                    dest.Parts = src.Parts;
                    dest.PartsString = src.PartsString;
                    dest.Use = src.Use;
                    dest.Required = src.Required;
                }
                return dest;
            }
 
            static XmlElement ConvertSoapFaultBinding(XmlElement src, EnvelopeVersion version)
            {
                if (src == null)
                    return null;
 
                if (version == EnvelopeVersion.Soap12)
                {
                    if (src.NamespaceURI == WsdlNS.Soap12Binding.Namespace)
                        return src;
                }
                else if (version == EnvelopeVersion.Soap11)
                {
                    if (src.NamespaceURI == WsdlNS.SoapBinding.Namespace)
                        return src;
                }
                else
                {
                    return null;
                }
 
                XmlElement dest = CreateSoapFaultBinding(version);
                if (src.HasAttributes)
                {
                    foreach (XmlAttribute attribute in src.Attributes)
                    {
                        dest.SetAttribute(attribute.Name, attribute.Value);
                    }
                }
                return dest;
            }
 
            static WsdlNS.SoapFaultBinding ConvertSoapFaultBinding(WsdlNS.SoapFaultBinding src, EnvelopeVersion version)
            {
                if (version == EnvelopeVersion.None)
                    return null;
 
                if (GetBindingVersion<WsdlNS.Soap12FaultBinding>(src) == version)
                    return src;
 
                WsdlNS.SoapFaultBinding dest = version == EnvelopeVersion.Soap12 ? new WsdlNS.Soap12FaultBinding() : new WsdlNS.SoapFaultBinding();
                if (src != null)
                {
                    dest.Encoding = src.Encoding;
                    dest.Name = src.Name;
                    dest.Namespace = src.Namespace;
                    dest.Use = src.Use;
                    dest.Required = src.Required;
                }
                return dest;
            }
 
            static WsdlNS.SoapHeaderBinding ConvertSoapHeaderBinding(WsdlNS.SoapHeaderBinding src, EnvelopeVersion version)
            {
                if (version == EnvelopeVersion.None)
                    return null;
 
                if (GetBindingVersion<WsdlNS.Soap12HeaderBinding>(src) == version)
                    return src;
 
                WsdlNS.SoapHeaderBinding dest = version == EnvelopeVersion.Soap12 ? new WsdlNS.Soap12HeaderBinding() : new WsdlNS.SoapHeaderBinding();
                if (src != null)
                {
                    dest.Fault = src.Fault;
                    dest.MapToProperty = src.MapToProperty;
                    dest.Message = src.Message;
                    dest.Part = src.Part;
                    dest.Encoding = src.Encoding;
                    dest.Namespace = src.Namespace;
                    dest.Use = src.Use;
                    dest.Required = src.Required;
                }
                return dest;
            }
 
            internal static EnvelopeVersion GetBindingVersion<T12>(object src)
            {
                return src is T12 ? EnvelopeVersion.Soap12 : EnvelopeVersion.Soap11;
            }
 
        }
 
        static WsdlNS.SoapAddressBinding CreateSoapAddressBinding(EnvelopeVersion version, WsdlNS.Port wsdlPort)
        {
            WsdlNS.SoapAddressBinding soapAddressBinding = null;
 
            if (version == EnvelopeVersion.Soap12)
            {
                soapAddressBinding = new WsdlNS.Soap12AddressBinding();
            }
            else if (version == EnvelopeVersion.Soap11)
            {
                soapAddressBinding = new WsdlNS.SoapAddressBinding();
            }
            Fx.Assert(soapAddressBinding != null, "EnvelopeVersion is not recognized. Please update the SoapHelper class");
 
            wsdlPort.Extensions.Add(soapAddressBinding);
            return soapAddressBinding;
        }
 
        // 
        static WsdlNS.SoapBinding CreateSoapBinding(EnvelopeVersion version, WsdlNS.Binding wsdlBinding)
        {
            WsdlNS.SoapBinding soapBinding = null;
 
            if (version == EnvelopeVersion.Soap12)
            {
                soapBinding = new WsdlNS.Soap12Binding();
            }
            else if (version == EnvelopeVersion.Soap11)
            {
                soapBinding = new WsdlNS.SoapBinding();
            }
            Fx.Assert(soapBinding != null, "EnvelopeVersion is not recognized. Please update the SoapHelper class");
 
            wsdlBinding.Extensions.Add(soapBinding);
            return soapBinding;
        }
 
        static WsdlNS.SoapOperationBinding CreateSoapOperationBinding(EnvelopeVersion version, WsdlNS.OperationBinding wsdlOperationBinding)
        {
            WsdlNS.SoapOperationBinding soapOperationBinding = null;
 
            if (version == EnvelopeVersion.Soap12)
            {
                soapOperationBinding = new WsdlNS.Soap12OperationBinding();
            }
            else if (version == EnvelopeVersion.Soap11)
            {
                soapOperationBinding = new WsdlNS.SoapOperationBinding();
            }
            Fx.Assert(soapOperationBinding != null, "EnvelopeVersion is not recognized. Please update the SoapHelper class");
 
            wsdlOperationBinding.Extensions.Add(soapOperationBinding);
            return soapOperationBinding;
        }
 
        static WsdlNS.SoapBodyBinding CreateSoapBodyBinding(EnvelopeVersion version, WsdlNS.MessageBinding wsdlMessageBinding)
        {
            WsdlNS.SoapBodyBinding soapBodyBinding = null;
 
            if (version == EnvelopeVersion.Soap12)
            {
                soapBodyBinding = new WsdlNS.Soap12BodyBinding();
            }
            else if (version == EnvelopeVersion.Soap11)
            {
                soapBodyBinding = new WsdlNS.SoapBodyBinding();
            }
            Fx.Assert(soapBodyBinding != null, "EnvelopeVersion is not recognized. Please update the SoapHelper class");
 
            wsdlMessageBinding.Extensions.Add(soapBodyBinding);
            return soapBodyBinding;
        }
 
        static WsdlNS.SoapHeaderBinding CreateSoapHeaderBinding(EnvelopeVersion version, WsdlNS.MessageBinding wsdlMessageBinding)
        {
            WsdlNS.SoapHeaderBinding soapHeaderBinding = null;
 
            if (version == EnvelopeVersion.Soap12)
            {
                soapHeaderBinding = new WsdlNS.Soap12HeaderBinding();
            }
            else if (version == EnvelopeVersion.Soap11)
            {
                soapHeaderBinding = new WsdlNS.SoapHeaderBinding();
            }
            Fx.Assert(soapHeaderBinding != null, "EnvelopeVersion is not recognized. Please update the SoapHelper class");
 
            wsdlMessageBinding.Extensions.Add(soapHeaderBinding);
            return soapHeaderBinding;
        }
 
        static XmlElement CreateSoapFaultBinding(EnvelopeVersion version)
        {
            string prefix = null;
            string ns = null;
            if (version == EnvelopeVersion.Soap12)
            {
                ns = WsdlNS.Soap12Binding.Namespace;
                prefix = "soap12";
            }
            else if (version == EnvelopeVersion.Soap11)
            {
                ns = WsdlNS.SoapBinding.Namespace;
                prefix = "soap";
            }
            Fx.Assert(ns != null, "EnvelopeVersion is not recognized. Please update the SoapHelper class");
            return Document.CreateElement(prefix, "fault", ns);
        }
 
 
        internal static WsdlNS.SoapAddressBinding GetSoapAddressBinding(WsdlNS.Port wsdlPort)
        {
            foreach (object o in wsdlPort.Extensions)
            {
                if (o is WsdlNS.SoapAddressBinding)
                    return (WsdlNS.SoapAddressBinding)o;
            }
            return null;
        }
        static WsdlNS.SoapBinding GetSoapBinding(WsdlEndpointConversionContext endpointContext)
        {
            foreach (object o in endpointContext.WsdlBinding.Extensions)
            {
                if (o is WsdlNS.SoapBinding)
                    return (WsdlNS.SoapBinding)o;
            }
            return null;
        }
 
        static WsdlNS.SoapOperationBinding GetSoapOperationBinding(WsdlEndpointConversionContext endpointContext, OperationDescription operation)
        {
            WsdlNS.OperationBinding wsdlOperationBinding = endpointContext.GetOperationBinding(operation);
 
            foreach (object o in wsdlOperationBinding.Extensions)
            {
                if (o is WsdlNS.SoapOperationBinding)
                    return (WsdlNS.SoapOperationBinding)o;
            }
            return null;
        }
 
        static WsdlNS.SoapBodyBinding GetSoapBodyBinding(WsdlEndpointConversionContext endpointContext, WsdlNS.MessageBinding wsdlMessageBinding)
        {
            foreach (object o in wsdlMessageBinding.Extensions)
            {
                if (o is WsdlNS.SoapBodyBinding)
                    return (WsdlNS.SoapBodyBinding)o;
            }
            return null;
        }
 
        internal static string ReadSoapAction(WsdlNS.OperationBinding wsdlOperationBinding)
        {
            WsdlNS.SoapOperationBinding soapOperationBinding = (WsdlNS.SoapOperationBinding)wsdlOperationBinding.Extensions.Find(typeof(WsdlNS.SoapOperationBinding));
            return soapOperationBinding != null ? soapOperationBinding.SoapAction : null;
        }
 
        internal static WsdlNS.SoapBindingStyle GetStyle(WsdlNS.Binding binding)
        {
            WsdlNS.SoapBindingStyle style = WsdlNS.SoapBindingStyle.Default;
            if (binding != null)
            {
                WsdlNS.SoapBinding soapBinding = binding.Extensions.Find(typeof(WsdlNS.SoapBinding)) as WsdlNS.SoapBinding;
                if (soapBinding != null)
                    style = soapBinding.Style;
            }
            return style;
        }
 
        internal static WsdlNS.SoapBindingStyle GetStyle(WsdlNS.OperationBinding operationBinding, WsdlNS.SoapBindingStyle defaultBindingStyle)
        {
            WsdlNS.SoapBindingStyle style = defaultBindingStyle;
            if (operationBinding != null)
            {
                WsdlNS.SoapOperationBinding soapOperationBinding = operationBinding.Extensions.Find(typeof(WsdlNS.SoapOperationBinding)) as WsdlNS.SoapOperationBinding;
                if (soapOperationBinding != null)
                {
                    if (soapOperationBinding.Style != WsdlNS.SoapBindingStyle.Default)
                        style = soapOperationBinding.Style;
                }
            }
            return style;
        }
 
        internal static bool IsSoapFaultBinding(XmlElement element)
        {
            return (element != null && element.LocalName == "fault" && (element.NamespaceURI == WsdlNS.Soap12Binding.Namespace || element.NamespaceURI == WsdlNS.SoapBinding.Namespace));
        }
 
        internal static bool IsEncoded(XmlElement element)
        {
            Fx.Assert(element != null, "");
            XmlAttribute attribute = element.GetAttributeNode("use");
            if (attribute == null)
                return false;
            return attribute.Value == "encoded";
        }
    }
}