MessageContractImporter.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 / Description / MessageContractImporter.cs / 5 / MessageContractImporter.cs

                            //------------------------------------------------------------------------------ 
// Copyright (c) Microsoft Corporation.  All rights reserved.
//-----------------------------------------------------------------------------
namespace System.ServiceModel.Description
{ 
    using System;
    using System.Diagnostics; 
    using System.ServiceModel.Channels; 
    using System.ServiceModel.Dispatcher;
    using System.CodeDom.Compiler; 
    using System.CodeDom;
    using System.Collections;
    using System.Collections.Generic;
    using System.Collections.ObjectModel; 
    using System.Globalization;
    using System.IO; 
    using System.Text; 
    using System.ServiceModel;
    using System.Runtime.Serialization; 
    using System.Xml;
    using System.Xml.Schema;
    using System.Xml.Serialization;
    using WsdlNS = System.Web.Services.Description; 
    using System.ServiceModel.Diagnostics;
 
    class MessageContractImporter 
    {
        static readonly XmlQualifiedName AnyType = new XmlQualifiedName("anyType", XmlSchema.Namespace); 

        readonly XmlSchemaSet allSchemas;
        readonly WsdlContractConversionContext contractContext;
        readonly WsdlImporter importer; 
        SchemaImporter schemaImporter;
        readonly FaultImportOptions faultImportOptions; 
 
        static object schemaImporterLock = new object();
 
        Dictionary> bodyPartsTable;

        Dictionary> BodyPartsTable
        { 
            get
            { 
                if (bodyPartsTable == null) 
                    bodyPartsTable = new Dictionary>();
                return bodyPartsTable; 
            }
        }

        static internal void ImportMessageBinding(WsdlImporter importer, WsdlEndpointConversionContext endpointContext, Type schemaImporterType) 
        {
            // All the work is done in ImportMessageContract call 
            bool isReferencedContract = IsReferencedContract(importer, endpointContext); 

            MarkSoapExtensionsAsHandled(endpointContext.WsdlBinding); 

            foreach (WsdlNS.OperationBinding wsdlOperationBinding in endpointContext.WsdlBinding.Operations)
            {
                OperationDescription operation = endpointContext.GetOperationDescription(wsdlOperationBinding); 
                if (isReferencedContract || OperationHasBeenHandled(operation))
                { 
                    MarkSoapExtensionsAsHandled(wsdlOperationBinding); 

                    if (wsdlOperationBinding.Input != null) 
                    {
                        MarkSoapExtensionsAsHandled(wsdlOperationBinding.Input);
                    }
 
                    if (wsdlOperationBinding.Output != null)
                    { 
                        MarkSoapExtensionsAsHandled(wsdlOperationBinding.Output); 
                    }
 
                    foreach (WsdlNS.MessageBinding wsdlMessageBinding in wsdlOperationBinding.Faults)
                    {
                        MarkSoapExtensionsAsHandled(wsdlMessageBinding);
                    } 
                }
            } 
 
        }
 
        static bool OperationHasBeenHandled(OperationDescription operation)
        {
            return (operation.Behaviors.Find() != null);
        } 

        static bool IsReferencedContract(WsdlImporter importer, WsdlEndpointConversionContext endpointContext) 
        { 
            return importer.KnownContracts.ContainsValue(endpointContext.Endpoint.Contract);
        } 

        static void MarkSoapExtensionsAsHandled(WsdlNS.NamedItem item)
        {
            foreach (object o in item.Extensions) 
            {
                WsdlNS.ServiceDescriptionFormatExtension ext = o as WsdlNS.ServiceDescriptionFormatExtension; 
                if (ext != null && IsSoapBindingExtension(ext)) 
                    ext.Handled = true;
                else if (SoapHelper.IsSoapFaultBinding(o as XmlElement)) 
                    ext.Handled = true;
            }
        }
 
        static bool IsSoapBindingExtension(WsdlNS.ServiceDescriptionFormatExtension ext)
        { 
            if (ext is WsdlNS.SoapBinding 
                || ext is WsdlNS.SoapBodyBinding
                || ext is WsdlNS.SoapHeaderBinding 
                || ext is WsdlNS.SoapOperationBinding
                || ext is WsdlNS.SoapFaultBinding
                || ext is WsdlNS.SoapHeaderFaultBinding
                ) 
            {
                return true; 
            } 

            return false; 

        }

        static internal void ImportMessageContract(WsdlImporter importer, WsdlContractConversionContext contractContext, SchemaImporter schemaImporter) 
        {
            new MessageContractImporter(importer, contractContext, schemaImporter).ImportMessageContract(); 
        } 

        MessageContractImporter(WsdlImporter importer, WsdlContractConversionContext contractContext, SchemaImporter schemaImporter) 
        {
            this.contractContext = contractContext;
            this.importer = importer;
            this.allSchemas = GatherSchemas(importer); 
            this.schemaImporter = schemaImporter;
 
            object faultImportOptions; 
            if (this.importer.State.TryGetValue(typeof(FaultImportOptions), out faultImportOptions))
                this.faultImportOptions = (FaultImportOptions)faultImportOptions; 
            else
                this.faultImportOptions = new FaultImportOptions();
        }
 
        XmlSchemaSet AllSchemas
        { 
            get { return this.allSchemas; } 
        }
 
        SchemaImporter CurrentSchemaImporter
        {
            get { return schemaImporter; }
        } 

        internal void AddWarning(string message) 
        { 
            AddError(message, true);
        } 

        void AddError(string message)
        {
            AddError(message, false); 
        }
 
        void AddError(string message, bool isWarning) 
        {
            MetadataConversionError warning = new MetadataConversionError(message, isWarning); 
            if (!importer.Errors.Contains(warning))
                importer.Errors.Add(warning);
        }
 
        void TraceImportInformation(OperationDescription operation)
        { 
            if (DiagnosticUtility.ShouldTraceInformation) 
            {
                Dictionary ht = new Dictionary(); 
                ht.Add("Operation", operation.Name);
                ht.Add("Format", CurrentSchemaImporter.GetFormatName());
                TraceUtility.TraceEvent(TraceEventType.Information, TraceCode.CannotBeImportedInCurrentFormat,
                                                    new DictionaryTraceRecord(ht), null, null); 
            }
        } 
 
        void ImportMessageContract()
        { 
            if (contractContext.Contract.Operations.Count <= 0)
                return;
            CurrentSchemaImporter.PreprocessSchema();
 
            bool importerUsed = true;
 
            OperationInfo[] infos = new OperationInfo[contractContext.Contract.Operations.Count]; 
            int i = 0;
            foreach (OperationDescription operation in contractContext.Contract.Operations) 
            {
                OperationInfo operationInfo;
                if (!CanImportOperation(operation, out operationInfo))
                { 
                    TraceImportInformation(operation);
                    importerUsed = false; 
                    break; 
                }
                infos[i++] = operationInfo; 
            }

            if (importerUsed)
            { 
                i = 0;
                foreach (OperationDescription operation in contractContext.Contract.Operations) 
                { 
                    ImportOperationContract(operation, infos[i++]);
                } 
            }
            CurrentSchemaImporter.PostprocessSchema(importerUsed);
        }
 
        bool CanImportOperation(OperationDescription operation, out OperationInfo operationInfo)
        { 
            operationInfo = null; 
            if (OperationHasBeenHandled(operation))
                return false; 

            WsdlNS.Operation wsdlOperation = contractContext.GetOperation(operation);
            Collection wsdlOperationBindings = contractContext.GetOperationBindings(wsdlOperation);
 
            return CanImportOperation(operation, wsdlOperation, wsdlOperationBindings, out operationInfo)
                && CanImportFaults(wsdlOperation, operation); 
        } 

        bool CanImportFaults(WsdlNS.Operation operation, OperationDescription description) 
        {
            // When this.faultImportOptions.UseMessageFormat is false, we fall back to the V1 behavior of using DataContractSerializer to import all faults.
            // We can, therefore, return true in those cases without actually doing the checks involved in CanImportFaults.
            if (!this.faultImportOptions.UseMessageFormat) 
                return true;
 
            foreach (WsdlNS.OperationFault fault in operation.Faults) 
            {
                if (!CanImportFault(fault, description)) 
                    return false;
            }
            return true;
        } 

        bool CanImportFault(WsdlNS.OperationFault fault, OperationDescription description) 
        { 
            XmlSchemaElement detailElement;
            XmlQualifiedName detailElementTypeName; 
            XmlQualifiedName detailElementQname;

            if (!ValidateFault(fault, description, out detailElement, out detailElementTypeName, out detailElementQname))
                return false; 

            return this.CurrentSchemaImporter.CanImportFault(detailElement, detailElementTypeName); 
        } 

        void ImportOperationContract(OperationDescription operation, OperationInfo operationInfo) 
        {
            Debug.Assert(!OperationHasBeenHandled(operation));
            Debug.Assert(operationInfo != null);
 
            WsdlNS.Operation wsdlOperation = contractContext.GetOperation(operation);
            Collection wsdlOperationBindings = contractContext.GetOperationBindings(wsdlOperation); 
 
            bool isReply = false;
            foreach (WsdlNS.OperationMessage operationMessage in wsdlOperation.Messages) 
            {
                ImportMessage(operationMessage, isReply, operationInfo.IsEncoded, operationInfo.AreAllMessagesWrapped);
                isReply = true;
            } 

            if (operationInfo.Style == OperationFormatStyle.Rpc) 
                SetWrapperName(operation); 
            this.CurrentSchemaImporter.SetOperationStyle(operation, operationInfo.Style);
            this.CurrentSchemaImporter.SetOperationIsEncoded(operation, operationInfo.IsEncoded); 
            this.CurrentSchemaImporter.SetOperationSupportFaults(operation,
                this.faultImportOptions.UseMessageFormat);

            ImportFaults(wsdlOperation, operation, operationInfo.IsEncoded); 

            foreach (WsdlNS.OperationBinding wsdlOperationBinding in wsdlOperationBindings) 
            { 
                foreach (MessageDescription message in operation.Messages)
                { 
                    WsdlNS.OperationMessage wsdlOperationMessage = contractContext.GetOperationMessage(message);
                    WsdlNS.ServiceDescriptionCollection wsdlDocuments = wsdlOperationMessage.Operation.PortType.ServiceDescription.ServiceDescriptions;
                    WsdlNS.Message wsdlMessage = wsdlDocuments.GetMessage(wsdlOperationMessage.Message);
 
                    WsdlNS.MessageBinding messageBinding = (message.Direction == MessageDirection.Input)
                        ? (WsdlNS.MessageBinding)wsdlOperationBinding.Input 
                        : (WsdlNS.MessageBinding)wsdlOperationBinding.Output; 

                    if (messageBinding != null) 
                        ImportMessageBinding(messageBinding, wsdlMessage, message, operationInfo.Style, operationInfo.IsEncoded);
                }
            }
 
            operation.Behaviors.Add(CurrentSchemaImporter.GetOperationGenerator());
        } 
 
        bool CanImportOperation(OperationDescription operation, WsdlNS.Operation wsdlOperation, Collection operationBindings,
            out OperationInfo operationInfo) 
        {
            operationInfo = null;
            OperationFormatStyle style = OperationFormatStyle.Document;
            bool isEncoded = false; 
            bool areAllMessagesWrapped = true;
 
            // Check if operation bindings can be imported 

            StyleAndUse? styleAndUse = null; 
            WsdlNS.ServiceDescriptionCollection documents = wsdlOperation.PortType.ServiceDescription.ServiceDescriptions;
            WsdlNS.OperationBinding prevOperationBinding = null;
            foreach (WsdlNS.OperationBinding operationBinding in operationBindings)
            { 
                OperationFormatStyle operationStyle = GetStyle(operationBinding);
                bool? isOperationEncoded = null; 
                foreach (MessageDescription message in operation.Messages) 
                {
                    WsdlNS.OperationMessage operationMessage = contractContext.GetOperationMessage(message); 

                    if (operationMessage.Message.IsEmpty)
                    {
                        if (operationMessage is WsdlNS.OperationInput) 
                            throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SFxWsdlOperationInputNeedsMessageAttribute2, wsdlOperation.Name, wsdlOperation.PortType.Name)));
                        if (operationMessage is WsdlNS.OperationOutput) 
                            throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SFxWsdlOperationOutputNeedsMessageAttribute2, wsdlOperation.Name, wsdlOperation.PortType.Name))); 
                    }
                    WsdlNS.Message wsdlMessage = documents.GetMessage(operationMessage.Message); 

                    if (wsdlMessage != null)
                    {
                        WsdlNS.MessageBinding messageBinding = (message.Direction == MessageDirection.Input) 
                            ? (WsdlNS.MessageBinding)operationBinding.Input
                            : (WsdlNS.MessageBinding)operationBinding.Output; 
 
                        if (messageBinding != null)
                        { 
                            bool isMessageEncoded;
                            if (!CanImportMessageBinding(messageBinding, wsdlMessage, operationStyle, out isMessageEncoded))
                                return false;
 
                            if (isOperationEncoded == null)
                                isOperationEncoded = isMessageEncoded; 
                            else if (isOperationEncoded != isMessageEncoded) 
                                AddError(SR.GetString(SR.SFxInconsistentWsdlOperationUseInBindingMessages, messageBinding.OperationBinding.Name, messageBinding.OperationBinding.Binding.Name));
                        } 
                    }
                }
                foreach (WsdlNS.FaultBinding faultBinding in operationBinding.Faults)
                { 
                    bool isFaultEncoded;
                    if (!CanImportFaultBinding(faultBinding, operationStyle, out isFaultEncoded)) 
                        return false; 
                    if (isOperationEncoded == null)
                        isOperationEncoded = isFaultEncoded; 
                    else if (isOperationEncoded != isFaultEncoded)
                        AddError(SR.GetString(SR.SFxInconsistentWsdlOperationUseInBindingFaults, faultBinding.OperationBinding.Name, faultBinding.OperationBinding.Binding.Name));
                }
                isOperationEncoded = isOperationEncoded ?? false; 

                if (styleAndUse == null) 
                { 
                    styleAndUse = GetStyleAndUse(operationStyle, isOperationEncoded.Value);
                    style = operationStyle; 
                    isEncoded = isOperationEncoded.Value;
                    prevOperationBinding = operationBinding;
                }
                else 
                {
                    StyleAndUse operationStyleAndUse = GetStyleAndUse(operationStyle, isOperationEncoded.Value); 
                    if (operationStyleAndUse != styleAndUse) 
                    {
                        AddError(SR.GetString(SR.SFxInconsistentWsdlOperationUseAndStyleInBinding, 
                            operation.Name, operationBinding.Binding.Name, GetUse(operationStyleAndUse), GetStyle(operationStyleAndUse),
                            prevOperationBinding.Binding.Name, GetUse(styleAndUse.Value), GetStyle(styleAndUse.Value)));
                    }
                    if (operationStyleAndUse < styleAndUse) 
                    {
                        styleAndUse = operationStyleAndUse; 
                        style = operationStyle; 
                        isEncoded = isOperationEncoded.Value;
                        prevOperationBinding = operationBinding; 
                    }
                }
            }
 
            // Check if operation can be imported
            OperationFormatStyle? inferredOperationStyle = null; 
            foreach (WsdlNS.OperationMessage wsdlOperationMessage in wsdlOperation.Messages) 
            {
                if (wsdlOperationMessage.Message.IsEmpty) 
                {
                    if (wsdlOperationMessage is WsdlNS.OperationInput)
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SFxWsdlOperationInputNeedsMessageAttribute2, wsdlOperation.Name, wsdlOperation.PortType.Name)));
                    if (wsdlOperationMessage is WsdlNS.OperationOutput) 
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SFxWsdlOperationOutputNeedsMessageAttribute2, wsdlOperation.Name, wsdlOperation.PortType.Name)));
                } 
                WsdlNS.Message wsdlMessage = documents.GetMessage(wsdlOperationMessage.Message); 

                OperationFormatStyle? inferredMessageStyle; 
                if (!CanImportMessage(wsdlMessage, wsdlOperationMessage.Name, out inferredMessageStyle, ref areAllMessagesWrapped))
                    return false;

                if (wsdlMessage.Parts.Count > 0) 
                {
                    if (inferredOperationStyle == null 
                        || (inferredMessageStyle != null 
                            && inferredMessageStyle != inferredOperationStyle
                            && inferredMessageStyle.Value == OperationFormatStyle.Document)) 
                    {
                        inferredOperationStyle = inferredMessageStyle;
                    }
                } 
            }
 
            // Verify that information in operation bindings and operation match 
            if (styleAndUse == null)
                style = inferredOperationStyle ?? OperationFormatStyle.Document; 
            else if (inferredOperationStyle != null)
            {
                if (inferredOperationStyle.Value != style && inferredOperationStyle.Value == OperationFormatStyle.Document)
                    AddError(SR.GetString(SR.SFxInconsistentWsdlOperationStyleInOperationMessages, operation.Name, inferredOperationStyle, style)); 
            }
            operationInfo = new OperationInfo(style, isEncoded, areAllMessagesWrapped); 
            return true; 
        }
 
        bool CanImportMessage(WsdlNS.Message wsdlMessage, string operationName, out OperationFormatStyle? inferredStyle, ref bool areAllMessagesWrapped)
        {
            WsdlNS.MessagePartCollection messageParts = wsdlMessage.Parts;
            // try the special cases: wrapped and Message 
            if (messageParts.Count == 1)
            { 
                if (CanImportAnyMessage(messageParts[0])) 
                {
                    areAllMessagesWrapped = false; 
                    inferredStyle = OperationFormatStyle.Document;
                    return true;
                }
 
                if (CanImportStream(messageParts[0], out inferredStyle, ref areAllMessagesWrapped))
                    return true; 
 
                if (areAllMessagesWrapped && CanImportWrappedMessage(messageParts[0]))
                { 
                    inferredStyle = OperationFormatStyle.Document;
                    return true;
                }
                areAllMessagesWrapped = false; 
            }
 
            inferredStyle = null; 
            IList bodyPartsFromBindings;
            BodyPartsTable.TryGetValue(wsdlMessage, out bodyPartsFromBindings); 
            foreach (WsdlNS.MessagePart part in messageParts)
            {
                if (bodyPartsFromBindings != null && !bodyPartsFromBindings.Contains(part.Name))
                    continue; 
                OperationFormatStyle style;
                if (!CurrentSchemaImporter.CanImportMessagePart(part, out style)) 
                    return false; 

                if (inferredStyle == null) 
                    inferredStyle = style;
                else if (style != inferredStyle.Value)
                    AddError(SR.GetString(SR.SFxInconsistentWsdlOperationStyleInMessageParts, operationName));
            } 
            return true;
        } 
 
        void ImportMessage(WsdlNS.OperationMessage wsdlOperationMessage, bool isReply, bool isEncoded, bool areAllMessagesWrapped)
        { 
            MessageDescription messageDescription = contractContext.GetMessageDescription(wsdlOperationMessage);
            OperationDescription operation = contractContext.GetOperationDescription(wsdlOperationMessage.Operation);
            WsdlNS.ServiceDescriptionCollection wsdlDocuments = wsdlOperationMessage.Operation.PortType.ServiceDescription.ServiceDescriptions;
            WsdlNS.Message wsdlMessage = wsdlDocuments.GetMessage(wsdlOperationMessage.Message); 

            if (wsdlMessage.Parts.Count == 1) 
            { 
                if (TryImportAnyMessage(wsdlMessage.Parts[0], messageDescription, isReply))
                    return; 
                if (TryImportStream(wsdlMessage.Parts[0], messageDescription, isReply, areAllMessagesWrapped))
                    return;
                if (areAllMessagesWrapped && TryImportWrappedMessage(messageDescription, operation.Messages[0], wsdlMessage, isReply))
                    return; 
            }
 
            WsdlNS.MessagePartCollection messageParts = wsdlMessage.Parts; 
            IList bodyPartsFromBindings;
            BodyPartsTable.TryGetValue(wsdlMessage, out bodyPartsFromBindings); 
            string[] parameterOrder = wsdlOperationMessage.Operation.ParameterOrder;

            foreach (WsdlNS.MessagePart part in messageParts)
            { 
                if (!ValidWsdl.Check(part, wsdlMessage, AddWarning))
                    continue; 
 
                if (bodyPartsFromBindings != null && !bodyPartsFromBindings.Contains(part.Name))
                    continue; 
                bool isReturn = false;
                if (parameterOrder != null && isReply)
                    isReturn = Array.IndexOf(parameterOrder, part.Name) == -1;
                MessagePartDescription partDesc = CurrentSchemaImporter.ImportMessagePart(part, false/*isHeader*/, isEncoded); 
                if (isReturn && messageDescription.Body.ReturnValue == null)
                    messageDescription.Body.ReturnValue = partDesc; 
                else 
                    messageDescription.Body.Parts.Add(partDesc);
            } 

            if (isReply && messageDescription.Body.ReturnValue == null)
            {
                if (messageDescription.Body.Parts.Count > 0) 
                {
                    if (!CheckIsRef(operation.Messages[0], messageDescription.Body.Parts[0])) 
                    { 
                        messageDescription.Body.ReturnValue = messageDescription.Body.Parts[0];
                        messageDescription.Body.Parts.RemoveAt(0); 
                    }
                }
            }
        } 

        enum StyleAndUse 
        { 
            DocumentLiteral,
            RpcLiteral, 
            RpcEncoded,
            DocumentEncoded,
        }
 
        static StyleAndUse GetStyleAndUse(OperationFormatStyle style, bool isEncoded)
        { 
            if (style == OperationFormatStyle.Document) 
            {
                return isEncoded ? StyleAndUse.DocumentEncoded : StyleAndUse.DocumentLiteral; 
            }
            else
            {
                return isEncoded ? StyleAndUse.RpcEncoded : StyleAndUse.RpcLiteral; 
            }
        } 
 
        static string GetStyle(StyleAndUse styleAndUse)
        { 
            return (styleAndUse == StyleAndUse.RpcLiteral || styleAndUse == StyleAndUse.RpcEncoded) ? "rpc" : "document";
        }

        static string GetUse(StyleAndUse styleAndUse) 
        {
            return (styleAndUse == StyleAndUse.RpcEncoded || styleAndUse == StyleAndUse.DocumentEncoded) ? "encoded" : "literal"; 
        } 

        static void SetWrapperName(OperationDescription operation) 
        {
            MessageDescriptionCollection messages = operation.Messages;
            if (messages != null && messages.Count > 0)
            { 
                MessageDescription request = messages[0];
                if (request != null) 
                { 
                    request.Body.WrapperName = operation.Name;
                    request.Body.WrapperNamespace = operation.DeclaringContract.Namespace; 
                }
                if (messages.Count > 1)
                {
                    MessageDescription response = messages[1]; 
                    if (response != null)
                    { 
                        response.Body.WrapperName = TypeLoader.GetBodyWrapperResponseName(operation.Name).EncodedName; 
                        response.Body.WrapperNamespace = operation.DeclaringContract.Namespace;
                    } 
                }
            }
        }
 
        void ImportFaults(WsdlNS.Operation operation, OperationDescription description, bool isEncoded)
        { 
            foreach (WsdlNS.OperationFault fault in operation.Faults) 
            {
                ImportFault(fault, description, isEncoded); 
            }
        }

        void ImportFault(WsdlNS.OperationFault fault, OperationDescription description, bool isEncoded) 
        {
            XmlSchemaElement detailElement; 
            XmlQualifiedName detailElementTypeName; 
            XmlQualifiedName detailElementQname;
 
            if (!ValidateFault(fault, description, out detailElement, out detailElementTypeName, out detailElementQname))
                return;

            SchemaImporter faultImporter; 
            if (this.faultImportOptions.UseMessageFormat)
                faultImporter = this.CurrentSchemaImporter; 
            else 
                faultImporter = DataContractSerializerSchemaImporter.Get(this.importer);
            CodeTypeReference detailElementTypeRef; 
            if (IsNullOrEmpty(detailElementTypeName))
                detailElementTypeRef = faultImporter.ImportFaultElement(detailElementQname, detailElement, isEncoded);
            else
                detailElementTypeRef = faultImporter.ImportFaultType(detailElementQname, detailElementTypeName, isEncoded); 
            FaultDescription faultDescription = contractContext.GetFaultDescription(fault);
            faultDescription.DetailTypeReference = detailElementTypeRef; 
            faultDescription.ElementName = new XmlName(detailElementQname.Name, true /*isEncoded*/); 
            faultDescription.Namespace = detailElementQname.Namespace;
        } 

        bool ValidateFault(WsdlNS.OperationFault fault, OperationDescription description, out XmlSchemaElement detailElement,
            out XmlQualifiedName detailElementTypeName, out XmlQualifiedName detailElementQname)
        { 
            detailElement = null;
            detailElementTypeName = null; 
            detailElementQname = null; 

            // this will throw if the message is not found (consider wrapping exception) 
            WsdlNS.ServiceDescriptionCollection wsdlDocuments = fault.Operation.PortType.ServiceDescription.ServiceDescriptions;

            if (fault.Message.IsEmpty)
            { 
                TraceFaultCannotBeImported(fault.Name, description.Name, SR.GetString(SR.SFxWsdlOperationFaultNeedsMessageAttribute2, fault.Name, fault.Operation.PortType.Name));
                description.Faults.Remove(contractContext.GetFaultDescription(fault)); 
                return false; 
            }
            WsdlNS.Message faultMessage = wsdlDocuments.GetMessage(fault.Message); 

            // we only recognize faults with a single part (single element inside detail):
            if (faultMessage.Parts.Count != 1)
            { 
                TraceFaultCannotBeImported(fault.Name, description.Name, SR.GetString(SR.UnsupportedWSDLOnlyOneMessage));
                description.Faults.Remove(contractContext.GetFaultDescription(fault)); 
                return false; 
            }
 
            WsdlNS.MessagePart faultMessageDetail = faultMessage.Parts[0];
            detailElementQname = faultMessageDetail.Element;

            if (IsNullOrEmpty(detailElementQname) || !IsNullOrEmpty(faultMessageDetail.Type)) 
            {
                TraceFaultCannotBeImported(fault.Name, description.Name, SR.GetString(SR.UnsupportedWSDLTheFault)); 
                description.Faults.Remove(contractContext.GetFaultDescription(fault)); 
                return false;
            } 

            detailElement = FindSchemaElement(this.AllSchemas, detailElementQname);
            detailElementTypeName = GetTypeName(detailElement);
            return true; 
        }
 
        bool CanImportAnyMessage(WsdlNS.MessagePart part) 
        {
            return CheckPart(part.Type, DataContractSerializerMessageContractImporter.GenericMessageTypeName); 
        }

        bool TryImportAnyMessage(WsdlNS.MessagePart part, MessageDescription description, bool isReply)
        { 
            return CheckAndAddPart(part.Type, DataContractSerializerMessageContractImporter.GenericMessageTypeName, part.Name, string.Empty, typeof(Message), description, isReply);
        } 
 
        bool CanImportStream(WsdlNS.MessagePart part, out OperationFormatStyle? style, ref bool areAllMessagesWrapped)
        { 
            style = OperationFormatStyle.Document;
            string ns;
            XmlSchemaForm elementFormDefault;
            if (areAllMessagesWrapped && IsWrapperPart(part)) 
            {
                XmlSchemaComplexType complexType = GetElementComplexType(part.Element, allSchemas, out ns, out elementFormDefault); 
                if (complexType != null) 
                {
                    XmlSchemaSequence rootSequence = GetRootSequence(complexType); 
                    if (rootSequence != null && rootSequence.Items.Count == 1 && rootSequence.Items[0] is XmlSchemaElement)
                        return CheckPart(((XmlSchemaElement)rootSequence.Items[0]).SchemaTypeName, DataContractSerializerMessageContractImporter.StreamBodyTypeName);
                }
                return false; 
            }
            areAllMessagesWrapped = false; 
            XmlQualifiedName typeName = part.Type; 
            style = OperationFormatStyle.Rpc;
            if (IsNullOrEmpty(typeName)) 
            {
                if (IsNullOrEmpty(part.Element))
                    return false;
                style = OperationFormatStyle.Document; 
                typeName = GetTypeName(FindSchemaElement(allSchemas, part.Element));
            } 
            return CheckPart(typeName, DataContractSerializerMessageContractImporter.StreamBodyTypeName); 
        }
 
        bool TryImportStream(WsdlNS.MessagePart part, MessageDescription description, bool isReply, bool areAllMessagesWrapped)
        {
            string ns = string.Empty;
            XmlSchemaForm elementFormDefault; 
            if (areAllMessagesWrapped && IsWrapperPart(part))
            { 
                XmlSchemaSequence rootSequence = GetRootSequence(GetElementComplexType(part.Element, allSchemas, out ns, out elementFormDefault)); 
                if (rootSequence != null && rootSequence.Items.Count == 1 && rootSequence.Items[0] is XmlSchemaElement)
                { 
                    XmlSchemaElement element = (XmlSchemaElement)rootSequence.Items[0];
                    description.Body.WrapperName = new XmlName(part.Element.Name, true /*isEncoded*/).EncodedName;
                    description.Body.WrapperNamespace = part.Element.Namespace;
                    return CheckAndAddPart(element.SchemaTypeName, DataContractSerializerMessageContractImporter.StreamBodyTypeName, element.Name, GetLocalElementNamespace(ns, element, elementFormDefault), typeof(Stream), description, isReply); 
                }
                return false; 
            } 
            XmlQualifiedName typeName = part.Type;
            if (IsNullOrEmpty(typeName)) 
            {
                if (IsNullOrEmpty(part.Element))
                    return false;
                ns = part.Element.Namespace; 
                typeName = GetTypeName(FindSchemaElement(allSchemas, part.Element));
            } 
            return CheckAndAddPart(typeName, DataContractSerializerMessageContractImporter.StreamBodyTypeName, part.Name, ns, typeof(Stream), description, isReply); 
        }
 
        bool CanImportWrappedMessage(WsdlNS.MessagePart wsdlPart)
        {
            return (IsWrapperPart(wsdlPart)) ? CurrentSchemaImporter.CanImportWrapperElement(wsdlPart.Element) : false;
        } 

        bool TryImportWrappedMessage(MessageDescription messageDescription, MessageDescription requestMessage, WsdlNS.Message wsdlMessage, bool isReply) 
        { 

            WsdlNS.MessagePart wsdlPart = wsdlMessage.Parts[0]; 
            if (CanImportWrappedMessage(wsdlPart))
            {
                XmlQualifiedName elementName = wsdlPart.Element;
                MessagePartDescription[] parts = CurrentSchemaImporter.ImportWrapperElement(elementName); 
                if (parts == null)
                    return false; 
                messageDescription.Body.WrapperName = new XmlName(elementName.Name, true /*isEncoded*/).EncodedName; 
                messageDescription.Body.WrapperNamespace = elementName.Namespace;
 
                if (parts.Length > 0)
                {
                    int partIndex = 0;
                    if (isReply && messageDescription.Body.ReturnValue == null && !CheckIsRef(requestMessage, parts[0])) 
                    {
                        messageDescription.Body.ReturnValue = parts[0]; 
                        partIndex = 1; 
                    }
                    for (; partIndex < parts.Length; partIndex++) 
                    {
                        MessagePartDescription part = parts[partIndex];
                        messageDescription.Body.Parts.Add(part);
                    } 
                }
                return true; 
            } 
            return false;
        } 

        private bool IsWrapperPart(WsdlNS.MessagePart wsdlPart)
        {
            bool wrapFlag = false; // turn off special-casing for partname="parameters" if "wrapped" flag was set by user 
            object wrappedOptions = null;
            if (this.importer.State.TryGetValue(typeof(WrappedOptions), out wrappedOptions)) 
            { 
                wrapFlag = ((WrappedOptions)wrappedOptions).WrappedFlag;
            } 
            return wsdlPart.Name == "parameters" && !IsNullOrEmpty(wsdlPart.Element) && !wrapFlag;
        }

        bool CheckIsRef(MessageDescription requestMessage, MessagePartDescription part) 
        {
            foreach (MessagePartDescription requestPart in requestMessage.Body.Parts) 
            { 
                if (CompareMessageParts(requestPart, part))
                    return true; 
            }
            return false;
        }
 
        bool CompareMessageParts(MessagePartDescription x, MessagePartDescription y)
        { 
            return (x.Name == y.Name && x.Namespace == y.Namespace); 
        }
 
        static WsdlNS.MessagePart FindPartByName(WsdlNS.Message message, string name)
        {
            Debug.Assert(message != null, "Should not attempt to look for a part in an null message.");
            foreach (WsdlNS.MessagePart part in message.Parts) 
                if (part.Name == name)
                    return part; 
 
            throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SFxWsdlMessageDoesNotContainPart3, name, message.Name, message.ServiceDescription.TargetNamespace)));
        } 

        static XmlSchemaElement FindSchemaElement(XmlSchemaSet schemaSet, XmlQualifiedName elementName)
        {
            XmlSchema schema; 
            return FindSchemaElement(schemaSet, elementName, out schema);
        } 
 
        static XmlSchemaElement FindSchemaElement(XmlSchemaSet schemaSet, XmlQualifiedName elementName, out XmlSchema containingSchema)
        { 
            XmlSchemaElement element = null;
            containingSchema = null;
            foreach (XmlSchema schema in GetSchema(schemaSet, elementName.Namespace))
            { 
                element = (XmlSchemaElement)schema.Elements[elementName];
                if (element != null) 
                { 
                    containingSchema = schema;
                    break; 
                }
            }
            if (element == null)
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SFxSchemaDoesNotContainElement, elementName.Name, elementName.Namespace))); 
            return element;
        } 
 
        static XmlSchemaType FindSchemaType(XmlSchemaSet schemaSet, XmlQualifiedName typeName)
        { 
            if (typeName.Namespace == XmlSchema.Namespace)
                return null;
            XmlSchema schema;
            return FindSchemaType(schemaSet, typeName, out schema); 
        }
 
        static XmlSchemaType FindSchemaType(XmlSchemaSet schemaSet, XmlQualifiedName typeName, out XmlSchema containingSchema) 
        {
            containingSchema = null; 
            if (StockSchemas.IsKnownSchema(typeName.Namespace))
                return null;

            XmlSchemaType type = null; 
            foreach (XmlSchema schema in GetSchema(schemaSet, typeName.Namespace))
            { 
                type = (XmlSchemaType)schema.SchemaTypes[typeName]; 
                if (type != null)
                { 
                    containingSchema = schema;
                    break;
                }
            } 
            if (type == null)
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SFxSchemaDoesNotContainType, typeName.Name, typeName.Namespace))); 
            return type; 
        }
 
        static XmlSchemaSet GatherSchemas(WsdlImporter importer)
        {
            XmlSchemaSet schemaSet = new XmlSchemaSet();
            schemaSet.XmlResolver = null; 

            foreach (WsdlNS.ServiceDescription wsdl in importer.WsdlDocuments) 
            { 
                XmlQualifiedName[] wsdlPrefixNsPairs = wsdl.Namespaces.ToArray();
                if (wsdl.Types != null && wsdl.Types.Schemas != null) 
                {
                    foreach (XmlSchema xsd in wsdl.Types.Schemas)
                    {
                        XmlSerializerNamespaces xsdNamespaces = xsd.Namespaces; 
                        XmlQualifiedName[] xsdPrefixNsPairs = xsdNamespaces.ToArray();
                        Dictionary prefixesUsed = new Dictionary(); 
                        foreach (XmlQualifiedName pair in xsdPrefixNsPairs) 
                            prefixesUsed.Add(pair.Name, null);
                        foreach (XmlQualifiedName pair in wsdlPrefixNsPairs) 
                            if (!prefixesUsed.ContainsKey(pair.Name))
                                xsdNamespaces.Add(pair.Name, pair.Namespace);
                        if (xsd.Items.Count > 0)
                        { 
                            schemaSet.Add(xsd);
                        } 
                        else 
                        {
                            // only add include schemas 
                            foreach (XmlSchemaExternal include in xsd.Includes)
                            {
                                if (include.Schema != null)
                                { 
                                    schemaSet.Add(include.Schema);
                                } 
                            } 
                        }
                    } 
                }
            }

            schemaSet.Add(importer.XmlSchemas); 

            return schemaSet; 
        } 

        // Segregate the schemas containing abstract types from those 
        // containing regular XML definitions.  This is important because
        // when you import something returning the ur-type (object), then
        // you need to import ALL types/elements within ALL schemas.  We
        // don't want the RPC-based types leaking over into the XML-based 
        // element definitions or literal types in the encoded schemas,
        // beacase it can cause schema coimpilation falure. 
        static void CollectEncodedAndLiteralSchemas(WsdlNS.ServiceDescriptionCollection serviceDescriptions, XmlSchemas encodedSchemas, XmlSchemas literalSchemas, XmlSchemaSet allSchemas) 
        {
            XmlSchema wsdl = StockSchemas.CreateWsdl(); 
            XmlSchema soap = StockSchemas.CreateSoap();
            XmlSchema soapEncoding = StockSchemas.CreateSoapEncoding();

            Hashtable references = new Hashtable(); 
            if (!allSchemas.Contains(wsdl.TargetNamespace))
            { 
                references[soap] = wsdl; 
            }
 
            if (!allSchemas.Contains(soap.TargetNamespace))
            {
                references[soap] = soap;
            } 
            if (!allSchemas.Contains(soapEncoding.TargetNamespace))
            { 
                references[soapEncoding] = soapEncoding; 
            }
            foreach (WsdlNS.ServiceDescription description in serviceDescriptions) 
            {
                foreach (WsdlNS.Message message in description.Messages)
                {
                    foreach (WsdlNS.MessagePart part in message.Parts) 
                    {
                        bool isEncoded; 
                        bool isLiteral; 
                        FindUse(part, out isEncoded, out isLiteral);
                        if (part.Element != null && !part.Element.IsEmpty) 
                        {
                            XmlSchemaElement element = FindSchemaElement(allSchemas, part.Element);
                            if (element != null)
                            { 
                                AddSchema(element.Parent as XmlSchema, isEncoded, isLiteral, encodedSchemas, literalSchemas, references);
                                if (element.SchemaTypeName != null && !element.SchemaTypeName.IsEmpty) 
                                { 
                                    XmlSchemaType type = FindSchemaType(allSchemas, element.SchemaTypeName);
                                    if (type != null) 
                                    {
                                        AddSchema(type.Parent as XmlSchema, isEncoded, isLiteral, encodedSchemas, literalSchemas, references);
                                    }
                                } 
                            }
                        } 
                        if (part.Type != null && !part.Type.IsEmpty) 
                        {
                            XmlSchemaType type = FindSchemaType(allSchemas, part.Type); 
                            if (type != null)
                            {
                                AddSchema(type.Parent as XmlSchema, isEncoded, isLiteral, encodedSchemas, literalSchemas, references);
                            } 
                        }
                    } 
                } 
            }
 
            Hashtable imports;
            foreach (XmlSchemas schemas in new XmlSchemas[] { encodedSchemas, literalSchemas })
            {
                // collect all imports 
                imports = new Hashtable();
                foreach (XmlSchema schema in schemas) 
                { 
                    AddImport(schema, imports, allSchemas);
                } 
                // make sure we add them to the corresponding schema collections
                foreach (XmlSchema schema in imports.Keys)
                {
                    if (references[schema] == null && !schemas.Contains(schema)) 
                    {
                        schemas.Add(schema); 
                    } 
                }
            } 

            // If a schema was not referenced by either a literal or an encoded message part,
            // add it to both collections. There's no way to tell which it should be.
            imports = new Hashtable(); 
            foreach (XmlSchema schema in allSchemas.Schemas())
            { 
                if (!encodedSchemas.Contains(schema) && !literalSchemas.Contains(schema)) 
                {
                    AddImport(schema, imports, allSchemas); 
                }
            }

            // make sure we add them to the corresponding schema collections 
            foreach (XmlSchema schema in imports.Keys)
            { 
                if (references[schema] != null) 
                    continue;
                if (!encodedSchemas.Contains(schema)) 
                {
                    encodedSchemas.Add(schema);
                }
                if (!literalSchemas.Contains(schema)) 
                {
                    literalSchemas.Add(schema); 
                } 
            }
            if (encodedSchemas.Count > 0) 
            {
                foreach (XmlSchema schema in references.Values)
                {
                    encodedSchemas.AddReference(schema); 
                }
            } 
            if (literalSchemas.Count > 0) 
            {
                foreach (XmlSchema schema in references.Values) 
                {
                    literalSchemas.AddReference(schema);
                }
            } 
            AddSoapEncodingSchemaIfNeeded(literalSchemas);
        } 
 
        static void AddSoapEncodingSchemaIfNeeded(XmlSchemas schemas)
        { 
            XmlSchema fakeXsdSchema = StockSchemas.CreateFakeXsdSchema();

            foreach (XmlSchema schema in schemas)
            { 
                foreach (object include in schema.Includes)
                { 
                    XmlSchemaImport import = include as XmlSchemaImport; 
                    if (import != null && import.Namespace == fakeXsdSchema.TargetNamespace)
                    { 
                        schemas.Add(fakeXsdSchema);
                        return;
                    }
                } 
            }
        } 
 
        static void AddImport(XmlSchema schema, Hashtable imports, XmlSchemaSet allSchemas)
        { 
            if (schema == null || imports[schema] != null)
                return;
            imports.Add(schema, schema);
            foreach (XmlSchemaExternal external in schema.Includes) 
            {
                if (external is XmlSchemaImport) 
                { 
                    XmlSchemaImport import = (XmlSchemaImport)external;
                    foreach (XmlSchema s in allSchemas.Schemas(import.Namespace)) 
                    {
                        AddImport(s, imports, allSchemas);
                    }
                } 
            }
        } 
 
        static void AddSchema(XmlSchema schema, bool isEncoded, bool isLiteral, XmlSchemas encodedSchemas, XmlSchemas literalSchemas, Hashtable references)
        { 
            if (schema != null)
            {
                if (isEncoded && !encodedSchemas.Contains(schema))
                { 
                    if (references.Contains(schema))
                    { 
                        encodedSchemas.AddReference(schema); 
                    }
                    else 
                    {
                        encodedSchemas.Add(schema);
                    }
                } 
                if (isLiteral && !literalSchemas.Contains(schema))
                { 
                    if (references.Contains(schema)) 
                    {
                        literalSchemas.AddReference(schema); 
                    }
                    else
                    {
                        literalSchemas.Add(schema); 
                    }
                } 
            } 
        }
 
        static void FindUse(WsdlNS.MessagePart part, out bool isEncoded, out bool isLiteral)
        {
            isEncoded = false;
            isLiteral = false; 
            string messageName = part.Message.Name;
            WsdlNS.Operation associatedOperation = null; 
            WsdlNS.ServiceDescription description = part.Message.ServiceDescription; 
            foreach (WsdlNS.PortType portType in description.PortTypes)
            { 
                foreach (WsdlNS.Operation operation in portType.Operations)
                {
                    foreach (WsdlNS.OperationMessage message in operation.Messages)
                    { 
                        if (message.Message.Equals(new XmlQualifiedName(part.Message.Name, description.TargetNamespace)))
                        { 
                            associatedOperation = operation; 
                            FindUse(associatedOperation, description, messageName, ref isEncoded, ref isLiteral);
                        } 
                    }
                }
            }
            if (associatedOperation == null) 
                FindUse(null, description, messageName, ref isEncoded, ref isLiteral);
        } 
 
        static void FindUse(WsdlNS.Operation operation, WsdlNS.ServiceDescription description, string messageName, ref bool isEncoded, ref bool isLiteral)
        { 
            string targetNamespace = description.TargetNamespace;
            foreach (WsdlNS.Binding binding in description.Bindings)
            {
                if (operation != null && !new XmlQualifiedName(operation.PortType.Name, targetNamespace).Equals(binding.Type)) 
                    continue;
                foreach (WsdlNS.OperationBinding bindingOperation in binding.Operations) 
                { 
                    if (bindingOperation.Input != null) foreach (object extension in bindingOperation.Input.Extensions)
                        { 
                            if (operation != null)
                            {
                                WsdlNS.SoapBodyBinding body = extension as WsdlNS.SoapBodyBinding;
                                if (body != null && operation.IsBoundBy(bindingOperation)) 
                                {
                                    if (body.Use == WsdlNS.SoapBindingUse.Encoded) 
                                        isEncoded = true; 
                                    else if (body.Use == WsdlNS.SoapBindingUse.Literal)
                                        isLiteral = true; 
                                }
                            }
                            else
                            { 
                                WsdlNS.SoapHeaderBinding header = extension as WsdlNS.SoapHeaderBinding;
                                if (header != null && header.Message.Name == messageName) 
                                { 
                                    if (header.Use == WsdlNS.SoapBindingUse.Encoded)
                                        isEncoded = true; 
                                    else if (header.Use == WsdlNS.SoapBindingUse.Literal)
                                        isLiteral = true;
                                }
                            } 
                        }
                    if (bindingOperation.Output != null) foreach (object extension in bindingOperation.Output.Extensions) 
                        { 
                            if (operation != null)
                            { 
                                if (operation.IsBoundBy(bindingOperation))
                                {
                                    WsdlNS.SoapBodyBinding body = extension as WsdlNS.SoapBodyBinding;
                                    if (body != null) 
                                    {
                                        if (body.Use == WsdlNS.SoapBindingUse.Encoded) 
                                            isEncoded = true; 
                                        else if (body.Use == WsdlNS.SoapBindingUse.Literal)
                                            isLiteral = true; 
                                    }
                                    else if (extension is WsdlNS.MimeXmlBinding)
                                        isLiteral = true;
                                } 
                            }
                            else 
                            { 
                                WsdlNS.SoapHeaderBinding header = extension as WsdlNS.SoapHeaderBinding;
                                if (header != null && header.Message.Name == messageName) 
                                {
                                    if (header.Use == WsdlNS.SoapBindingUse.Encoded)
                                        isEncoded = true;
                                    else if (header.Use == WsdlNS.SoapBindingUse.Literal) 
                                        isLiteral = true;
                                } 
                            } 
                        }
                } 
            }
        }

        static string GetLocalElementNamespace(string ns, XmlSchemaElement element, XmlSchemaForm elementFormDefault) 
        {
            XmlSchemaForm elementForm = (element.Form != XmlSchemaForm.None) ? element.Form : elementFormDefault; 
            if (elementForm != XmlSchemaForm.Qualified) 
                return string.Empty;
            return ns; 
        }

        static IEnumerable GetSchema(XmlSchemaSet schemaSet, string ns)
        { 
            ICollection schemas = schemaSet.Schemas(ns);
            if (schemas == null || schemas.Count == 0) 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SFxSchemaNotFound, ns))); 
            return schemas;
        } 

        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;
        }
 
        static OperationFormatStyle GetStyle(WsdlNS.OperationBinding operationBinding)
        { 
            WsdlNS.SoapBindingStyle style = GetStyle(operationBinding.Binding); 
            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 == WsdlNS.SoapBindingStyle.Rpc) ? OperationFormatStyle.Rpc : OperationFormatStyle.Document;
        } 

        static XmlQualifiedName GetTypeName(XmlSchemaElement element)
        {
            if (element.SchemaType != null) 
                return XmlQualifiedName.Empty;
            else if (IsNullOrEmpty(element.SchemaTypeName)) 
                return AnyType; 
            else
                return element.SchemaTypeName; 
        }

        static bool IsNullOrEmpty(XmlQualifiedName qname)
        { 
            return qname == null || qname.IsEmpty;
        } 
 
        void TraceFaultCannotBeImported(string faultName, string operationName, string message)
        { 
            AddWarning(SR.GetString(SR.SFxFaultCannotBeImported, faultName, operationName, message));
        }

        static bool CheckAndAddPart(XmlQualifiedName typeNameFound, XmlQualifiedName typeNameRequired, string name, string ns, Type type, MessageDescription description, bool isReply) 
        {
            if (IsNullOrEmpty(typeNameFound) || typeNameFound != typeNameRequired) 
                return false; 
            MessagePartDescription bodyPart = new MessagePartDescription(name, ns);
            bodyPart.Type = type; 
            if (isReply && description.Body.ReturnValue == null)
                description.Body.ReturnValue = bodyPart;
            else
                description.Body.Parts.Add(bodyPart); 
            return true;
        } 
 
        static bool CheckPart(XmlQualifiedName typeNameFound, XmlQualifiedName typeNameRequired)
        { 
            return !IsNullOrEmpty(typeNameFound) && typeNameFound == typeNameRequired;
        }

        static XmlSchemaComplexType GetElementComplexType(XmlQualifiedName elementName, XmlSchemaSet schemaSet, out string ns, out XmlSchemaForm elementFormDefault) 
        {
            XmlSchema schema; 
            XmlSchemaElement schemaElement = FindSchemaElement(schemaSet, elementName, out schema); 
            ns = elementName.Namespace;
            elementFormDefault = schema.ElementFormDefault; 

            XmlSchemaType schemaType = null;
            if (schemaElement.SchemaType != null)
            { 
                schemaType = schemaElement.SchemaType;
            } 
            else 
            {
                XmlQualifiedName schemaTypeName = GetTypeName(schemaElement); 
                if (schemaTypeName.Namespace == XmlSchema.Namespace)
                    return null;

                schemaType = FindSchemaType(schemaSet, schemaTypeName, out schema); 
                ns = schemaTypeName.Namespace;
                elementFormDefault = schema.ElementFormDefault; 
            } 
            if (schemaType == null)
                return null; 

            return schemaType as XmlSchemaComplexType;
        }
 
        static XmlSchemaSequence GetRootSequence(XmlSchemaComplexType complexType)
        { 
            if (complexType == null) 
                return null;
            return complexType.Particle != null ? complexType.Particle as XmlSchemaSequence : null; 
        }

        bool CanImportMessageBinding(WsdlNS.MessageBinding messageBinding, WsdlNS.Message wsdlMessage, OperationFormatStyle style, out bool isEncoded)
        { 
            isEncoded = false;
 
            bool? isMessageEncoded = null; 
            foreach (object extension in messageBinding.Extensions)
            { 
                bool currentIsEncoded;
                WsdlNS.SoapHeaderBinding soapHeaderBinding = extension as WsdlNS.SoapHeaderBinding;

                if (soapHeaderBinding != null) 
                {
                    if (!ValidWsdl.Check(soapHeaderBinding, messageBinding, AddWarning)) 
                        return false; 

                    if (!CanImportMessageHeaderBinding(soapHeaderBinding, wsdlMessage, style, out currentIsEncoded)) 
                        return false;
                    if (isMessageEncoded == null)
                        isMessageEncoded = currentIsEncoded;
                    else if (isMessageEncoded.Value != currentIsEncoded) 
                        AddError(SR.GetString(SR.SFxInconsistentWsdlOperationUseInBindingExtensions, messageBinding.OperationBinding.Name, messageBinding.OperationBinding.Binding.Name));
                } 
                else 
                {
                    WsdlNS.SoapBodyBinding soapBodyBinding = extension as WsdlNS.SoapBodyBinding; 
                    if (soapBodyBinding != null)
                    {
                        if (!CanImportMessageBodyBinding(soapBodyBinding, style, out currentIsEncoded))
                            return false; 
                        if (isMessageEncoded == null)
                            isMessageEncoded = currentIsEncoded; 
                        else if (isMessageEncoded.Value != currentIsEncoded) 
                            AddError(SR.GetString(SR.SFxInconsistentWsdlOperationUseInBindingExtensions, messageBinding.OperationBinding.Name, messageBinding.OperationBinding.Binding.Name));
                        string[] messageParts = soapBodyBinding.Parts; 
                        if (messageParts == null)
                        {
                            messageParts = new string[wsdlMessage.Parts.Count];
                            for (int i = 0; i < messageParts.Length; i++) 
                                messageParts[i] = wsdlMessage.Parts[i].Name;
                        } 
                        IList bodyPartsFromBindings; 
                        bool isFirstBinding = false;
                        if (!BodyPartsTable.TryGetValue(wsdlMessage, out bodyPartsFromBindings)) 
                        {
                            bodyPartsFromBindings = new List();
                            BodyPartsTable.Add(wsdlMessage, bodyPartsFromBindings);
                            isFirstBinding = true; 
                        }
                        foreach (string partName in messageParts) 
                        { 
                            if (string.IsNullOrEmpty(partName))
                                continue; 
                            if (isFirstBinding)
                                bodyPartsFromBindings.Add(partName);
                            else if (!bodyPartsFromBindings.Contains(partName))
                            { 
                                AddError(SR.GetString(SR.SFxInconsistentBindingBodyParts, messageBinding.OperationBinding.Name, messageBinding.OperationBinding.Binding.Name, partName));
                                bodyPartsFromBindings.Add(partName); 
                            } 
                        }
                    } 
                }
            }
            if (isMessageEncoded != null)
                isEncoded = isMessageEncoded.Value; 
            return true;
        } 
 
        private bool CanImportFaultBinding(WsdlNS.FaultBinding faultBinding, OperationFormatStyle style, out bool isFaultEncoded)
        { 
            bool? isEncoded = null;
            bool currentIsEncoded;
            foreach (object extension in faultBinding.Extensions)
            { 
                XmlElement soapFaultBindingRaw = extension as XmlElement;
                if (SoapHelper.IsSoapFaultBinding(soapFaultBindingRaw)) 
                { 
                    currentIsEncoded = SoapHelper.IsEncoded(soapFaultBindingRaw);
                } 
                else
                {
                    WsdlNS.SoapFaultBinding soapFaultBinding = extension as WsdlNS.SoapFaultBinding;
                    if (soapFaultBinding == null) 
                        continue;
 
                    if (!ValidWsdl.Check(soapFaultBinding, faultBinding, AddWarning)) 
                        continue;
                    currentIsEncoded = (soapFaultBinding.Use == System.Web.Services.Description.SoapBindingUse.Encoded); 
                }

                if (isEncoded == null)
                    isEncoded = currentIsEncoded; 
                else if (isEncoded.Value != currentIsEncoded)
                    AddError(SR.GetString(SR.SFxInconsistentWsdlOperationUseInBindingExtensions, faultBinding.OperationBinding.Name, faultBinding.OperationBinding.Binding.Name)); 
            } 
            isFaultEncoded = isEncoded ?? false;
            return this.CurrentSchemaImporter.CanImportStyleAndUse(style, isFaultEncoded); 
        }


        bool CanImportMessageBodyBinding(WsdlNS.SoapBodyBinding bodyBinding, OperationFormatStyle style, out bool isEncoded) 
        {
            isEncoded = (bodyBinding.Use == WsdlNS.SoapBindingUse.Encoded); 
            return CurrentSchemaImporter.CanImportStyleAndUse(style, isEncoded); 
        }
 
        bool CanImportMessageHeaderBinding(WsdlNS.SoapHeaderBinding headerBinding, WsdlNS.Message wsdlMessage, OperationFormatStyle style, out bool isEncoded)
        {
            isEncoded = (headerBinding.Use == WsdlNS.SoapBindingUse.Encoded);
            WsdlNS.Message wsdlHeaderMessage = wsdlMessage.ServiceDescription.ServiceDescriptions.GetMessage(headerBinding.Message); 
            WsdlNS.MessagePart part = FindPartByName(wsdlHeaderMessage, headerBinding.Part);
 
            OperationFormatStyle headerStyle; 
            if (!CurrentSchemaImporter.CanImportMessagePart(part, out headerStyle))
                return false; 
            if (headerStyle != style)
                AddError(SR.GetString(SR.SFxInconsistentWsdlOperationStyleInHeader, part.Name, headerStyle, style));
            return CurrentSchemaImporter.CanImportStyleAndUse(style, isEncoded);
        } 

        void ImportMessageBinding(WsdlNS.MessageBinding messageBinding, WsdlNS.Message wsdlMessage, MessageDescription description, OperationFormatStyle style, bool isEncoded) 
        { 
            WsdlNS.OperationMessage wsdlOperationMessage = contractContext.GetOperationMessage(description);
            foreach (object extension in messageBinding.Extensions) 
            {
                WsdlNS.SoapHeaderBinding soapHeaderBinding = extension as WsdlNS.SoapHeaderBinding;
                if (soapHeaderBinding != null)
                { 
                    ImportMessageHeaderBinding(soapHeaderBinding, wsdlMessage, description, style, isEncoded, messageBinding.OperationBinding.Name);
                } 
                else 
                {
                    WsdlNS.SoapBodyBinding soapBodyBinding = extension as WsdlNS.SoapBodyBinding; 
                    if (soapBodyBinding != null)
                    {
                        ImportMessageBodyBinding(soapBodyBinding, wsdlMessage, description, style, isEncoded, messageBinding.OperationBinding.Name);
                    } 
                }
            } 
        } 

        void ImportMessageBodyBinding(WsdlNS.SoapBodyBinding bodyBinding, WsdlNS.Message wsdlMessage, MessageDescription description, OperationFormatStyle style, bool isEncoded, string operationName) 
        {
            if (style == OperationFormatStyle.Rpc && bodyBinding.Namespace != null)
                description.Body.WrapperNamespace = bodyBinding.Namespace;
            this.CurrentSchemaImporter.ValidateStyleAndUse(style, isEncoded, operationName); 
        }
 
        void ImportMessageHeaderBinding(WsdlNS.SoapHeaderBinding headerBinding, WsdlNS.Message wsdlMessage, MessageDescription description, OperationFormatStyle style, bool isEncoded, string operationName) 
        {
            WsdlNS.Message wsdlHeaderMessage = wsdlMessage.ServiceDescription.ServiceDescriptions.GetMessage(headerBinding.Message); 
            WsdlNS.MessagePart part = FindPartByName(wsdlHeaderMessage, headerBinding.Part);
            if (!description.Headers.Contains(this.CurrentSchemaImporter.GetPartName(part)))
            {
                description.Headers.Add((MessageHeaderDescription)schemaImporter.ImportMessagePart(part, true/*isHeader*/, isEncoded)); 
                this.CurrentSchemaImporter.ValidateStyleAndUse(style, isEncoded, operationName);
            } 
        } 

 
        internal abstract class SchemaImporter
        {
            readonly protected XmlSchemaSet schemaSet;
            readonly protected WsdlImporter importer; 

            internal SchemaImporter(WsdlImporter importer) 
            { 
                this.importer = importer;
                this.schemaSet = GatherSchemas(importer); 
            }

            internal XmlQualifiedName GetPartName(WsdlNS.MessagePart part)
            { 
                if (!IsNullOrEmpty(part.Element))
                    return part.Element; 
                if (!IsNullOrEmpty(part.Type)) 
                    return new XmlQualifiedName(part.Name, String.Empty);
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SFxWsdlPartMustHaveElementOrType, part.Name, part.Message.Name, part.Message.Namespaces))); 
            }

            internal bool CanImportMessagePart(WsdlNS.MessagePart part, out OperationFormatStyle style)
            { 
                style = OperationFormatStyle.Document;
                if (!IsNullOrEmpty(part.Element)) 
                    return CanImportElement(FindSchemaElement(this.schemaSet, part.Element)); 
                if (!IsNullOrEmpty(part.Type))
                { 
                    style = OperationFormatStyle.Rpc;
                    return CanImportType(part.Type);
                }
                return false; 
            }
 
            internal MessagePartDescription ImportMessagePart(WsdlNS.MessagePart part, bool isHeader, bool isEncoded) 
            {
                MessagePartDescription bodyPart = null; 
                if (!IsNullOrEmpty(part.Element))
                    return ImportParameterElement(part.Element, isHeader, false/*isMultiple*/);
                if (!IsNullOrEmpty(part.Type))
                { 
                    bodyPart = isHeader ? (MessagePartDescription)new MessageHeaderDescription(part.Name, String.Empty) : new MessagePartDescription(part.Name, String.Empty);
                    bodyPart.BaseType = ImportType(bodyPart, part.Type, isEncoded); 
                    return bodyPart; 
                }
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SFxWsdlPartMustHaveElementOrType, part.Name, part.Message.Name, part.Message.Namespaces))); 
            }


            internal MessagePartDescription ImportParameterElement(XmlQualifiedName elementName, bool isHeader, bool isMultiple) 
            {
                return ImportParameterElement(FindSchemaElement(this.schemaSet, elementName), elementName.Namespace, isHeader, isMultiple); 
            } 

            internal MessagePartDescription ImportParameterElement(XmlSchemaElement element, string ns, bool isHeader, bool isMultiple) 
            {
                if (element.MaxOccurs > 1)
                    isMultiple = true;
                if (!IsNullOrEmpty(element.RefName)) 
                    return ImportParameterElement(element.RefName, isHeader, isMultiple);
 
                MessagePartDescription part = isHeader ? (MessagePartDescription)new MessageHeaderDescription(element.Name, ns) : new MessagePartDescription(element.Name, ns); 
                part.Multiple = isMultiple;
                part.BaseType = ImportElement(part, element, false/*isEncoded*/); 
                return part;
            }

            internal virtual bool CanImportFault(XmlSchemaElement detailElement, XmlQualifiedName detailElementTypeName) 
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotImplementedException()); 
            } 

            internal virtual CodeTypeReference ImportFaultElement(XmlQualifiedName elementName, XmlSchemaElement element, bool isEncoded) 
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotImplementedException());
            }
 
            internal virtual CodeTypeReference ImportFaultType(XmlQualifiedName elementName, XmlQualifiedName typeName, bool isEncoded)
            { 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotImplementedException()); 
            }
 
            internal virtual void SetOperationSupportFaults(OperationDescription operation, bool supportFaults)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotImplementedException());
            } 

            internal abstract void PreprocessSchema(); 
            internal abstract void PostprocessSchema(bool used); 
            internal abstract bool CanImportStyleAndUse(OperationFormatStyle style, bool isEncoded);
            internal abstract void ValidateStyleAndUse(OperationFormatStyle style, bool isEncoded, string operationName); 
            internal abstract IOperationBehavior GetOperationGenerator();
            internal abstract bool CanImportType(XmlQualifiedName typeName);
            internal abstract string ImportType(MessagePartDescription part, XmlQualifiedName typeName, bool isEncoded);
            internal abstract bool CanImportElement(XmlSchemaElement element); 
            internal abstract string ImportElement(MessagePartDescription part, XmlSchemaElement element, bool isEncoded);
            internal abstract bool CanImportWrapperElement(XmlQualifiedName elementName); 
            internal abstract MessagePartDescription[] ImportWrapperElement(XmlQualifiedName elementName); 
            internal abstract void SetOperationStyle(OperationDescription operation, OperationFormatStyle style);
            internal abstract bool GetOperationIsEncoded(OperationDescription operation); 
            internal abstract void SetOperationIsEncoded(OperationDescription operation, bool isEncoded);
            internal abstract string GetFormatName();
        }
 
        internal class DataContractSerializerSchemaImporter : SchemaImporter
        { 
            DataContractSerializerOperationGenerator DataContractSerializerOperationGenerator; 
            ValidationEventHandler compileValidationEventHandler;
            Collection errors; 
            public DataContractSerializerSchemaImporter(WsdlImporter importer)
                : base(importer)
            {
                DataContractSerializerOperationGenerator = new DataContractSerializerOperationGenerator(DataContractImporter.CodeCompileUnit); 
            }
 
            XsdDataContractImporter DataContractImporter 
            {
                get 
                {
                    object dataContractImporter;
                    if (!importer.State.TryGetValue(typeof(XsdDataContractImporter), out dataContractImporter))
                    { 
                        object compileUnit;
                        if (!importer.State.TryGetValue(typeof(CodeCompileUnit), out compileUnit)) 
                        { 
                            compileUnit = new CodeCompileUnit();
                            importer.State.Add(typeof(CodeCompileUnit), compileUnit); 
                        }
                        dataContractImporter = new XsdDataContractImporter((CodeCompileUnit)compileUnit);
                        importer.State.Add(typeof(XsdDataContractImporter), dataContractImporter);
                    } 
                    return (XsdDataContractImporter)dataContractImporter;
                } 
            } 

            internal override bool CanImportElement(XmlSchemaElement element) 
            {
                if (!element.IsNillable && !SchemaHelper.IsElementValueType(element))
                    return false;
                return DataContractImporter.CanImport(schemaSet, element); 
            }
 
 
            internal override bool CanImportType(XmlQualifiedName typeName)
            { 
                return DataContractImporter.CanImport(schemaSet, typeName);
            }
            internal override bool CanImportWrapperElement(XmlQualifiedName elementName)
            { 
                string ns;
                XmlSchemaForm elementFormDefault; 
                XmlSchemaComplexType complexType = GetElementComplexType(elementName, schemaSet, out ns, out elementFormDefault); 
                if (complexType == null)
                    return false; 
                if (complexType.Particle == null)
                    return true;
                XmlSchemaSequence rootSequence = complexType.Particle as XmlSchemaSequence;
                if (rootSequence == null) 
                    return false;
 
                for (int i = 0; i < rootSequence.Items.Count; i++) 
                {
                    XmlSchemaElement element = rootSequence.Items[i] as XmlSchemaElement; 
                    if (element == null)
                        return false;
                    if (!IsNullOrEmpty(element.RefName))
                        element = FindSchemaElement(this.schemaSet, element.RefName); 
                    if (element.MaxOccurs > 1)
                        return false; 
                    if (!DataContractImporter.CanImport(schemaSet, element)) 
                        return false;
                } 
                return true;
            }

            internal override bool CanImportFault(XmlSchemaElement detailElement, XmlQualifiedName detailElementTypeName) 
            {
                DataContractSerializerSchemaImporter faultImporter = DataContractSerializerSchemaImporter.Get(importer); 
                if (IsNullOrEmpty(detailElementTypeName)) 
                    return faultImporter.CanImportFaultElement(detailElement);
                else 
                    return faultImporter.CanImportFaultType(detailElementTypeName);
            }

            internal static DataContractSerializerSchemaImporter Get(WsdlImporter importer) 
            {
                Type type = typeof(DataContractSerializerSchemaImporter); 
                object schemaImporter; 
                if (importer.State.ContainsKey(type))
                    schemaImporter = importer.State[type]; 
                else
                {
                    schemaImporter = new DataContractSerializerSchemaImporter(importer);
                    importer.State.Add(type, schemaImporter); 
                }
                return (DataContractSerializerSchemaImporter)schemaImporter; 
            } 

            internal override MessagePartDescription[] ImportWrapperElement(XmlQualifiedName elementName) 
            {
                string ns;
                XmlSchemaForm elementFormDefault;
                XmlSchemaComplexType complexType = GetElementComplexType(elementName, schemaSet, out ns, out elementFormDefault); 
                if (complexType == null)
                    return null; 
                if (complexType.Particle == null) 
                    return new MessagePartDescription[0];
                XmlSchemaSequence rootSequence = complexType.Particle as XmlSchemaSequence; 
                if (rootSequence == null)
                    return null;

                MessagePartDescription[] parts = new MessagePartDescription[rootSequence.Items.Count]; 

                for (int i = 0; i < rootSequence.Items.Count; i++) 
                { 
                    XmlSchemaElement localElement = rootSequence.Items[i] as XmlSchemaElement;
                    if (localElement == null) 
                        return null;
                    parts[i] = ImportParameterElement(localElement, GetLocalElementNamespace(ns, localElement, elementFormDefault), false/*isHeader*/, false/*isMultiple*/);
                    if (parts[i] == null)
                        return null; 
                }
                return parts; 
            } 

            internal override string ImportType(MessagePartDescription part, XmlQualifiedName typeName, bool isEncoded) 
            {
                if (isEncoded)
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SFxDataContractSerializerDoesNotSupportEncoded, part.Name)));
                DataContractImporter.Import(schemaSet, typeName); 
                CodeTypeReference typeRef = DataContractImporter.GetCodeTypeReference(typeName);
                ICollection knownTypeRefs = DataContractImporter.GetKnownTypeReferences(typeName); 
                DataContractSerializerOperationGenerator.Add(part, typeRef, knownTypeRefs, false/*IsNonNillableReferenceType*/); 
                if (typeRef.ArrayRank == 0)
                    return typeRef.BaseType; 
                else
                    return typeRef.BaseType + "[]";
            }
 
            internal override string ImportElement(MessagePartDescription part, XmlSchemaElement element, bool isEncoded)
            { 
                if (part.Multiple) 
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SFxDataContractSerializerDoesNotSupportBareArray, part.Name)));
                XmlQualifiedName typeName = DataContractImporter.Import(schemaSet, element); 
                CodeTypeReference typeRef = DataContractImporter.GetCodeTypeReference(typeName, element);
                ICollection knownTypeRefs = DataContractImporter.GetKnownTypeReferences(typeName);
                DataContractSerializerOperationGenerator.Add(part, typeRef, knownTypeRefs, !element.IsNillable && !IsValueType(typeName));
                if (typeRef.ArrayRank == 0) 
                    return typeRef.BaseType;
                else 
                    return typeRef.BaseType + "[]"; 
            }
 
            private bool IsValueType(XmlQualifiedName typeName)
            {
                XmlSchemaElement element = new XmlSchemaElement();
                element.IsNillable = true; 
                CodeTypeReference typeRef = DataContractImporter.GetCodeTypeReference(typeName, element);
                return typeRef.BaseType == typeof(Nullable<>).FullName; 
            } 

            int SetImportXmlType(bool value) 
            {
                if (DataContractImporter.Options == null)
                {
                    DataContractImporter.Options = new ImportOptions(); 
                    DataContractImporter.Options.ImportXmlType = value;
                    return -1; 
                } 
                if (DataContractImporter.Options.ImportXmlType != value)
                { 
                    DataContractImporter.Options.ImportXmlType = value;
                    return 0;
                }
                return 1; 
            }
 
            void RestoreImportXmlType(int oldValue) 
            {
                if (oldValue == 1) 
                    return;
                if (oldValue == 0)
                {
                    DataContractImporter.Options.ImportXmlType = !DataContractImporter.Options.ImportXmlType; 
                    return;
                } 
                DataContractImporter.Options = null; 
            }
 
            internal override CodeTypeReference ImportFaultElement(XmlQualifiedName elementName, XmlSchemaElement element, bool isEncoded)
            {
                int oldValue = SetImportXmlType(true);
                try 
                {
                    XmlQualifiedName typeName = DataContractImporter.Import(schemaSet, element); 
                    return DataContractImporter.GetCodeTypeReference(typeName, element); 
                }
                finally 
                {
                    RestoreImportXmlType(oldValue);
                }
            } 

            internal bool CanImportFaultElement(XmlSchemaElement element) 
            { 
                int oldValue = SetImportXmlType(false);
                try 
                {
                    return DataContractImporter.CanImport(schemaSet, element);
                }
                finally 
                {
                    RestoreImportXmlType(oldValue); 
                } 
            }
 
            internal override CodeTypeReference ImportFaultType(XmlQualifiedName elementName, XmlQualifiedName typeName, bool isEncoded)
            {
                int oldValue = SetImportXmlType(true);
                try 
                {
                    DataContractImporter.Import(schemaSet, typeName); 
                    return DataContractImporter.GetCodeTypeReference(typeName); 
                }
                finally 
                {
                    RestoreImportXmlType(oldValue);
                }
            } 

            internal bool CanImportFaultType(XmlQualifiedName typeName) 
            { 
                int oldValue = SetImportXmlType(false);
                try 
                {
                    return DataContractImporter.CanImport(schemaSet, typeName);
                }
                finally 
                {
                    RestoreImportXmlType(oldValue); 
                } 
            }
 
            internal override void PreprocessSchema()
            {
                errors = new Collection();
                compileValidationEventHandler = new ValidationEventHandler(delegate(object sender, ValidationEventArgs args) 
                {
                    SchemaHelper.HandleSchemaValidationError(sender, args, errors); 
                } 
                );
                schemaSet.ValidationEventHandler += compileValidationEventHandler; 
            }

            internal override void PostprocessSchema(bool used)
            { 
                if (used && errors != null)
                { 
                    foreach (MetadataConversionError error in errors) 
                        importer.Errors.Add(error);
                    errors.Clear(); 
                }
                schemaSet.ValidationEventHandler -= compileValidationEventHandler;
            }
 
            internal override IOperationBehavior GetOperationGenerator()
            { 
                return DataContractSerializerOperationGenerator; 
            }
 
            internal override bool CanImportStyleAndUse(OperationFormatStyle style, bool isEncoded)
            {
                return !isEncoded;
            } 

            internal override void ValidateStyleAndUse(OperationFormatStyle style, bool isEncoded, string operationName) 
            { 
                if (isEncoded)
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SFxDataContractSerializerDoesNotSupportEncoded, operationName))); 
            }

            internal override void SetOperationStyle(OperationDescription operation, OperationFormatStyle style)
            { 
                DataContractSerializerOperationBehavior operationBehavior = operation.Behaviors.Find();
                if (operationBehavior == null) 
                { 
                    operationBehavior = new DataContractSerializerOperationBehavior(operation, new DataContractFormatAttribute());
                    operation.Behaviors.Add(operationBehavior); 
                }
                operationBehavior.DataContractFormatAttribute.Style = style;
            }
 
            internal override bool GetOperationIsEncoded(OperationDescription operation)
            { 
                return false; 
            }
 
            internal override void SetOperationIsEncoded(OperationDescription operation, bool isEncoded)
            {
                if (isEncoded)
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SFxDataContractSerializerDoesNotSupportEncoded, operation.Name))); 
            }
 
            internal override void SetOperationSupportFaults(OperationDescription operation, bool supportFaults) 
            {
                return; 
            }

            internal override string GetFormatName()
            { 
                return "DataContract";
            } 
        } 

        internal class XmlSerializerSchemaImporter : SchemaImporter 
        {
            XmlSerializerOperationGenerator xmlSerializerOperationGenerator;
            XmlSchemaImporter xmlImporter;
            SoapSchemaImporter soapImporter; 
            CodeDomProvider codeProvider;
            XmlSchemas literalSchemas, encodedSchemas; 
            public XmlSerializerSchemaImporter(WsdlImporter importer) 
                : base(importer)
            { 

                XmlSerializerImportOptions options;
                if (importer.State.ContainsKey(typeof(XmlSerializerImportOptions)))
                { 
                    options = (XmlSerializerImportOptions)importer.State[typeof(XmlSerializerImportOptions)];
                } 
                else 
                {
                    object compileUnit; 
                    if (!importer.State.TryGetValue(typeof(CodeCompileUnit), out compileUnit))
                    {
                        compileUnit = new CodeCompileUnit();
                        importer.State.Add(typeof(CodeCompileUnit), compileUnit); 
                    }
                    options = new XmlSerializerImportOptions((CodeCompileUnit)compileUnit); 
                    importer.State.Add(typeof(XmlSerializerImportOptions), options); 
                }
                WsdlNS.WebReferenceOptions webReferenceOptions = options.WebReferenceOptions; 
                codeProvider = options.CodeProvider;

                encodedSchemas = new XmlSchemas();
                literalSchemas = new XmlSchemas(); 
                CollectEncodedAndLiteralSchemas(importer.WsdlDocuments, encodedSchemas, literalSchemas, schemaSet);
 
                CodeIdentifiers codeIdentifiers = new CodeIdentifiers(); 

                //SchemaImporter.ctor is not thread safe: MB49115, VSWhidbey580396 
                lock (schemaImporterLock)
                {
                    xmlImporter = new XmlSchemaImporter(literalSchemas, webReferenceOptions.CodeGenerationOptions, options.CodeProvider, new ImportContext(codeIdentifiers, false));
                } 

                if (webReferenceOptions != null) 
                { 
                    foreach (string extTypeName in webReferenceOptions.SchemaImporterExtensions)
                    { 
                        xmlImporter.Extensions.Add(extTypeName, Type.GetType(extTypeName, true /*throwOnError*/));
                    }
                }
                //SchemaImporter.ctor is not thread safe: MB49115, VSWhidbey580396 
                lock (schemaImporterLock)
                { 
                    soapImporter = new SoapSchemaImporter(encodedSchemas, webReferenceOptions.CodeGenerationOptions, options.CodeProvider, new ImportContext(codeIdentifiers, false)); 
                }
                xmlSerializerOperationGenerator = new XmlSerializerOperationGenerator(options); 
            }

            internal override bool CanImportElement(XmlSchemaElement element)
            { 
                return true;
            } 
 
            internal override bool CanImportType(XmlQualifiedName typeName)
            { 
                return true;
            }

            internal override bool CanImportWrapperElement(XmlQualifiedName elementName) 
            {
                string ns; 
                XmlSchemaForm elementFormDefault; 
                XmlSchemaComplexType complexType = GetElementComplexType(elementName, schemaSet, out ns, out elementFormDefault);
                if (complexType == null) 
                    return false;
                return true;
            }
 
            internal override bool CanImportFault(XmlSchemaElement detailElement, XmlQualifiedName detailElementTypeName)
            { 
                return true; 
            }
 
            internal static XmlSerializerSchemaImporter Get(WsdlImporter importer)
            {
                Type type = typeof(XmlSerializerSchemaImporter);
                object schemaImporter; 
                if (importer.State.ContainsKey(type))
                    schemaImporter = importer.State[type]; 
                else 
                {
                    schemaImporter = new XmlSerializerSchemaImporter(importer); 
                    importer.State.Add(type, schemaImporter);
                }
                return (XmlSerializerSchemaImporter)schemaImporter;
            } 

            internal override MessagePartDescription[] ImportWrapperElement(XmlQualifiedName elementName) 
            { 
                XmlMembersMapping membersMapping = xmlImporter.ImportMembersMapping(elementName);
                ArrayList parts = new ArrayList(); 
                for (int i = 0; i < membersMapping.Count; i++)
                {
                    XmlMemberMapping member = membersMapping[i];
                    string xmlName = NamingHelper.XmlName(member.MemberName); 
                    MessagePartDescription part = new MessagePartDescription(xmlName, member.Namespace == null ? string.Empty : member.Namespace);
                    xmlSerializerOperationGenerator.Add(part, member, membersMapping, false/*isEncoded*/); 
                    part.BaseType = member.GenerateTypeName(codeProvider); 
                    parts.Add(part);
                } 
                return (MessagePartDescription[])parts.ToArray(typeof(MessagePartDescription));
            }

            internal override CodeTypeReference ImportFaultElement(XmlQualifiedName elementName, XmlSchemaElement element, bool isEncoded) 
            {
                return ImportFaultType(elementName, element.QualifiedName, isEncoded); 
            } 

            internal override CodeTypeReference ImportFaultType(XmlQualifiedName elementName, XmlQualifiedName typeName, bool isEncoded) 
            {
                XmlName memberName = new XmlName(elementName.Name, true /*isEncoded*/);
                string memberNs = elementName.Namespace;
                XmlMembersMapping membersMapping; 
                SoapSchemaMember schemaMember = new SoapSchemaMember();
                schemaMember.MemberName = memberName.EncodedName; 
                schemaMember.MemberType = typeName; 
                if (isEncoded)
                { 
                    membersMapping = soapImporter.ImportMembersMapping(memberName.DecodedName, memberNs, new SoapSchemaMember[] { schemaMember });
                    this.xmlSerializerOperationGenerator.SoapExporter.ExportMembersMapping(membersMapping);
                }
                else 
                {
                    membersMapping = xmlImporter.ImportMembersMapping(memberName.DecodedName, memberNs, new SoapSchemaMember[] { schemaMember }); 
                    this.xmlSerializerOperationGenerator.XmlExporter.ExportMembersMapping(membersMapping); 
                }
                return new CodeTypeReference(this.xmlSerializerOperationGenerator.GetTypeName(membersMapping[0])); 
            }

            internal override string ImportType(MessagePartDescription part, XmlQualifiedName typeName, bool isEncoded)
            { 
                XmlName memberName = new XmlName(part.Name, true /*isEncoded*/);
                string memberNs = part.Namespace; 
                XmlMembersMapping membersMapping; 
                SoapSchemaMember schemaMember = new SoapSchemaMember();
                schemaMember.MemberName = memberName.EncodedName; 
                schemaMember.MemberType = typeName;
                if (isEncoded)
                    membersMapping = soapImporter.ImportMembersMapping(memberName.DecodedName, memberNs, new SoapSchemaMember[] { schemaMember });
                else 
                    membersMapping = xmlImporter.ImportMembersMapping(memberName.DecodedName, memberNs, new SoapSchemaMember[] { schemaMember });
                return AddPartType(part, membersMapping, isEncoded); 
            } 

            internal override string ImportElement(MessagePartDescription part, XmlSchemaElement element, bool isEncoded) 
            {
                if (isEncoded)
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SFxDocEncodedNotSupported, part.Name)));
                XmlMembersMapping membersMapping = xmlImporter.ImportMembersMapping(new XmlQualifiedName[] { element.QualifiedName }); 
                return AddPartType(part, membersMapping, isEncoded);
            } 
 
            private string AddPartType(MessagePartDescription part, XmlMembersMapping membersMapping, bool isEncoded)
            { 
                xmlSerializerOperationGenerator.Add(part, membersMapping[0], membersMapping, isEncoded);
                return membersMapping[0].GenerateTypeName(codeProvider);
            }
 
            internal override void PreprocessSchema()
            { 
                XmlSchema wsdl = StockSchemas.CreateWsdl(); 
                XmlSchema soap = StockSchemas.CreateSoap();
                XmlSchema soapEncoding = StockSchemas.CreateSoapEncoding(); 
                XmlSchema fakeXsdSchema = StockSchemas.CreateFakeXsdSchema();
                XmlSchema fakeXmlSchema = StockSchemas.CreateFakeXmlSchema();

                schemaSet.Add(wsdl); 
                schemaSet.Add(soap);
                schemaSet.Add(soapEncoding); 
                schemaSet.Add(fakeXsdSchema); 
                schemaSet.Add(fakeXmlSchema);
                SchemaHelper.Compile(schemaSet, importer.Errors); 
                schemaSet.Remove(wsdl);
                schemaSet.Remove(soap);
                schemaSet.Remove(soapEncoding);
                schemaSet.Remove(fakeXsdSchema); 
                schemaSet.Remove(fakeXmlSchema);
            } 
 
            internal override void PostprocessSchema(bool used)
            { 
            }

            internal override IOperationBehavior GetOperationGenerator()
            { 
                return xmlSerializerOperationGenerator;
            } 
 
            internal override bool CanImportStyleAndUse(OperationFormatStyle style, bool isEncoded)
            { 
                // Intentionally return true in all cases. Warning will be generated later if there are multiple bindings and one is doc-encoded.
                return true;
            }
 
            internal override void ValidateStyleAndUse(OperationFormatStyle style, bool isEncoded, string operationName)
            { 
                if (isEncoded && style != OperationFormatStyle.Rpc) 
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SFxDocEncodedNotSupported, operationName)));
            } 

            internal static XmlSerializerFormatAttribute GetFormatAttribute(OperationDescription operation, bool createNew)
            {
                XmlSerializerOperationBehavior operationBehavior = operation.Behaviors.Find(); 

                if (operationBehavior != null) 
                    return operationBehavior.XmlSerializerFormatAttribute; 
                if (!createNew)
                    return null; 
                operationBehavior = new XmlSerializerOperationBehavior(operation);
                operation.Behaviors.Add(operationBehavior);
                return operationBehavior.XmlSerializerFormatAttribute;
            } 

            internal override void SetOperationStyle(OperationDescription operation, OperationFormatStyle style) 
            { 
                XmlSerializerFormatAttribute operationAttribute = GetFormatAttribute(operation, true/*createNew*/);
                operationAttribute.Style = style; 
            }

            internal override bool GetOperationIsEncoded(OperationDescription operation)
            { 
                XmlSerializerFormatAttribute operationAttribute = GetFormatAttribute(operation, false /*createNew*/);
                if (operationAttribute == null) 
                    return TypeLoader.DefaultXmlSerializerFormatAttribute.IsEncoded; 
                return operationAttribute.IsEncoded;
            } 

            internal override void SetOperationIsEncoded(OperationDescription operation, bool isEncoded)
            {
                XmlSerializerFormatAttribute operationAttribute = GetFormatAttribute(operation, true/*createNew*/); 
                operationAttribute.IsEncoded = isEncoded;
            } 
 
            internal override void SetOperationSupportFaults(OperationDescription operation, bool supportFaults)
            { 
                XmlSerializerFormatAttribute operationAttribute = GetFormatAttribute(operation, true/*createNew*/);
                operationAttribute.SupportFaults = supportFaults;
            }
 
            internal override string GetFormatName()
            { 
                return "XmlSerializer"; 
            }
        } 

        class OperationInfo
        {
            OperationFormatStyle style; 
            bool isEncoded;
            bool areAllMessagesWrapped; 
 
            internal OperationInfo(OperationFormatStyle style, bool isEncoded, bool areAllMessagesWrapped)
            { 
                this.style = style;
                this.isEncoded = isEncoded;
                this.areAllMessagesWrapped = areAllMessagesWrapped;
            } 
            internal OperationFormatStyle Style { get { return style; } }
            internal bool IsEncoded { get { return isEncoded; } } 
            internal bool AreAllMessagesWrapped { get { return areAllMessagesWrapped; } } 
        }
    } 

    internal delegate void WsdlWarningHandler(string warning);

    static class ValidWsdl 
    {
        internal static bool Check(WsdlNS.SoapHeaderBinding soapHeaderBinding, WsdlNS.MessageBinding messageBinding, WsdlWarningHandler warningHandler) 
        { 
            if (soapHeaderBinding.Message == null || soapHeaderBinding.Message.IsEmpty)
            { 
                string reason = SR.GetString(SR.XsdMissingRequiredAttribute1, "message");
                string warning = SR.GetString(SR.IgnoreSoapHeaderBinding3, messageBinding.OperationBinding.Name, messageBinding.OperationBinding.Binding.ServiceDescription.TargetNamespace, reason);
                warningHandler(warning);
                return false; 
            }
 
            if (string.IsNullOrEmpty(soapHeaderBinding.Part)) 
            {
                string reason = SR.GetString(SR.XsdMissingRequiredAttribute1, "part"); 
                string warning = SR.GetString(SR.IgnoreSoapHeaderBinding3, messageBinding.OperationBinding.Name, messageBinding.OperationBinding.Binding.ServiceDescription.TargetNamespace, reason);
                warningHandler(warning);
                return false;
            } 
            return true;
        } 
 
        internal static bool Check(WsdlNS.SoapFaultBinding soapFaultBinding, WsdlNS.FaultBinding faultBinding, WsdlWarningHandler warningHandler)
        { 
            if (string.IsNullOrEmpty(soapFaultBinding.Name))
            {
                string reason = SR.GetString(SR.XsdMissingRequiredAttribute1, "name");
                string warning = SR.GetString(SR.IgnoreSoapFaultBinding3, faultBinding.OperationBinding.Name, faultBinding.OperationBinding.Binding.ServiceDescription.TargetNamespace, reason); 
                warningHandler(warning);
                return false; 
            } 
            return true;
        } 

        internal static bool Check(WsdlNS.MessagePart part, WsdlNS.Message message, WsdlWarningHandler warningHandler)
        {
            // check required name attribute, do not check NCName validity 
            if (string.IsNullOrEmpty(part.Name))
            { 
                string reason = SR.GetString(SR.XsdMissingRequiredAttribute1, "name"); 
                string warning = SR.GetString(SR.IgnoreMessagePart3, message.Name, message.ServiceDescription.TargetNamespace, reason);
                warningHandler(warning); 
                return false;
            }
            return true;
        } 
    }
} 

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