File: metadata\wsdlparser.cs
Project: ndp\clr\src\managedlibraries\remoting\System.Runtime.Remoting.csproj (System.Runtime.Remoting)
// ==++==
// 
//   Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// ==--==
//============================================================
//
// File:    WsdlParser.cs
//<EMAIL>
// Author:  Peter de Jong (Microsoft)
//</EMAIL>
// Purpose: Defines WsdlParser that parses a given WSDL document
//          and generates types defined in it.
//
// Date:    November 15, 2000
//
//============================================================
namespace System.Runtime.Remoting.MetadataServices
{
    using System;
    using System.Threading;
    using System.Collections;
    using System.Reflection;
    using System.Xml;
    using System.Diagnostics;
    using System.IO;
    using System.Text;
    using System.Net;
    using System.Runtime.Remoting.Channels; // This is so we can get the resource strings.
    using System.Runtime.Remoting;
    using System.Globalization;
 
    // This class parses SUDS documents
    internal class WsdlParser
    {
 
        // Main parser
        internal WsdlParser(TextReader input, String outputDir, ArrayList outCodeStreamList, String locationURL, bool bWrappedProxy, String proxyNamespace)
        {
            Util.Log("WsdlParser.WsdlParser outputDir "+outputDir+" locationURL "+locationURL+" bWrappedProxy "+bWrappedProxy+" proxyNamespace "+proxyNamespace);
            // Initialize member variables
            _XMLReader = null;
            _readerStreamsWsdl = new ReaderStream(locationURL);
            _readerStreamsWsdl.InputStream = input;
            _writerStreams = null;
            _outputDir = outputDir;
            _outCodeStreamList = outCodeStreamList;
            _bWrappedProxy = bWrappedProxy;
            if (proxyNamespace == null || proxyNamespace.Length == 0)
                _proxyNamespace = "InteropNS";
            else
                _proxyNamespace = proxyNamespace;
            if (outputDir == null)
                outputDir = ".";
 
            int length = outputDir.Length;
            if (length > 0)
            {
                char endChar = outputDir[length-1];
                if (endChar != '\\' && endChar != '/')
                    _outputDir = _outputDir + '\\';
            }
            //_namespaceStack = null;
            _URTNamespaces = new ArrayList();
            _blockDefault = SchemaBlockType.ALL;
            _primedNametable = CreatePrimedNametable();
            
        }
 
        internal String SchemaNamespaceString
        {
            get
            { 
                String schemaStr = null;
                switch (_xsdVersion)
                {
                case XsdVersion.V1999:
                    schemaStr = s_schemaNamespaceString1999;
                    break;
                case XsdVersion.V2000:
                    schemaStr = s_schemaNamespaceString2000;
                    break;
                case XsdVersion.V2001:
                    schemaStr = s_schemaNamespaceString;
                    break;
                }
                return schemaStr;
            }
        }
 
        internal String ProxyNamespace
        {
            get {return _proxyNamespace;}
        }
 
        internal int ProxyNamespaceCount
        {
            get {return _proxyNamespaceCount;}
            set {_proxyNamespaceCount = value;}
        }
 
        internal XmlTextReader XMLReader
        {
            get {return _XMLReader;}
        }
 
        // Skips past endtags and non content tags
        private bool SkipXmlElement()
        {
            Util.Log("WsdlParser.SkipXmlElement");          
            //PrintNode(Console.Out);
            _XMLReader.Skip();
            XmlNodeType nodeType = _XMLReader.MoveToContent();
            while (nodeType == XmlNodeType.EndElement)
            {
                _XMLReader.Read();
                nodeType = _XMLReader.MoveToContent();
                if (nodeType == XmlNodeType.None)
                    break;
            }
 
            return(nodeType != XmlNodeType.None);
        }
 
        // Reads past endtags and non content tags
        private bool ReadNextXmlElement()
        {
            Util.Log("WsdlParser.ReadNextXmlElement");                      
            _XMLReader.Read();
            XmlNodeType nodeType = _XMLReader.MoveToContent();
            while (nodeType == XmlNodeType.EndElement)
            {
                _XMLReader.Read();
                nodeType = _XMLReader.MoveToContent();
                if (nodeType == XmlNodeType.None)
                    break;
            }
 
            //PrintNode(Console.Out);
            return(nodeType != XmlNodeType.None);
        }
 
        // Parses complex types
        private URTComplexType ParseComplexType(URTNamespace parsingNamespace, String typeName)
        {
            Util.Log("WsdlParser.ParseComplexType NS "+parsingNamespace.Name+" typeName "+typeName);                                 
            // Lookup the name of the type and the base type from which it derives
            if (typeName == null)
                typeName = LookupAttribute(s_nameString, null, true);
 
            URTNamespace xns = null;
            String typeNS = ParseQName(ref typeName, parsingNamespace, out xns);            
 
            Util.Log("WsdlParser.ParseComplexType actualNS 1 "+xns);
            Util.Log("WsdlParser.ParseComplexType actualNS 2 "+xns.Name);
            URTComplexType parsingComplexType = xns.LookupComplexType(typeName);
            if (parsingComplexType == null)
            {
                parsingComplexType = new URTComplexType(typeName, xns.Name, xns.Namespace,
                                                        xns.EncodedNS, _blockDefault,
                                                        false, typeName != null, this, xns);
                xns.AddComplexType(parsingComplexType);
            }
 
            String baseType = LookupAttribute(s_baseString, null, false);
 
            if (!MatchingStrings(baseType, s_emptyString))
            {
                String baseNS = ParseQName(ref baseType, parsingNamespace);
                parsingComplexType.Extends(baseType, baseNS);
            }
 
            if (parsingComplexType.Fields.Count > 0)
            {
                SkipXmlElement();
            }
            else
            {
                int curDepth = _XMLReader.Depth;
                ReadNextXmlElement();
 
                int fieldNum = 0;
                String elementName;
                while (_XMLReader.Depth > curDepth)
                {
                    elementName = _XMLReader.LocalName;
                    if (MatchingStrings(elementName, s_elementString))
                    {
                        ParseElementField(xns, parsingComplexType, fieldNum);
                        ++fieldNum;
                        continue;
                    }
                    else if (MatchingStrings(elementName, s_attributeString))
                    {
                        ParseAttributeField(xns, parsingComplexType);
                        continue;
                    }
                    else if (MatchingStrings(elementName, s_allString))
                    {
                        parsingComplexType.BlockType = SchemaBlockType.ALL;
                    }
                    else if (MatchingStrings(elementName, s_sequenceString))
                    {
                        parsingComplexType.BlockType = SchemaBlockType.SEQUENCE;
                    }
                    else if (MatchingStrings(elementName, s_choiceString))
                    {
                        parsingComplexType.BlockType = SchemaBlockType.CHOICE;
                    }
                    else if (MatchingStrings(elementName, s_complexContentString))
                    {
                        parsingComplexType.BlockType = SchemaBlockType.ComplexContent; 
                    }
                    else if (MatchingStrings(elementName, s_restrictionString))
                    {
                        ParseRestrictionField(xns, parsingComplexType);
                        //++fieldNum;
                        continue;
                    }
                    else
                    {
                        // Ignore others elements such as annotations
                        SkipXmlElement();
                        continue;
                    }
 
                    // Read next element
                    ReadNextXmlElement();
                }
            }
 
            return(parsingComplexType);
        }
 
        // Parses simple types
        private URTSimpleType ParseSimpleType(URTNamespace parsingNamespace, String typeName)
        {
            Util.Log("WsdlParser.ParseSimpleType NS "+parsingNamespace+" typeName "+typeName);                                              
            // Lookup the name of the type and the base type from which it derives
            if (typeName == null)
                typeName = LookupAttribute(s_nameString, null, true);
            String enumType = LookupAttribute(s_enumTypeString, s_wsdlSudsNamespaceString, false);
            URTSimpleType parsingSimpleType = parsingNamespace.LookupSimpleType(typeName);
            if (parsingSimpleType == null)
            {
                parsingSimpleType = new URTSimpleType(typeName, parsingNamespace.Name, parsingNamespace.Namespace,
                                                      parsingNamespace.EncodedNS, typeName != null, this);
                String baseType = LookupAttribute(s_baseString, null, false);
                if (!MatchingStrings(baseType, s_emptyString))
                {
                    String baseNS = ParseQName(ref baseType, parsingNamespace);
                    parsingSimpleType.Extends(baseType, baseNS);
                }
                parsingNamespace.AddSimpleType(parsingSimpleType);
 
                int curDepth = _XMLReader.Depth;
                ReadNextXmlElement();
 
                //int enumFacetNum = 0;
                string elementName;
                while (_XMLReader.Depth > curDepth)
                {
                    elementName = _XMLReader.LocalName;
 
                    if (MatchingStrings(elementName, s_restrictionString))
                    {
                        ParseRestrictionField(parsingNamespace, parsingSimpleType);
                    }
                    /*
                    else if (MatchingStrings(elementName, s_encodingString))
                    {
                        ParseEncoding(parsingSimpleType);
                    }
                    */
                    else
                    {
                        SkipXmlElement();
                    }
                }
            }
            else
            {
                SkipXmlElement();
            }
            if (enumType != null)
                parsingSimpleType.EnumType = enumType;
 
            return(parsingSimpleType);
        }
 
        /*
        // Parses encoding
        private void ParseEncoding(URTSimpleType parsingSimpleType)
        {
            Util.Log("WsdlParser.ParseEncoding URTSimpleType "+parsingSimpleType);                                              
            if (_XMLReader.IsEmptyElement == true)
            {
                // Get the encoding value
                String valueString = LookupAttribute(s_valueString, null, true);
                parsingSimpleType.Encoding = valueString;
            }
            else
            {
                throw new SUDSParserException(
                                             CoreChannel.GetResourceString("Remoting_Suds_EncodingMustBeEmpty"));
            }
 
            ReadNextXmlElement();
            return;
        }
        */
 
        // Parses enumeration
        private void ParseEnumeration(URTSimpleType parsingSimpleType, int enumFacetNum)
        {
            Util.Log("WsdlParser.ParseEnumeration facitNum "+enumFacetNum);
            if (_XMLReader.IsEmptyElement == true)
            {
                // Get the enum value
                String valueString = LookupAttribute(s_valueString, null, true);
                parsingSimpleType.IsEnum = true;
                parsingSimpleType.AddFacet(new EnumFacet(valueString, enumFacetNum));
            }
            else
            {
                throw new SUDSParserException(
                                             CoreChannel.GetResourceString("Remoting_Suds_EnumMustBeEmpty"));
            }
            return;
        }
 
 
        // Parses element fields
        private void ParseElementField(URTNamespace parsingNamespace,
                                       URTComplexType parsingComplexType,
                                       int fieldNum)
        {
            Util.Log("WsdlParser.ParseElementField NS "+parsingNamespace+" fieldNum "+fieldNum);            
            // Determine the field name
            String fieldTypeName, fieldTypeXmlNS;
            String fieldName = LookupAttribute(s_nameString, null, true);
 
            // Look for array bounds
            String minOccurs = LookupAttribute(s_minOccursString, null, false);
            String maxOccurs = LookupAttribute(s_maxOccursString, null, false);
 
            // Check if the field is optional
            bool bOptional = false;
            if (MatchingStrings(minOccurs, s_zeroString))
                bOptional = true;
 
            // Check if the field is an inline array
            bool bArray = false;
            String arraySize = null;
            if (!MatchingStrings(maxOccurs, s_emptyString) &&
                !MatchingStrings(maxOccurs, s_oneString))
            {
                if (MatchingStrings(maxOccurs, s_unboundedString))
                    arraySize = String.Empty;
                else
                    arraySize = maxOccurs;
                bArray = true;
            }
 
            // Handle anonymous types
            bool bEmbedded, bPrimitive;
            if (_XMLReader.IsEmptyElement == true)
            {
                // Non-anonymous type case
                fieldTypeName = LookupAttribute(s_typeString, null, false);
 
                // Handle the absense of type attribute (Object case)
                ResolveTypeAttribute(ref fieldTypeName, out fieldTypeXmlNS,
                                     out bEmbedded, out bPrimitive);
 
                // Read next element
                ReadNextXmlElement();
            }
            else
            {
                // Anonymous type case
                fieldTypeXmlNS = parsingNamespace.Namespace;
                fieldTypeName = parsingNamespace.GetNextAnonymousName();
                bPrimitive = false;
                bEmbedded = true;
                int curDepth = _XMLReader.Depth;
                ReadNextXmlElement();
 
                // Parse the type
                String elementName;
                while (_XMLReader.Depth > curDepth)
                {
                    elementName = _XMLReader.LocalName;
                    if (MatchingStrings(elementName, s_complexTypeString))
                    {
                        URTComplexType complexType = ParseComplexType(parsingNamespace, fieldTypeName);
                        if (complexType.IsEmittableFieldType)
                        {
                            fieldTypeXmlNS = complexType.FieldNamespace;
                            fieldTypeName = complexType.FieldName;
                            bPrimitive = complexType.PrimitiveField;
                            parsingNamespace.RemoveComplexType(complexType);
                        }
                    }
                    else if (MatchingStrings(elementName, s_simpleTypeString))
                    {
                        URTSimpleType simpleType = ParseSimpleType(parsingNamespace, fieldTypeName);
                        if (simpleType.IsEmittableFieldType)
                        {
                            fieldTypeXmlNS = simpleType.FieldNamespace;
                            fieldTypeName = simpleType.FieldName;
                            bPrimitive = simpleType.PrimitiveField;
                            parsingNamespace.RemoveSimpleType(simpleType);
                        }
                    }
                    else
                    {
                        // Ignore others elements such as annotations
                        SkipXmlElement();
                    }
                }
            }
 
            // Add field to the type being parsed
            parsingComplexType.AddField(new URTField(fieldName, fieldTypeName, fieldTypeXmlNS,
                                                     this, bPrimitive, bEmbedded, false,
                                                     bOptional, bArray, arraySize, parsingNamespace));
            return;
        }
 
        // Parses attribute fields
        private void ParseAttributeField(URTNamespace parsingNamespace,
                                         URTComplexType parsingComplexType)
        {
            Util.Log("WsdlParser.ParseAttributeField NS "+parsingNamespace);
            // Lookup field name
            String attrTypeName, attrTypeNS;
            String attrName = LookupAttribute(s_nameString, null, true);
 
            // Check if the field is optional
            bool bOptional = false;
            String minOccurs = LookupAttribute(s_minOccursString, null, false);
            if (MatchingStrings(minOccurs, s_zeroString))
                bOptional = true;
 
            // Handle anonymous types
            bool bEmbedded, bPrimitive;
            if (_XMLReader.IsEmptyElement == true)
            {
                // Non-anonymous type case and type has to present
                attrTypeName = LookupAttribute(s_typeString, null, true);
                ResolveTypeAttribute(ref attrTypeName, out attrTypeNS,
                                     out bEmbedded, out bPrimitive);
 
                // Read next element
                ReadNextXmlElement();
 
                // Check for xsd:ID type
                if (MatchingStrings(attrTypeName, s_idString) &&
                    MatchingSchemaStrings(attrTypeNS))
                {
                    parsingComplexType.IsStruct = false;
                    return;
                }
            }
            else
            {
                // Anonymous type case
                attrTypeNS = parsingNamespace.Namespace;
                attrTypeName = parsingNamespace.GetNextAnonymousName();
                bPrimitive = false;
                bEmbedded = true;
                int curDepth = _XMLReader.Depth;
                ReadNextXmlElement();
 
                // Parse the type
                String elementName;
                while (_XMLReader.Depth > curDepth)
                {
                    elementName = _XMLReader.LocalName;
                    if (MatchingStrings(elementName, s_simpleTypeString))
                    {
                        URTSimpleType simpleType = ParseSimpleType(parsingNamespace, attrTypeName);
                        if (simpleType.IsEmittableFieldType)
                        {
                            attrTypeNS = simpleType.FieldNamespace;
                            attrTypeName = simpleType.FieldName;
                            bPrimitive = simpleType.PrimitiveField;
                            parsingNamespace.RemoveSimpleType(simpleType);
                        }
                    }
                    else
                    {
                        // Ignore others elements such as annotations
                        SkipXmlElement();
                    }
                }
            }
 
            // Add field to the type being parsed
            parsingComplexType.AddField(new URTField(attrName, attrTypeName, attrTypeNS,
                                                     this, bPrimitive, bEmbedded, true,
                                                     bOptional, false, null, parsingNamespace));
            return;
        }
 
 
        // Parses RestrictionField fields
        // Now only set up to recognize arrays
        private void ParseRestrictionField(URTNamespace parsingNamespace,
                                           BaseType parsingType)
        {
            Util.Log("WsdlParser.ParseRestrictionField Enter NS "+parsingNamespace+" type "+parsingType);
            // Lookup field name
 
            String attrName = LookupAttribute(s_baseString, null, true);
            String baseNS = ParseQName(ref attrName, parsingNamespace);
            //if (MatchingStrings(baseNS, s_soapEncodingString) && MatchingStrings(attrName, s_arrayString))
            {
                int curDepth = _XMLReader.Depth;
                ReadNextXmlElement();
 
                // Parse the type
                String elementName;
                String arrayNS;
                String arrayType;
                int enumFacetNum = 0;
                while (_XMLReader.Depth > curDepth)
                {
                    elementName = _XMLReader.LocalName;
                    Util.Log("WsdlParser.ParseRestrictionField elementName "+elementName);
                    if (MatchingStrings(elementName, s_attributeString))
                    {
                        String refValue = LookupAttribute(s_refString, null, true);
                        String refNS = ParseQName(ref refValue, parsingNamespace);
                        if (MatchingStrings(refNS, s_soapEncodingString) && MatchingStrings(refValue, s_arrayTypeString))
                        {
                            URTComplexType parsingComplexType = (URTComplexType)parsingType;
                            arrayType = LookupAttribute(s_arrayTypeString, s_wsdlNamespaceString, true);
                            Util.Log("WsdlParser.ParseRestrictionField arrayType "+arrayType);
                            URTNamespace arrayNamespace = null;
                            arrayNS = ParseQName(ref arrayType, null, out arrayNamespace);
 
                            parsingComplexType.AddArray(arrayType, arrayNamespace);
                            //Add array to the array namespace
                            arrayNamespace.AddComplexType(parsingComplexType); 
                            parsingComplexType.IsPrint = false;
                        }
                    }
                    else if (MatchingStrings(elementName, s_enumerationString))
                    {
                        URTSimpleType parsingSimpleType = (URTSimpleType)parsingType;
                        ParseEnumeration(parsingSimpleType, enumFacetNum);
                        ++enumFacetNum;
                    }
                    else
                    {
                        // Ignore others elements such as annotations
                        SkipXmlElement();
                    }
                    ReadNextXmlElement();
                }
            }
            // else
            // SkipXmlElement();
 
            Util.Log("WsdlParser.ParseRestrictionField Exit NS "+parsingNamespace+" type "+parsingType);
            return;
        }
 
 
        // Parses a global element declaration
        private void ParseElementDecl(URTNamespace parsingNamespace)
        {
            Util.Log("WsdlParser.ParseElementDecl");            
            // Obtain element name and its type
            String elmName = LookupAttribute(s_nameString, null, true);
            String elmNS = parsingNamespace.Name;
            String typeName = LookupAttribute(s_typeString, null, false);
 
            // Handle the anonymous types
            String typeNS;
            bool bEmbedded, bPrimitive;
            if (_XMLReader.IsEmptyElement == true)
            {
                // Non-anonymous type case
                // We cannot assert that the type attribute must have been present
                // due to the Object/ur-type case
                ResolveTypeAttribute(ref typeName, out typeNS, out bEmbedded, out bPrimitive);
 
                // Position to the next element
                ReadNextXmlElement();
            }
            else
            {
                // Anonymous type case
                typeNS = parsingNamespace.Name;
                typeName = parsingNamespace.GetNextAnonymousName();
                bEmbedded = true;
                bPrimitive = false;
 
                // Parse the type
                int curDepth = _XMLReader.Depth;
                ReadNextXmlElement();
                String elementName;
                while (_XMLReader.Depth > curDepth)
                {
                    elementName = _XMLReader.LocalName;
                    if (MatchingStrings(elementName, s_complexTypeString))
                    {
                        ParseComplexType(parsingNamespace, typeName);
                    }
                    else if (MatchingStrings(elementName, s_simpleTypeString))
                    {
                        ParseSimpleType(parsingNamespace, typeName);
                    }
                    else
                    {
                        // Ignore others elements such as annotations
                        SkipXmlElement();
                    }
                }
            }
 
            // Create a new global element under the current namespace
            parsingNamespace.AddElementDecl(new ElementDecl(elmName, elmNS, typeName, typeNS,
                                                            bPrimitive));
 
            return;
        }
 
        // Checks for reference and array types and resolves to
        // actual types. It returns true if the type needs [Embedded] attribute
        private void ResolveTypeNames(ref String typeNS, ref String typeName,
                                      out bool bEmbedded, out bool bPrimitive)
        {
            Util.Log("WsdlParser.ResolveTypeNames typeNS "+typeNS+" typeName "+typeName);           
            // Check for reference and array types
            bEmbedded = true;
            bool bArrayType = false;
            if (MatchingStrings(typeNS, s_wsdlSoapNamespaceString))
            {
                if (MatchingStrings(typeName, s_referenceString))
                    bEmbedded = false;
                else if (MatchingStrings(typeName, s_arrayString))
                    bArrayType = true;
            }
 
            Util.Log("WsdlParser.ResolveTypeNames typeNS 1 bEmbedded "+bEmbedded+" bArrayType "+bArrayType);
            // Resolve to the actual type in the case of reference and array types
            if ((bEmbedded == false) || (bArrayType == true))
            {
                typeName = LookupAttribute(s_refTypeString, s_wsdlSudsNamespaceString, true);
                typeNS = ParseQName(ref typeName);
            }
 
            // Primitive types do not need the [Embedded] attribute;
            bPrimitive = IsPrimitiveType(typeNS, typeName);
            if (bPrimitive)
            {
                typeName = MapSchemaTypesToCSharpTypes(typeName);
                bEmbedded = false;
            }
            else if (MatchingStrings(typeName, s_urTypeString) &&
                     MatchingSchemaStrings(typeNS))
            {
                typeName = s_objectString;
            }
 
            return;
        }
 
        // Parses namespace declaration elements
        private URTNamespace ParseNamespace()
        {
            Util.Log("WsdlParser.ParseNamespace");          
            // Determine the new namespace encountered
            String name = (String) LookupAttribute(s_targetNamespaceString, null, false);
            bool bUnique = false;
            if (MatchingStrings(name, s_emptyString) &&
                MatchingStrings(_XMLReader.LocalName, s_sudsString) &&
                _parsingInput.UniqueNS == null)
            {
                name = _parsingInput.TargetNS;
                bUnique = true;
            }
 
            // Add the namespace being parsed to the list if neccessary
            URTNamespace parsingNamespace = LookupNamespace(name);
            if (parsingNamespace == null)
            {
                parsingNamespace = new URTNamespace(name, this);
            }
            if (bUnique)
                _parsingInput.UniqueNS = parsingNamespace;
            //_namespaceStack = NamespaceStack.Push(_namespaceStack, _parsingNamespace, _XMLReader.Depth);
 
            // Parse schema defaults
            //if(MatchingStrings(_XMLReader.LocalName, s_sudsString))
            //{
 
            //}
 
            // Read the next record
            ReadNextXmlElement();
 
            return(parsingNamespace);
        }
 
#if false
        private void AddToNamespace(String name)
        {
        URTNamespace parsingNamespace = LookupNamespace(name);
        if(parsingNamespace == null)
        {
        parsingNamespace = new URTNamespace(name, this);
        _URTNamespaces.Add(parsingNamespace);
        }
        }
#endif
 
        private void ParseReaderStreamLocation(ReaderStream reader, ReaderStream currentReaderStream)
        {
            Util.Log("WsdlParser.ParseReaderStreamLocation location "+reader.Location+" current location "+currentReaderStream.Location);           
            String location = reader.Location;
            int index = location.IndexOf(':');
            if (index == -1)
            {
                // relative path
                if (currentReaderStream == null || currentReaderStream.Location == null)
                    throw new SUDSParserException(String.Format(CultureInfo.CurrentCulture, CoreChannel.GetResourceString("Remoting_Suds_Import"), reader.Location));
 
                if (currentReaderStream.Uri == null)
                    currentReaderStream.Uri= new Uri(currentReaderStream.Location); // If relative path, will already be changed to absolute path by next statement in previous invocation.
                Uri uri = new Uri(currentReaderStream.Uri, location);
                reader.Uri= uri;
                location = uri.ToString();
                index = location.IndexOf(':');
                if (index == -1)
                    return;
                reader.Location= location;
            }
            
            String protocol = location.Substring(0, index).ToLower(CultureInfo.InvariantCulture);
            String value = location.Substring(index+1);
            if (protocol == "file")
            {
                //Console.WriteLine("Loading file:" + value);
                reader.InputStream = new StreamReader(value);
            }
            else if (protocol.StartsWith("http", StringComparison.Ordinal))
            {
                Util.Log("WsdlParser.ParseReaderStreamLocation http "+location);            
                WebRequest request = WebRequest.Create(location);
                WebResponse response = request.GetResponse();
                Stream responseStream = response.GetResponseStream();
                reader.InputStream = new StreamReader(responseStream);
            }
        }
            
        private void ParseImport()
        {
            Util.Log("WsdlParser.ParseImport");         
            String ns = LookupAttribute(s_namespaceString, null, true);
            String location = null;
            location = LookupAttribute(s_locationString, null, false); //wsdl
 
            Util.Log("WsdlParser.ParseImport "+ns+" location "+location);         
            if (location != null && location.Length > 0)
            {
                ReaderStream reader = new ReaderStream(location);
                ParseReaderStreamLocation(reader, (ReaderStream)_currentReaderStack.Peek());
                ReaderStream.GetReaderStream(_readerStreamsWsdl, reader);
            }
            ReadNextXmlElement();
            return;
        }
 
        internal void Parse()
        {
            Util.Log("WsdlParser.Parse");                       
            //XmlNameTable primedNametable = CreatePrimedNametable();
            ReaderStream input = _readerStreamsWsdl;
            do
            {
                // Initialize the parser
                _XMLReader = new XmlTextReader(input.InputStream, _primedNametable) { DtdProcessing = DtdProcessing.Ignore };
                _XMLReader.WhitespaceHandling = WhitespaceHandling.None;
                _XMLReader.XmlResolver = null;
                ParseInput(input);
                input = ReaderStream.GetNextReaderStream(input);
            } while (input != null);
 
            StartWsdlResolution();
 
            if (null != _writerStreams)
            {
                WriterStream.Close(_writerStreams);
            }
 
            return;
        }
 
        // Starts the parser
        private void ParseInput(ReaderStream input)
        {
            Util.Log("WsdlParser.ParseInput" + input.Location);                                  
            _parsingInput = input;
            try
            {
                ReadNextXmlElement();
                String elementName = _XMLReader.LocalName;
                if (MatchingNamespace(s_wsdlNamespaceString) && MatchingStrings(elementName, s_definitionsString))
                {
                    Util.Log("WsdlParser.ParseInput before ParseWsdl "+input.Location);
                    _currentReaderStack.Push(input); // need this to get the base url for relative import elements.
                    ParseWsdl();
                    _currentReaderStack.Pop(); // need this to get the base url for relative import elements.
                }
                else if (MatchingNamespace(s_wsdlNamespaceString) && MatchingStrings(elementName, s_typesString))
                {
                    Util.Log("WsdlParser.ParseInput before ParseWsdlTypes "+input.Location);
                    _currentReaderStack.Push(input); // need this to get the base url for relative import elements.
                    ParseWsdlTypes();
                    _currentReaderStack.Pop(); // need this to get the base url for relative import elements.
                }
 
                else if (MatchingSchemaNamespace() && MatchingStrings(elementName, s_schemaString))
                {
                    Util.Log("WsdlParser.ParseInput before ParseWsdl "+input.Location);
                    _currentReaderStack.Push(input); // need this to get the base url for relative import elements.
                    ParseSchema();
                    _currentReaderStack.Pop(); // need this to get the base url for relative import elements.
                }
                else
                    throw new SUDSParserException(String.Format(CultureInfo.CurrentCulture, CoreChannel.GetResourceString("Remoting_Suds_UnknownElementAtRootLevel"), elementName));
            }
            finally
            {
                WriterStream.Flush(_writerStreams);
            }
        }
 
        private void ParseWsdl()
        {
            Util.Log("WsdlParser.ParseWsdl elementName "+_XMLReader.LocalName+" namespace "+ _XMLReader.NamespaceURI);
            int curDepth = _XMLReader.Depth;            
            _parsingInput.Name = LookupAttribute(s_nameString, null, false);
            _parsingInput.TargetNS = LookupAttribute(s_targetNamespaceString, null, false);
 
            URTNamespace parsingNamespace = ParseNamespace();           
 
            //ReadNextXmlElement();
            while (_XMLReader.Depth > curDepth)
            {
                String elementName = _XMLReader.LocalName;
                Util.Log("WsdlParser.ParseWsdl Loop "+_XMLReader.LocalName);
                if (MatchingNamespace(s_wsdlNamespaceString))
                {
                    if (MatchingStrings(elementName,s_typesString))
                    {
                        ParseWsdlTypes();
                        continue;
                    }
                    else if (MatchingStrings(elementName,s_messageString))
                    {
                        ParseWsdlMessage();
                        continue;
                    }
                    else if (MatchingStrings(elementName,s_portTypeString))
                    {
                        ParseWsdlPortType();
                        continue;
                    }
                    else if (MatchingStrings(elementName,s_bindingString))
                    {
                        ParseWsdlBinding(parsingNamespace);
                        continue;
                    }
                    else if (MatchingStrings(elementName,s_serviceString))
                    {
                        ParseWsdlService();
                        continue;
                    }
                    else if (MatchingStrings(elementName, s_importString))
                    {
                        ParseImport();
                        continue;
                    }
                }
                // Ignore others elements such as annotations
                SkipXmlElement();
            }
 
            
        }
 
        private void StartWsdlResolution()
        {
            Util.Log("WsdlParser.StartWsdlResolution ");                                  
            DumpWsdl();
            ResolveWsdl();
            Resolve();
            PruneNamespaces();
            Util.Log("WsdlParser.ParseWsdl Invoke PrintCSC");                       
            PrintCSC();
        }
        
        // Since the Wsdl can contains binding sections which are not Rcp,Soap, Encoded. Prune the namespaces from messages etc
        // which are not directly referenced by the Soap binding sections.
        private void PruneNamespaces()
        {
            Util.Log("WsdlParser.PruneNamespaces");       
            ArrayList tempList = new ArrayList(10);
            for (int i=0;i<_URTNamespaces.Count;i++)
            {
                URTNamespace urtNS = (URTNamespace) _URTNamespaces[i];
                if (urtNS.bReferenced)
                    tempList.Add(urtNS);
            }
 
            _URTNamespaces = tempList;
        }
 
        [System.Diagnostics.Conditional("_LOGGING")]        
        private void DumpWsdl()
        {
            foreach (DictionaryEntry d in wsdlMessages)
            ((IDump)d.Value).Dump();
            foreach (DictionaryEntry d in wsdlPortTypes)
            ((IDump)d.Value).Dump();                    
            foreach (WsdlBinding item in wsdlBindings)
            item.Dump();
            foreach (WsdlService item in wsdlServices)
            item.Dump();            
        }
 
        private void ParseWsdlTypes()
        {
            Util.Log("WsdlParser.ParseWsdlTypes");                                              
            int curDepth = _XMLReader.Depth;
            ReadNextXmlElement();               
            
            // Initialize mechanism to support xsd import statements;
            _currentSchemaReaderStack.Push(_currentReaderStack.Peek()); // put current wsdl location as xsd location
            
            while (_XMLReader.Depth > curDepth)
            {
                String elementName = _XMLReader.LocalName;
                if (MatchingSchemaNamespace())
                {
                    if (MatchingStrings(elementName, s_schemaString))
                    {
                        ParseSchema();
                        if (_readerStreamsXsd != null)
                        {
                            // import element appeared in schema
                            ParseImportedSchemaController();
                        }
 
                        continue;
                    }
                }
 
                // Ignore others elements such as annotations
                SkipXmlElement();
            }
            _currentSchemaReaderStack.Pop();
        }
 
 
        private void ParseSchemaIncludeElement()
        {
            ParseSchemaImportElement(false);
        }
 
        private void ParseSchemaImportElement()
        {
            ParseSchemaImportElement(true);
        }
 
 
        // Processes an import statement in an xsd schema.
        private void ParseSchemaImportElement(bool bImport)
        { 
            Util.Log("WsdlParser.ParseSchemaImportElement IsImport "+bImport);         
            String ns = null;
            if (bImport)
                ns = LookupAttribute(s_namespaceString, null, true);
            String location = null;
            location = LookupAttribute(s_schemaLocationString, null, false);
 
            Util.Log("WsdlParser.ParseSchemaImportElement "+ns+" location "+location);         
            if (location != null && location.Length > 0)
            {
                if (_readerStreamsXsd == null)
                {
                _readerStreamsXsd = new ReaderStream(location);
                ParseReaderStreamLocation(_readerStreamsXsd, (ReaderStream)_currentSchemaReaderStack.Peek()); 
                }
                else
                {
                    ReaderStream reader = new ReaderStream(location);
                    ParseReaderStreamLocation(reader, (ReaderStream)_currentSchemaReaderStack.Peek());
                    ReaderStream.GetReaderStream(_readerStreamsWsdl, reader);
                }
            }
            ReadNextXmlElement();
            return;
        }
 
        // Controls the processing of the imported xsd schema.
        internal void ParseImportedSchemaController()
        {
            Util.Log("WsdlParser.ParseImportedSchemaController");  
            XmlNameTable primedNametable = CreatePrimedNametable();
            ReaderStream input = _readerStreamsXsd;
            XmlTextReader _XMLReaderWsdl = _XMLReader;
            ReaderStream _parsingInputWsdl = _parsingInput;
            do
            {
                // Initialize the parser
                _XMLReader = new XmlTextReader(input.InputStream, _primedNametable) { DtdProcessing = DtdProcessing.Ignore };
                _XMLReader.WhitespaceHandling = WhitespaceHandling.None;
                _XMLReader.XmlResolver = null;
                _parsingInput = input;
                ParseImportedSchema(input);
                input = ReaderStream.GetNextReaderStream(input);
            } while (input != null);
            _readerStreamsXsd = null;
            _XMLReader = _XMLReaderWsdl;
            _parsingInput = _parsingInputWsdl;
            return;
        }
 
        // Process the xsd schema imported from an xsd import statement
        private void ParseImportedSchema(ReaderStream input)
        {
            Util.Log("WsdlParser.ParseImportedSchema "+input.Location);                                  
            try
            {
                String elementName = _XMLReader.LocalName;
                _currentSchemaReaderStack.Push(input); // need this to get the base url for relative import elements.
                ReadNextXmlElement();               
                ParseSchema();
                _currentSchemaReaderStack.Pop(); // need this to get the base url for relative import elements.
            }
            finally
            {
                WriterStream.Flush(_writerStreams);
            }
        }
 
        private void ParseWsdlMessage()
        {
            Util.Log("WsdlParser.ParseWsdlMessage");
            WsdlMessage message = new WsdlMessage();
            message.name = LookupAttribute(s_nameString, null, true);
            message.nameNs = _parsingInput.TargetNS;
            int curDepth = _XMLReader.Depth; 
            ReadNextXmlElement();               
            while (_XMLReader.Depth > curDepth)
            {
                String elementName = _XMLReader.LocalName;
 
                if (MatchingStrings(elementName, s_partString))
                {
                    WsdlMessagePart part = new WsdlMessagePart();
                    part.name = LookupAttribute(s_nameString, null, true); 
                    part.nameNs = _parsingInput.TargetNS;
                    //AddToNamespace(part.nameNs);//temp
                    part.element = LookupAttribute(s_elementString, null, false);
                    part.typeName = LookupAttribute(s_typeString, null, false);
                    if (part.element != null)
                    {
                        part.elementNs = ParseQName(ref part.element);
                    }
                    if (part.typeName != null)
                    {
                        part.typeNameNs = ParseQName(ref part.typeName); 
                    }
 
                    message.parts.Add(part);
                    ReadNextXmlElement();
                    continue;
                }
 
                // Ignore others elements such as annotations
                SkipXmlElement();
            }
            wsdlMessages[message.name] = message;
        }
 
        private void ParseWsdlPortType()
        {
            Util.Log("WsdlParser.ParseWsdlPortType");
            WsdlPortType portType = new WsdlPortType();
            portType.name = LookupAttribute(s_nameString, null, true);
            //portType.nameNs = ParseQName(ref portType.name);
            int curDepth = _XMLReader.Depth; 
            ReadNextXmlElement();               
            while (_XMLReader.Depth > curDepth)
            {
                String elementName = _XMLReader.LocalName;
 
                if (MatchingStrings(elementName, s_operationString))
                {
                    WsdlPortTypeOperation portTypeOperation = new WsdlPortTypeOperation();
                    portTypeOperation.name = LookupAttribute(s_nameString, null, true);
                    portTypeOperation.nameNs = ParseQName(ref portTypeOperation.nameNs);
                    portTypeOperation.parameterOrder = LookupAttribute(s_parameterOrderString, null, false);
                    ParseWsdlPortTypeOperationContent(portType, portTypeOperation);
                    portType.operations.Add(portTypeOperation);
                    continue;
                }
 
                // Ignore others elements such as annotations
                SkipXmlElement();
            }
            wsdlPortTypes[portType.name] = portType;
        }
 
 
        private void ParseWsdlPortTypeOperationContent(WsdlPortType portType, WsdlPortTypeOperation portTypeOperation)
        { 
            Util.Log("WsdlParser.ParseWsdlPortTypeOperationContent type "+portType.name+" operationName "+portTypeOperation.name);
            int curDepth = _XMLReader.Depth; 
 
            ReadNextXmlElement();               
            while (_XMLReader.Depth > curDepth)
            {
                String elementName = _XMLReader.LocalName;
 
                if (MatchingStrings(elementName, s_inputString))
                {
                    WsdlPortTypeOperationContent portContent = new WsdlPortTypeOperationContent();
                    portContent.element = Atomize("input");
                    portContent.name = LookupAttribute(s_nameString, null, false);
 
                    if (MatchingStrings(portContent.name, s_emptyString))
                    {
                        portContent.name = Atomize(portTypeOperation.name+"Request");
                        if (portType.sections.ContainsKey(portContent.name))
                            throw new SUDSParserException(String.Format(CultureInfo.CurrentCulture, CoreChannel.GetResourceString("Remoting_Suds_DuplicatePortTypesOperationName"), portTypeOperation.name));
 
                        portType.sections[portContent.name] = portTypeOperation; //for request response
                        portType.sections[portTypeOperation.name] = portTypeOperation; // for one way don't know yet if one way or response
                    }
                    else
                    {
                        if (portType.sections.ContainsKey(portContent.name))
                            throw new SUDSParserException(String.Format(CultureInfo.CurrentCulture, CoreChannel.GetResourceString("Remoting_Suds_DuplicatePortSectionName"), portContent.name));
 
 
                        portType.sections[portContent.name] = portTypeOperation;
                    }
 
                    portContent.message = LookupAttribute(s_messageString, null, true);
                    portContent.messageNs = ParseQName(ref portContent.message);
                    portTypeOperation.contents.Add(portContent);
                    ReadNextXmlElement();
                    continue;                   
                }
                else if (MatchingStrings(elementName, s_outputString))
                {
                    WsdlPortTypeOperationContent portContent = new WsdlPortTypeOperationContent();                  
                    portContent.element = Atomize("output");
                    portContent.name = LookupAttribute(s_nameString, null, false);
                    portContent.nameNs = ParseQName(ref portContent.name);
                    if (MatchingStrings(portContent.name, s_emptyString))
                        portContent.name = Atomize(portTypeOperation.name+"Response");
                    if (!portType.sections.ContainsKey(portContent.name))
                        portType.sections[portContent.name] = portTypeOperation;
                    portContent.message = LookupAttribute(s_messageString, null, true);
                    portContent.messageNs = ParseQName(ref portContent.message);
                    portTypeOperation.contents.Add(portContent);                    
                    ReadNextXmlElement();
                    continue;                   
                }
 
                // Ignore others elements such as annotations
                SkipXmlElement();
            }
        }
 
 
        private void ParseWsdlBinding(URTNamespace inparsingNamespace)
        {
            Util.Log("WsdlParser.ParseWsdlBinding");
            WsdlBinding binding = new WsdlBinding();
            binding.name = LookupAttribute(s_nameString, null, true);
            //binding.nameNs = ParseQName(ref binding.name);
            binding.type = LookupAttribute(s_typeString, null, true);
            binding.typeNs = ParseQName(ref binding.type);
            URTNamespace parsingNamespace = LookupNamespace(binding.typeNs);
            if (parsingNamespace == null)
            {
                parsingNamespace = new URTNamespace(binding.typeNs, this); 
            }
            binding.parsingNamespace = parsingNamespace;
            bool bSoapBinding = false;
            bool bRpcBinding = false;
            bool bSoapEncoded = false;
            bool bSoapSuds = false;
            int curDepth = _XMLReader.Depth; 
            ReadNextXmlElement();               
            while (_XMLReader.Depth > curDepth)
            {
                String elementName = _XMLReader.LocalName;
                if (MatchingNamespace(s_wsdlSoapNamespaceString) &&
                    MatchingStrings(elementName, s_bindingString))
                {
                    bSoapBinding = true;
                    WsdlBindingSoapBinding sb = new WsdlBindingSoapBinding();
                    sb.style = LookupAttribute(s_styleString, null, true);
                    if (sb.style == "rpc")
                        bRpcBinding = true;
 
                    /*
                    if (sb.style == "document")
                    {
                        throw new SUDSParserException(
                            String.Format(CoreChannel.GetResourceString("Remoting_Suds_SoapStyleNotSupported"),
                                          sb.style));
                    }
                    */
 
                    sb.transport = LookupAttribute(s_transportString, null, true);
                    binding.soapBinding = sb;
                    ReadNextXmlElement();
                    continue;                   
                }
                else if (MatchingNamespace(s_wsdlSudsNamespaceString))
                {
                    bSoapSuds = true;
                    if (MatchingStrings(elementName, s_classString) || MatchingStrings(elementName, s_structString))
                    {
                        WsdlBindingSuds suds = new WsdlBindingSuds();
                        suds.elementName = elementName;
                        suds.typeName = LookupAttribute(s_typeString, null, true);
                        suds.ns = ParseQName(ref suds.typeName);
                        suds.extendsTypeName = LookupAttribute(s_extendsString, null, false);
                        String use = LookupAttribute(s_rootTypeString, null, false);
                        suds.sudsUse = ProcessSudsUse(use, elementName);
                        if (!MatchingStrings(suds.extendsTypeName, s_emptyString))
                            suds.extendsNs = ParseQName(ref suds.extendsTypeName);
                        ParseWsdlBindingSuds(suds);
                        binding.suds.Add(suds);
                        continue;                       
                    }
                    else if (MatchingStrings(elementName, s_interfaceString))
                    {
                        WsdlBindingSuds suds = new WsdlBindingSuds();                       
                        suds.elementName = elementName; //Atomize("interface");
                        suds.typeName = LookupAttribute(s_typeString, null, true);
                        suds.ns = ParseQName(ref suds.typeName);        
                        String use = LookupAttribute(s_rootTypeString, null, false);
                        suds.sudsUse = ProcessSudsUse(use, elementName);
                        ParseWsdlBindingSuds(suds);
                        binding.suds.Add(suds);
                        continue;                       
                    }
                }
                else if (MatchingNamespace(s_wsdlNamespaceString) &&
                         MatchingStrings(elementName, s_operationString))
                {
                    WsdlBindingOperation op = new WsdlBindingOperation();
                    op.name = LookupAttribute(s_nameString, null, true); 
                    op.nameNs = _parsingInput.TargetNS;
                    ParseWsdlBindingOperation(op, ref bRpcBinding, ref bSoapEncoded);
                    binding.operations.Add(op);
                    continue;                   
                }
 
                // Ignore others elements such as annotations
                SkipXmlElement();
            }
            if (bSoapBinding && bRpcBinding && bSoapEncoded || bSoapSuds)
                wsdlBindings.Add(binding);
        }
 
        private void ParseWsdlBindingSuds(WsdlBindingSuds suds)
        {
            Util.Log("WsdlParser.ParseWsdlBindingSuds");            
            int curDepth = _XMLReader.Depth; 
            ReadNextXmlElement();               
            while (_XMLReader.Depth > curDepth)
            {
                String elementName = _XMLReader.LocalName;
 
                if (MatchingStrings(elementName, s_implementsString) ||
                    MatchingStrings(elementName, s_extendsString))
                {
                    WsdlBindingSudsImplements impl = new WsdlBindingSudsImplements();
                    impl.typeName = LookupAttribute(s_typeString, null, true);
                    impl.ns = ParseQName(ref impl.typeName);
                    suds.implements.Add(impl);
                    ReadNextXmlElement();
                    continue;                   
                }
                else if (MatchingStrings(elementName, s_nestedTypeString))
                {
                    WsdlBindingSudsNestedType nestedType = new WsdlBindingSudsNestedType();
                    nestedType.name = LookupAttribute(s_nameString, null, true);
                    nestedType.typeName = LookupAttribute(s_typeString, null, true);
                    nestedType.ns = ParseQName(ref nestedType.typeName);
                    suds.nestedTypes.Add(nestedType);
                    ReadNextXmlElement();
                    continue;                   
                }
 
 
                // Ignore others elements such as annotations
                SkipXmlElement();
            }
        }
 
        private SudsUse ProcessSudsUse(String use, String elementName)
        {
            Util.Log("WsdlParser.ProcessSudsUse use enter "+use+" elementName "+elementName);            
            SudsUse sudsUse = SudsUse.Class;
 
            if (use == null || use.Length == 0)
                use = elementName;
 
            if (MatchingStrings(use, s_interfaceString))
                sudsUse = SudsUse.Interface;
            else if (MatchingStrings(use, s_classString))
                sudsUse = SudsUse.Class;
            else if (MatchingStrings(use, s_structString))
                sudsUse = SudsUse.Struct;
            else if (MatchingStrings(use, s_ISerializableString))
                sudsUse = SudsUse.ISerializable;
            else if (MatchingStrings(use, s_marshalByRefString))
                sudsUse = SudsUse.MarshalByRef;
            else if (MatchingStrings(use, s_delegateString))
                sudsUse = SudsUse.Delegate;
            else if (MatchingStrings(use, s_servicedComponentString))
                sudsUse = SudsUse.ServicedComponent;
 
            Util.Log("WsdlParser.ProcessSudsUse use exit "+((Enum)sudsUse).ToString());
            return sudsUse;
        }
 
        private void ParseWsdlBindingOperation(WsdlBindingOperation op, ref bool bRpcBinding, ref bool bSoapEncoded)
        {
            Util.Log("WsdlParser.ParseWsdlBindingOperation");                                                                                   
            int curDepth = _XMLReader.Depth; 
            bool binput = false;
            bool boutput = false;
            WsdlBindingOperationSection opSec = null;
 
            ReadNextXmlElement();               
 
            while (_XMLReader.Depth > curDepth)
            {
                String elementName = _XMLReader.LocalName;
 
                if (MatchingNamespace(s_wsdlSudsNamespaceString) && MatchingStrings(elementName, s_methodString))
                {
                    op.methodAttributes = LookupAttribute(s_attributesString, null, true);
                    ReadNextXmlElement();                                   
                    continue;                                       
                }
                else if (MatchingNamespace(s_wsdlSoapNamespaceString) &&
                         MatchingStrings(elementName, s_operationString))
                {
                    WsdlBindingSoapOperation soapOp = new WsdlBindingSoapOperation();
                    soapOp.soapAction = LookupAttribute(s_soapActionString, null, false);
                    soapOp.style = LookupAttribute(s_styleString, null, false);
                    if (soapOp.style == "rpc")
                        bRpcBinding = true;
                    {
                    }
                    op.soapOperation = soapOp;
                    ReadNextXmlElement();                                   
                    continue;                   
                }
                else if (MatchingNamespace(s_wsdlNamespaceString))
                {
                    if (MatchingStrings(elementName, s_inputString))
                    {
                        binput = true;
                        opSec = ParseWsdlBindingOperationSection(op, elementName, ref bSoapEncoded);
                        continue;                       
                    }
                    else if (MatchingStrings(elementName, s_outputString))
                    {
                        boutput = true;
                        ParseWsdlBindingOperationSection(op, elementName, ref bSoapEncoded);
                        continue;                       
                    }
                    else if (MatchingStrings(elementName, s_faultString))
                    {
                        ParseWsdlBindingOperationSection(op, elementName, ref bSoapEncoded);
                        continue;                       
                    }
                }
 
                // Ignore others elements such as annotations
                SkipXmlElement();
            }
 
            // if no output section then the default name is just the op name.
            if (opSec != null && binput && !boutput)
                opSec.name = op.name;
 
 
        }
 
        private WsdlBindingOperationSection ParseWsdlBindingOperationSection(WsdlBindingOperation op, String inputElementName, ref bool bSoapEncoded)
        {
            Util.Log("WsdlParser.ParseWsdlBindingOperationSections");
            bool breturn = false;
            WsdlBindingOperationSection opSec = new WsdlBindingOperationSection();
            op.sections.Add(opSec);
            opSec.name = LookupAttribute(s_nameString, null, false);
            if (MatchingStrings(opSec.name, s_emptyString))
            {
                if (MatchingStrings(inputElementName, s_inputString))
                {
                    breturn = true;
                    opSec.name = Atomize(op.name+"Request");
                }
                else if (MatchingStrings(inputElementName, s_outputString))
                    opSec.name = Atomize(op.name+"Response");
            }
            opSec.elementName = inputElementName;
            int curDepth = _XMLReader.Depth; 
            ReadNextXmlElement();               
            while (_XMLReader.Depth > curDepth)
            {
                String elementName = _XMLReader.LocalName;
                if (MatchingNamespace(s_wsdlSoapNamespaceString))
                {
                    if (MatchingStrings(elementName, s_bodyString))
                    {
                        WsdlBindingSoapBody soapBody = new WsdlBindingSoapBody();
                        opSec.extensions.Add(soapBody);
                        soapBody.parts = LookupAttribute(s_partsString, null, false);
                        soapBody.use = LookupAttribute(s_useString, null, true); 
                        if (soapBody.use == "encoded")
                            bSoapEncoded = true;
                        soapBody.encodingStyle = LookupAttribute(s_encodingStyleString, null, false);
                        soapBody.namespaceUri = LookupAttribute(s_namespaceString, null, false);
                        ReadNextXmlElement();
                        continue;                       
                    }
                    else if (MatchingStrings(elementName, s_headerString))
                    {
                        WsdlBindingSoapHeader soapHeader = new WsdlBindingSoapHeader();
                        opSec.extensions.Add(soapHeader);
                        soapHeader.message = LookupAttribute(s_messageString, null, true);  
                        soapHeader.messageNs = ParseQName(ref soapHeader.message);
                        soapHeader.part = LookupAttribute(s_partString, null, true);
                        soapHeader.use = LookupAttribute(s_useString, null, true);
                        soapHeader.encodingStyle = LookupAttribute(s_encodingStyleString, null, false);
                        soapHeader.namespaceUri = LookupAttribute(s_namespaceString, null, false);
                        ReadNextXmlElement();
                        continue;                       
                    }
                    else if (MatchingStrings(elementName, s_faultString))
                    {
                        WsdlBindingSoapFault soapFault = new WsdlBindingSoapFault();
                        opSec.extensions.Add(soapFault);
                        soapFault.name = LookupAttribute(s_nameString, null, true);  
                        soapFault.use = LookupAttribute(s_useString, null, true);
                        soapFault.encodingStyle = LookupAttribute(s_encodingStyleString, null, false);
                        soapFault.namespaceUri = LookupAttribute(s_namespaceString, null, false);
                        ReadNextXmlElement();
                        continue;                       
                    }
 
                }
                // Ignore others elements such as annotations
                // headerFault currently ignored
                SkipXmlElement();
            }
 
            // returning opSec only if a fixup might be necessary, this is the case of an input section with an empty input name
            // it will be fixed up later if there is no output section
            if (breturn)
                return opSec;
            else
                return null;
        }
 
        private void ParseWsdlService()
        {
            Util.Log("WsdlParser.ParseWsdlService");
            WsdlService service = new WsdlService();
            service.name = LookupAttribute(s_nameString, null, true);
            //service.nameNs = ParseQName(ref service.name);
            int curDepth = _XMLReader.Depth; 
            ReadNextXmlElement();               
            while (_XMLReader.Depth > curDepth)
            {
                String elementName = _XMLReader.LocalName;
 
                if (MatchingNamespace(s_wsdlNamespaceString) &&
                    MatchingStrings(elementName, s_portString))
                {
                    WsdlServicePort port = new WsdlServicePort();
                    port.name = LookupAttribute(s_nameString, null, true);
                    port.nameNs = ParseQName(ref port.nameNs);
                    port.binding = LookupAttribute(s_bindingString, null, true);
                    port.bindingNs = ParseQName(ref port.binding);
                    ParseWsdlServicePort(port);
                    service.ports[port.binding] = port;
                    continue;                   
                }
 
                // Ignore others elements such as annotations
                SkipXmlElement();
            }
            wsdlServices.Add(service);
        }
 
        private void ParseWsdlServicePort(WsdlServicePort port)
        {
            Util.Log("WsdlParser.ParseWsdlServicePort");
            int curDepth = _XMLReader.Depth; 
            ReadNextXmlElement();               
            while (_XMLReader.Depth > curDepth)
            {
                String elementName = _XMLReader.LocalName;
                if (MatchingNamespace(s_wsdlSoapNamespaceString) &&
                    MatchingStrings(elementName, s_addressString))
                {
                    if (port.locations == null)
                        port.locations = new ArrayList(10);
                    port.locations.Add(LookupAttribute(s_locationString, null, true));
                    ReadNextXmlElement();
                    continue;                   
                }
 
                // Ignore others elements such as annotations
                SkipXmlElement();
            }
        }
 
        private void ResolveWsdl()
        {
            Util.Log("WsdlParser.ResolveWsdl ");
 
            if (wsdlBindings.Count == 0)
                throw new SUDSParserException(String.Format(CultureInfo.CurrentCulture, CoreChannel.GetResourceString("Remoting_Suds_RpcBindingsMissing")));
 
            foreach (WsdlBinding binding in wsdlBindings)
            {
                // Only creating classes for soap
                if (binding.soapBinding != null)
                {
                    if (binding.suds != null && binding.suds.Count > 0)
                    {
                        bool bFirstSuds = true;
                        foreach (WsdlBindingSuds suds in binding.suds)
                        {
                            if (MatchingStrings(suds.elementName, s_classString) || MatchingStrings(suds.elementName, s_structString))
                            {
                                ResolveWsdlClass(binding, suds, bFirstSuds);
                                bFirstSuds = false;
                            }
                            else if (MatchingStrings(suds.elementName, s_interfaceString))
                                ResolveWsdlInterface(binding, suds);
                            else
                            {
                                throw new SUDSParserException(
                                                             String.Format(CultureInfo.CurrentCulture, CoreChannel.GetResourceString("Remoting_Suds_CantResolveElementInNS"),
                                                                           suds.elementName, s_wsdlSudsNamespaceString));
                            }
                        }
                    }
                    else
                        ResolveWsdlClass(binding, null, true); // No suds, create a default class
                }
            }
        }
 
        private void ResolveWsdlClass(WsdlBinding binding, WsdlBindingSuds suds, bool bFirstSuds)
        {
            // bFirstSuds is true then the suds class is the class for the binding. 
            // The other suds are additional class without bindings in the same namespace.
            Util.Log("WsdlParser.ResolveWsdlClass suds "+suds);
            URTComplexType parsingComplexType;
            //URTNamespace parsingNamespace = binding.parsingNamespace;
            URTNamespace parsingNamespace;
            //URTNamespace parsingNamespace = binding.typeNs;
 
            if (suds != null)
            {
                Util.Log("WsdlParser.ResolveWsdlClass suds not null "+suds.elementName+" "+suds.typeName);
                // Suds
                parsingNamespace = AddNewNamespace(suds.ns);
                parsingComplexType = parsingNamespace.LookupComplexType(suds.typeName);
                if (parsingComplexType == null)
                {
                    parsingComplexType = new URTComplexType(suds.typeName, parsingNamespace.Name, parsingNamespace.Namespace, parsingNamespace.EncodedNS, _blockDefault ,false, false, this, parsingNamespace);
                    parsingNamespace.AddComplexType(parsingComplexType);
                }
 
                if (MatchingStrings(suds.elementName, s_structString))
                    parsingComplexType.IsValueType = true;
 
                parsingComplexType.SudsUse = suds.sudsUse;
 
                if (suds.sudsUse == SudsUse.MarshalByRef || 
                    suds.sudsUse == SudsUse.ServicedComponent
                   )
                {
                    Util.Log("WsdlParser.ResolveWsdlClass MarshalByRef IsSudsType true 1 "+suds.elementName+" "+suds.typeName);
                    parsingComplexType.IsSUDSType = true; 
 
                    if (_bWrappedProxy)
                        parsingComplexType.SUDSType = SUDSType.ClientProxy;
                    else
                        parsingComplexType.SUDSType = SUDSType.MarshalByRef;
 
 
                    if ((suds.extendsTypeName != null) && (suds.extendsTypeName.Length > 0))
                    {
                        URTNamespace extendsNamespace = AddNewNamespace(suds.extendsNs);                    
                        /*
                        if (extendsNamespace == null)
                            extendsNamespace = new URTNamespace(suds.extendsTypeName, this);
                            */
 
                        URTComplexType extendsComplexType = extendsNamespace.LookupComplexType(suds.extendsTypeName);                   
                        if (extendsComplexType == null)
                        {
                            extendsComplexType = new URTComplexType(suds.extendsTypeName, extendsNamespace.Name, extendsNamespace.Namespace, extendsNamespace.EncodedNS, _blockDefault ,true, false, this, extendsNamespace);
                            extendsNamespace.AddComplexType(extendsComplexType);
                        }
                        else
                        {
                            Util.Log("WsdlParser.ResolveWsdlClass IsSudsType true 2 "+suds.elementName+" "+suds.typeName);
                            extendsComplexType.IsSUDSType = true;
                        }
 
                        if (_bWrappedProxy)
                            extendsComplexType.SUDSType = SUDSType.ClientProxy;
                        else
                            extendsComplexType.SUDSType = SUDSType.MarshalByRef;
 
                        extendsComplexType.SudsUse = suds.sudsUse;
 
                        // Only top of inheritance hierarchy is marked
                        //parsingComplexType.SUDSType = SUDSType.None; 
                    }
                }
 
                foreach (WsdlBindingSudsNestedType nestedType in suds.nestedTypes)
                {
                    ResolveWsdlNestedType(binding, suds, nestedType);
                }
            }
            else
            {
                // No suds
                Util.Log("WsdlParser.ResolveWsdlClass no suds ");
                parsingNamespace = AddNewNamespace(binding.typeNs);
                String name = binding.name;
                int index = binding.name.IndexOf("Binding");
                if (index > 0)
                {
                    //name = Atomize(binding.name.Substring(0,index));
                    name = binding.name.Substring(0,index);
                }
 
                parsingComplexType = parsingNamespace.LookupComplexTypeEqual(name);
                if (parsingComplexType == null)
                {
                    parsingComplexType = new URTComplexType(name, parsingNamespace.Name, parsingNamespace.Namespace, parsingNamespace.EncodedNS, _blockDefault ,true, false, this, parsingNamespace);
                    parsingNamespace.AddComplexType(parsingComplexType);                    
                }
                else
                {
                    Util.Log("WsdlParser.ResolveWsdlClass IsSudsType true 3 "+name);
                    parsingComplexType.IsSUDSType = true;
                }
                if (_bWrappedProxy)
                    parsingComplexType.SUDSType = SUDSType.ClientProxy;
                else
                    parsingComplexType.SUDSType = SUDSType.MarshalByRef;
 
                parsingComplexType.SudsUse = SudsUse.MarshalByRef;
            }
 
            // Resolve address
            parsingComplexType.ConnectURLs = ResolveWsdlAddress(binding);
 
            // Resolve extends and implements
            if (suds != null)
            {
                if (!MatchingStrings(suds.extendsTypeName, s_emptyString))
                {
                    parsingComplexType.Extends(suds.extendsTypeName, suds.extendsNs);
                }
 
                foreach (WsdlBindingSudsImplements impl in suds.implements)
                parsingComplexType.Implements(impl.typeName, impl.ns, this);  
            }
 
 
 
 
            if (bFirstSuds && 
                (parsingComplexType.SudsUse == SudsUse.MarshalByRef || 
                 parsingComplexType.SudsUse == SudsUse.ServicedComponent || 
                 parsingComplexType.SudsUse == SudsUse.Delegate || 
                 parsingComplexType.SudsUse == SudsUse.Interface))
            {
                // Resolve methods
 
                ArrayList methodInfos = ResolveWsdlMethodInfo(binding);
 
                foreach (WsdlMethodInfo methodInfo in methodInfos)
                {
                    if ((methodInfo.inputMethodName != null) && (methodInfo.outputMethodName != null))
                    {
                        RRMethod parsingRRMethod = new RRMethod(methodInfo, parsingComplexType);
                        parsingRRMethod.AddRequest(methodInfo.methodName, methodInfo.methodNameNs);
                        parsingRRMethod.AddResponse(methodInfo.methodName, methodInfo.methodNameNs);
                        parsingComplexType.AddMethod(parsingRRMethod);
                    }
                    else if (methodInfo.inputMethodName != null)
                    {
                        OnewayMethod parsingOWMethod = new OnewayMethod(methodInfo, parsingComplexType);
                        parsingComplexType.AddMethod(parsingOWMethod);
                        parsingOWMethod.AddMessage(methodInfo.methodName, methodInfo.methodNameNs);
                    }
                    else
                    {
                        throw new SUDSParserException(
                                                     String.Format(CultureInfo.CurrentCulture, CoreChannel.GetResourceString("Remoting_Suds_WsdlInvalidMessage"),
                                                                   methodInfo.methodName));
                    }
                }
            }
        }
 
        private void ResolveWsdlInterface(WsdlBinding binding, WsdlBindingSuds suds)
        {
            Util.Log("WsdlParser.ResolveWsdlInterface "+binding.name+" ns "+binding.parsingNamespace.Namespace+" suds "+suds.typeName);
 
            URTNamespace parsingNamespace = binding.parsingNamespace;
 
            URTNamespace sudsNamespace = AddNewNamespace(suds.ns);
            /*
            if (sudsNamespace == null)
            {
                sudsNamespace = new URTNamespace(suds.ns, this);
            }
            */
 
            URTInterface parsingInterface = sudsNamespace.LookupInterface(suds.typeName);           
            if (parsingInterface == null)
            {
                parsingInterface = new URTInterface(suds.typeName, sudsNamespace.Name, sudsNamespace.Namespace, sudsNamespace.EncodedNS, this);
                sudsNamespace.AddInterface(parsingInterface);
            }
 
            if (suds.extendsTypeName != null)
            {
                parsingInterface.Extends(suds.extendsTypeName, suds.extendsNs, this);
            }
            foreach (WsdlBindingSudsImplements impl in suds.implements)
            {
                parsingInterface.Extends(impl.typeName, impl.ns, this);             
            }
 
            ArrayList methodInfos = ResolveWsdlMethodInfo(binding);
 
            foreach (WsdlMethodInfo methodInfo in methodInfos)          
            {
                if ((methodInfo.inputMethodName != null) && (methodInfo.outputMethodName != null))
                {
                    RRMethod parsingRRMethod = new RRMethod(methodInfo, null);
                    parsingRRMethod.AddRequest(methodInfo.methodName, methodInfo.methodNameNs);
                    parsingRRMethod.AddResponse(methodInfo.methodName, methodInfo.methodNameNs);
                    parsingInterface.AddMethod(parsingRRMethod);
                }
                else if (methodInfo.inputMethodName != null)
                {
                    OnewayMethod parsingOWMethod = new OnewayMethod(methodInfo.methodName, methodInfo.soapAction, null);
                    parsingOWMethod.AddMessage(methodInfo.methodName, methodInfo.methodNameNs);                 
                    parsingInterface.AddMethod(parsingOWMethod);
                }
                else
                {
                    throw new SUDSParserException(
                                                 String.Format(CultureInfo.CurrentCulture, CoreChannel.GetResourceString("Remoting_Suds_WsdlInvalidMessage"),
                                                               methodInfo.methodName));
 
                }
            }
        }
 
        private void ResolveWsdlNestedType(WsdlBinding binding, WsdlBindingSuds suds, WsdlBindingSudsNestedType nested)
        {
            Util.Log("WsdlParser.ResolveWsdlNestedType "+binding.name+" ns "+binding.parsingNamespace.Namespace+" suds "+suds.typeName+" nestedName "+nested.name+" nestedTypeName "+nested.typeName);
            String className = suds.typeName;
            String ns = nested.ns;
            String nestedName = nested.name;
            String nestedTypeName = nested.typeName;
            if (suds.ns != ns)
            {
                throw new SUDSParserException(
                                             String.Format(CultureInfo.CurrentCulture, CoreChannel.GetResourceString("Remoting_Suds_CantResolveNestedTypeNS"),
                                                           suds.typeName, suds.ns));
            }
 
            URTNamespace sudsNamespace = AddNewNamespace(suds.ns);
 
            URTComplexType outerType = sudsNamespace.LookupComplexType(suds.typeName);
            if (outerType == null)
            {
                throw new SUDSParserException(
                                             String.Format(CultureInfo.CurrentCulture, CoreChannel.GetResourceString("Remoting_Suds_CantResolveNestedType"),
                                                           suds.typeName, suds.ns));
            }
 
            BaseType innerType = sudsNamespace.LookupType(nested.typeName);
            if (innerType == null)
            {
                // Can be URTSimpleType for Enum
                Util.Log("WsdlParser.ResolveWsdlNestedType cann't find inner type "+nested.typeName+" className "+className+" ns "+ns);
 
                innerType = sudsNamespace.LookupComplexType(nested.typeName);
                if (innerType == null)
                {
                    innerType = new URTComplexType(nested.typeName, sudsNamespace.Name, sudsNamespace.Namespace, sudsNamespace.EncodedNS, _blockDefault ,false, false, this, sudsNamespace);
                    sudsNamespace.AddComplexType((URTComplexType)innerType);
                }
            }
 
 
            innerType.bNestedType = true;
            innerType.NestedTypeName = nested.name;
            innerType.FullNestedTypeName = nested.typeName;
            innerType.OuterTypeName = suds.typeName;
 
            outerType.AddNestedType(innerType);
        }
 
        private ArrayList ResolveWsdlAddress(WsdlBinding binding)
        {
            Util.Log("WsdlParser.ResolveWsdlAddress "+binding.name);            
            ArrayList serviceEndpoints = null;
            if (_bWrappedProxy)
            {
                foreach (WsdlService service in wsdlServices)
                {
                    WsdlServicePort port = (WsdlServicePort)service.ports[binding.name];
                    if (port != null)
                    {
                        serviceEndpoints = port.locations;
                        break;
                    }
                    if (serviceEndpoints != null)
                        break;
                }
            }
            return serviceEndpoints;
        }
 
        private ArrayList ResolveWsdlMethodInfo(WsdlBinding binding)
        {
            Util.Log("WsdlParser.ResolveWsdlMethodInfo "+binding.name);                     
            ArrayList methodInfos = new ArrayList(10);
            Hashtable propertyMethod = new Hashtable(3);
            for (int i=0; i<binding.operations.Count; i++)
            {
                bool bGet = false;
                bool bSet = false;
                WsdlBindingOperation op = (WsdlBindingOperation)binding.operations[i];
                if (op.soapOperation != null)
                {
                    WsdlMethodInfo methodInfo = new WsdlMethodInfo();
                    methodInfo.methodName = op.name;
                    methodInfo.methodNameNs = op.nameNs;
                    methodInfo.methodAttributes = op.methodAttributes;
                    AddNewNamespace(op.nameNs);
                    WsdlBindingSoapOperation opSoap = (WsdlBindingSoapOperation)op.soapOperation;
 
                    if ((methodInfo.methodName.StartsWith("get_", StringComparison.Ordinal) && methodInfo.methodName.Length > 4))
                        bGet = true;
                    else if ((methodInfo.methodName.StartsWith("set_", StringComparison.Ordinal) && methodInfo.methodName.Length > 4))
                        bSet = true;
                    if (bGet || bSet)
                    {
                        bool bNew = false;
                        String propertyName = methodInfo.methodName.Substring(4);
                        WsdlMethodInfo propertyMethodInfo = (WsdlMethodInfo)propertyMethod[propertyName];
                        if (propertyMethodInfo == null)
                        {
                            propertyMethod[propertyName] = methodInfo;
                            methodInfos.Add(methodInfo);
                            propertyMethodInfo = methodInfo;
                            methodInfo.propertyName = propertyName;
                            methodInfo.bProperty = true;
                            bNew = true;
                        }
 
                        if (bGet)
                        {
                            propertyMethodInfo.bGet = true;
                            propertyMethodInfo.soapActionGet = opSoap.soapAction;
                        }
                        else
                        {
                            propertyMethodInfo.bSet = true;
                            propertyMethodInfo.soapActionSet = opSoap.soapAction;
                            //propertyMethodInfo.Dump();
                        }
 
                        if (!bNew)
                            continue; //already processed this property
                    }
                    else
                        methodInfos.Add(methodInfo);
                    methodInfo.soapAction = opSoap.soapAction;
 
                    WsdlPortType portType = (WsdlPortType)wsdlPortTypes[binding.type];
 
                    if ((portType == null) || (portType.operations.Count != binding.operations.Count))
                    {
                        throw new SUDSParserException(
                                                     String.Format(CultureInfo.CurrentCulture, CoreChannel.GetResourceString("Remoting_Suds_WsdlInvalidPortType"),
                                                                   binding.type));
                    }
 
                    // PortType operations are obtained by the <binding><operation><input name = porttype operation>
 
                    WsdlPortTypeOperation portTypeOp = null;
                    foreach (WsdlBindingOperationSection opSec in op.sections)
                    {
                        if (MatchingStrings(opSec.elementName, s_inputString))
                        {
 
                            portTypeOp = (WsdlPortTypeOperation)portType.sections[opSec.name];
 
                            Util.Log("WsdlParser.ResolveWsdlMethodInfo find portTypeOp 1 "+opSec.name+" portTypeOp "+portTypeOp);
 
                            if (portTypeOp == null)
                            {
                                //this is for interop testing because other implementations are using the opSec.name wrong.
                                // a "Request" is not being added to the end of the name.
                                int index  = opSec.name.LastIndexOf("Request");
                                if (index > 0)
                                {
                                    String newOpName = opSec.name.Substring(0, index);
                                    portTypeOp = (WsdlPortTypeOperation)portType.sections[newOpName];
                                    Util.Log("WsdlParser.ResolveWsdlMethodInfo find portTypeOp 2 "+newOpName+" portTypeOp "+portTypeOp);
                                }
                            }
 
                            if (portTypeOp != null && portTypeOp.parameterOrder != null && portTypeOp.parameterOrder.Length > 0)
                            {
                                methodInfo.paramNamesOrder = portTypeOp.parameterOrder.Split(' ');
                            }
 
                            foreach (WsdlBindingSoapBody body in opSec.extensions)
                            {
                                if (body.namespaceUri != null || body.namespaceUri.Length > 0)
                                    methodInfo.inputMethodNameNs = body.namespaceUri;
                            }
                        }
                        else if (MatchingStrings(opSec.elementName, s_outputString))
                        {
                            foreach (WsdlBindingSoapBody body in opSec.extensions)
                            {
                                if (body.namespaceUri != null || body.namespaceUri.Length > 0)
                                    methodInfo.outputMethodNameNs = body.namespaceUri;
                            }
                        }
                    }
 
                    /*
                    if (portTypeOp == null)
                    {
                    throw new SUDSParserException(
                    String.Format(CoreChannel.GetResourceString("Remoting_Suds_WsdlInvalidPortType"),
                    binding.type));
                    }
                    */
 
                    if (portTypeOp != null)
                    {
 
                        foreach (WsdlPortTypeOperationContent content in portTypeOp.contents)
                        {
                            if (MatchingStrings(content.element, s_inputString))
                            {
                                methodInfo.inputMethodName = content.message;
                                if (methodInfo.inputMethodNameNs == null)
                                    methodInfo.inputMethodNameNs = content.messageNs;
                                WsdlMessage message = (WsdlMessage)wsdlMessages[content.message];
                                if (message == null)
                                {
                                    throw new SUDSParserException(
                                                                 String.Format(CultureInfo.CurrentCulture, CoreChannel.GetResourceString("Remoting_Suds_WsdlMissingMessage"),
                                                                               content.message));
                                }
                                else
                                {
                                    if (message.parts != null)
                                    {
                                        methodInfo.inputNames = new String[message.parts.Count];
                                        methodInfo.inputNamesNs = new String[message.parts.Count];
                                        methodInfo.inputElements = new String[message.parts.Count];
                                        methodInfo.inputElementsNs = new String[message.parts.Count];
                                        methodInfo.inputTypes = new String[message.parts.Count];
                                        methodInfo.inputTypesNs = new String[message.parts.Count];
                                        for (int ip=0; ip<message.parts.Count; ip++)
                                        {
                                            methodInfo.inputNames[ip] = ((WsdlMessagePart)message.parts[ip]).name;
                                            methodInfo.inputNamesNs[ip] = ((WsdlMessagePart)message.parts[ip]).nameNs;
                                            AddNewNamespace(methodInfo.inputNamesNs[ip]);
                                            methodInfo.inputElements[ip] = ((WsdlMessagePart)message.parts[ip]).element;
                                            methodInfo.inputElementsNs[ip] = ((WsdlMessagePart)message.parts[ip]).elementNs;
                                            AddNewNamespace(methodInfo.inputElementsNs[ip]);
                                            methodInfo.inputTypes[ip] = ((WsdlMessagePart)message.parts[ip]).typeName;
                                            methodInfo.inputTypesNs[ip] = ((WsdlMessagePart)message.parts[ip]).typeNameNs;
                                            AddNewNamespace(methodInfo.inputTypesNs[ip]);
                                            if (methodInfo.bProperty && methodInfo.inputTypes[ip] != null && methodInfo.propertyType == null)
                                            {
                                                methodInfo.propertyType = methodInfo.inputTypes[ip];
                                                methodInfo.propertyNs = methodInfo.inputTypesNs[ip];
                                                AddNewNamespace(methodInfo.propertyNs);
                                            }
 
                                        }
                                    }
                                }
                            }
                            else if (MatchingStrings(content.element, s_outputString))
                            {
                                methodInfo.outputMethodName = content.message;
                                if (methodInfo.outputMethodNameNs == null)
                                    methodInfo.outputMethodNameNs = content.messageNs;
                                WsdlMessage message = (WsdlMessage)wsdlMessages[content.message];
                                if (message == null)
                                {
                                    throw new SUDSParserException(
                                                                 String.Format(CultureInfo.CurrentCulture, CoreChannel.GetResourceString("Remoting_Suds_WsdlMissingMessage"),
                                                                               content.message));
                                }
                                else
                                {
                                    if (message.parts != null)
                                    {
                                        methodInfo.outputNames = new String[message.parts.Count];
                                        methodInfo.outputNamesNs = new String[message.parts.Count];
                                        methodInfo.outputElements = new String[message.parts.Count];
                                        methodInfo.outputElementsNs = new String[message.parts.Count];
                                        methodInfo.outputTypes = new String[message.parts.Count];
                                        methodInfo.outputTypesNs = new String[message.parts.Count];
                                        for (int ip=0; ip<message.parts.Count; ip++)
                                        {
                                            methodInfo.outputNames[ip] = ((WsdlMessagePart)message.parts[ip]).name;
                                            methodInfo.outputNamesNs[ip] = ((WsdlMessagePart)message.parts[ip]).nameNs;
                                            AddNewNamespace(methodInfo.outputNamesNs[ip]);
                                            methodInfo.outputElements[ip] = ((WsdlMessagePart)message.parts[ip]).element;
                                            methodInfo.outputElementsNs[ip] = ((WsdlMessagePart)message.parts[ip]).elementNs;
                                            AddNewNamespace(methodInfo.outputElementsNs[ip]);
                                            methodInfo.outputTypes[ip] = ((WsdlMessagePart)message.parts[ip]).typeName;
                                            methodInfo.outputTypesNs[ip] = ((WsdlMessagePart)message.parts[ip]).typeNameNs;
                                            AddNewNamespace(methodInfo.outputTypesNs[ip]);
                                            if (methodInfo.bProperty && methodInfo.outputTypes[ip] != null && methodInfo.propertyType == null)
                                            {
                                                methodInfo.propertyType = methodInfo.outputTypes[ip];
                                                methodInfo.propertyNs = methodInfo.outputTypesNs[ip];
                                                AddNewNamespace(methodInfo.outputTypesNs[ip]);
                                            }
                                        }
                                    }
                                }
                            }
                            else
                                throw new SUDSParserException(
                                                             String.Format(CultureInfo.CurrentCulture, CoreChannel.GetResourceString("Remoting_Suds_WsdlInvalidPortType"),
                                                                           content.element));
                        }
                        //methodInfo.Dump();
                    } //no porttype
                }
            }
            return methodInfos;
        }
 
        // Parse Schema
        private void ParseSchema()
        {
            Util.Log("WsdlParser.ParseSchema");                                 
            // Remember the current depth
            int curDepth = _XMLReader.Depth;
 
            // Parse the target namespace first
            URTNamespace parsingNamespace = ParseNamespace();
 
            // Parse schema elements
            while (_XMLReader.Depth > curDepth)
            {
                String elementName = _XMLReader.LocalName;
                //if (MatchingSchemaNamespace())
                {
                    if (MatchingStrings(elementName, s_complexTypeString))
                        ParseComplexType(parsingNamespace, null);
                    else if (MatchingStrings(elementName, s_simpleTypeString))
                        ParseSimpleType(parsingNamespace, null);
                    else if (MatchingStrings(elementName, s_schemaString))
                        ParseSchema();
                    else if (MatchingStrings(elementName, s_elementString))
                        ParseElementDecl(parsingNamespace);
                    else if (MatchingStrings(elementName, s_importString))
                        ParseSchemaImportElement();
                    else if (MatchingStrings(elementName, s_includeString))
                        ParseSchemaIncludeElement();
                    else
                        goto SkipXMLNode;
 
                    continue;
                }
 
                SkipXMLNode:
                // Ignore others elements such as annotations
                SkipXmlElement();
            }
 
            return;
        }
 
 
        // Resolves internal references
        private void Resolve()
        {
            Util.Log("WsdlParser.Resolve");                                 
            for (int i=0;i<_URTNamespaces.Count;i++)
                ((URTNamespace)_URTNamespaces[i]).ResolveElements(this);
 
            for (int i=0;i<_URTNamespaces.Count;i++)
                ((URTNamespace)_URTNamespaces[i]).ResolveTypes(this);
 
            for (int i=0;i<_URTNamespaces.Count;i++)
                ((URTNamespace)_URTNamespaces[i]).ResolveMethods();
        }
 
        // Lookup a given attribute position.
        // Note that the supplied strings must have been atomized
        private String LookupAttribute(String attrName, String attrNS, bool throwExp)
        {
            Util.Log("WsdlParser.LookupAttribute Enter "+attrName+", NS "+attrNS+", Exp "+throwExp);                                    
            String value = s_emptyString;
            bool bPresent;
            if (attrNS != null)
                bPresent = _XMLReader.MoveToAttribute(attrName, attrNS);
            else
                bPresent = _XMLReader.MoveToAttribute(attrName);
 
            if (bPresent)
                value = Atomize(_XMLReader.Value.Trim());
            _XMLReader.MoveToElement();
 
            if ((bPresent == false) && (throwExp == true))
            {
                throw new SUDSParserException(
                                             String.Format(CultureInfo.CurrentCulture, CoreChannel.GetResourceString("Remoting_Suds_AttributeNotFound"),
                                                           attrName, XMLReader.LineNumber, XMLReader.LinePosition, XMLReader.Name));
            }
            Util.Log("WsdlParser.LookupAttribute exit "+attrName+"="+value+", NS "+attrNS+", Exp "+throwExp);                                    
            return(value);
        }
 
        // Resolves type attribute into its constituent parts
        private void ResolveTypeAttribute(ref String typeName, out String typeNS,
                                          out bool bEmbedded, out bool bPrimitive)
        {
            Util.Log("WsdlParser.ResolveTypeAttribute typeName "+typeName);                                 
            if (MatchingStrings(typeName, s_emptyString))
            {
                typeName = s_objectString;
                typeNS = SchemaNamespaceString;
                bEmbedded = true;
                bPrimitive = false;
            }
            else
            {
                // The type field is a QName
                typeNS = ParseQName(ref typeName);
 
                // Check for reference and array types
                ResolveTypeNames(ref typeNS, ref typeName, out bEmbedded, out bPrimitive);
            }
 
            return;
        }
 
        // Parses a qname
 
        private String ParseQName(ref String qname)
        {
            return ParseQName(ref qname, null);
        }
        private String ParseQName(ref String qname, URTNamespace defaultNS)
        {
            URTNamespace returnNS = null;
            return ParseQName( ref qname, defaultNS, out returnNS);
        }
 
        private String ParseQName(ref String qname, URTNamespace defaultNS, out URTNamespace returnNS)
        {
            Util.Log("WsdlParser.ParseQName Enter qname "+qname+" default xmlns NS "+_XMLReader.LookupNamespace(""));
 
            String ns = null;
            returnNS = null;
            if ((qname == null) || (qname.Length == 0))
            {
                Util.Log("WsdlParser.ParseQName Exit null");
                return null;
            }
 
            int colonIndex = qname.IndexOf(":");
            if (colonIndex == -1)
            {
                // The default namespace is the s_empty string (this will need to change)
                //textWriter.WriteLine("DefaultNS: " + _XMLReader.LookupNamespace(s_emptyString) + '\n' +
                //                     "ElementNS: " + _XMLReader.Namespace);
                // Should this be element namespace or default namespace
                // For attributes names, element namespace makes more sense
                // For QName values, default namespace makes more sense
                // I am currently returning default namespace
 
                returnNS = defaultNS;
                if (defaultNS == null)
                {
                    Util.Log("WsdlParser.ParseQName Exit defaultNS qname "+qname);          
                    ns = _XMLReader.LookupNamespace("");
                }
                else
                {
                    Util.Log("WsdlParser.ParseQName Exit defaultNS qname "+qname+" default "+defaultNS.Name);          
                    ns = defaultNS.Name;
                }
 
            }
            else
            {
                // Get the suffix and atmoize it
                String prefix = qname.Substring(0, colonIndex);
                qname = Atomize(qname.Substring(colonIndex+1));
                ns = _XMLReader.LookupNamespace(prefix);
            }
 
            ns = Atomize(ns);
 
            URTNamespace xns = LookupNamespace(ns);
 
            if (xns == null)
            {
                xns = new URTNamespace(ns, this);
            }
 
 
            returnNS = xns;
 
            Util.Log("WsdlParser.ParseQName Exit qname "+qname+" typeString "+ns+" returnNS "+(returnNS == null?"null":returnNS.Name));          
            return(ns);
        }
 
        // Returns true if the type needs to be qualified with namespace
        private bool Qualify(String typeNS, String curNS)
        {
            Util.Log("WsdlParser.Qualify typeNS "+typeNS+" curNS "+curNS);                                  
            if (MatchingSchemaStrings(typeNS) ||
                MatchingStrings(typeNS, s_soapNamespaceString) ||
                MatchingStrings(typeNS, s_wsdlSoapNamespaceString) ||               
                MatchingStrings(typeNS, "System") ||
                MatchingStrings(typeNS, curNS))
                return(false);
 
            return(true);
        }
 
        // Returns true if the current element node namespace has matching namespace
        private bool MatchingNamespace(String elmNS)
        {
            Util.Log("WsdlParser.MatchingNamespace "+elmNS+" ***** "+_XMLReader.NamespaceURI);                                              
            if (MatchingStrings(_XMLReader.NamespaceURI, elmNS))
                // ||
                //   MatchingStrings(_XMLReader.Prefix, s_emptyString))
                return(true);
 
            return(false);
        }
 
        private bool MatchingSchemaNamespace()
        {
            Util.Log("WsdlParser.MatchingSchemaNamespace ");
            if (MatchingNamespace(s_schemaNamespaceString))
                return true;
            else if (MatchingNamespace(s_schemaNamespaceString1999))
            {
                _xsdVersion = XsdVersion.V1999;
                return true;
            }
            else if (MatchingNamespace(s_schemaNamespaceString2000))
            {
                _xsdVersion = XsdVersion.V2000;
                return true;
            }
            else if (MatchingNamespace(s_schemaNamespaceString))
            {
                _xsdVersion = XsdVersion.V2001;
                return true;
            }
            else
            {
                return false;
            }
        }
 
        private static string TransliterateString(string str)
        {
            if (string.IsNullOrEmpty(str))
            {
                return "\"\"";
            }
 
            //UnicodeCategory: (Lu)UppercaseLetter, (Ll)LowercaseLetter, (Lt)TitlecaseLetter, (Lm)ModifierLetter, (Lo)OtherLetter, or (Nd)DecimalDigitNumber.
 
            StringBuilder sb = new StringBuilder("\"");
 
            foreach (char c in str)
            {
                if (char.IsControl(c))
                {
                    continue;
                }
 
                if (char.IsLetterOrDigit(c))
                {
                    sb.Append(c);
                }
                else
                {
                    sb.Append("\\u");
                    sb.Append(Convert.ToInt32(c).ToString("X4"));
                }
            }
 
            sb.Append("\"");
            return sb.ToString();
        }
 
        static StringBuilder vsb = new StringBuilder();
        internal static string IsValidUrl(string value)
        {
            if (!System.Runtime.Remoting.Configuration.AppSettings.AllowUnsanitizedWSDLUrls)
            {
                return WsdlParser.TransliterateString(value);
            }
 
            if (value == null)
            {
                return "\"\"";
            }
 
            vsb.Length= 0;
            vsb.Append("@\"");
 
            for (int i=0; i<value.Length; i++) 
            {
                if (value[i] == '\"')
                    vsb.Append("\"\"");
                else
                    vsb.Append(value[i]);
            }
 
            vsb.Append("\"");
            return vsb.ToString();
        }
 
 
        static Hashtable cSharpKeywords;
         static bool IsCSharpKeyword(string value) 
         {
            if (cSharpKeywords == null) InitKeywords();
            return cSharpKeywords.ContainsKey(value);
         }
 
        static void InitKeywords() 
        {
            // build the cSharpKeywords hashtable
            Hashtable cSharpKeywordstemp = new Hashtable(75); // about 75 cSharpKeywords to be added
            Object obj = new Object();
            cSharpKeywordstemp["abstract"] = obj;
            cSharpKeywordstemp["base"] = obj;
            cSharpKeywordstemp["bool"] = obj;
            cSharpKeywordstemp["break"] = obj;
            cSharpKeywordstemp["byte"] = obj;
            cSharpKeywordstemp["case"] = obj;
            cSharpKeywordstemp["catch"] = obj;
            cSharpKeywordstemp["char"] = obj;
            cSharpKeywordstemp["checked"] = obj;
            cSharpKeywordstemp["class"] = obj;
            cSharpKeywordstemp["const"] = obj;
            cSharpKeywordstemp["continue"] = obj;
            cSharpKeywordstemp["decimal"] = obj;
            cSharpKeywordstemp["default"] = obj;
            cSharpKeywordstemp["delegate"] = obj;
            cSharpKeywordstemp["do"] = obj;
            cSharpKeywordstemp["double"] = obj;
            cSharpKeywordstemp["else"] = obj;
            cSharpKeywordstemp["enum"] = obj;
            cSharpKeywordstemp["event"] = obj;
            cSharpKeywordstemp["exdouble"] = obj;
            cSharpKeywordstemp["exfloat"] = obj;
            cSharpKeywordstemp["explicit"] = obj;
            cSharpKeywordstemp["extern"] = obj;
            cSharpKeywordstemp["false"] = obj;
            cSharpKeywordstemp["finally"] = obj;
            cSharpKeywordstemp["fixed"] = obj;
            cSharpKeywordstemp["float"] = obj;
            cSharpKeywordstemp["for"] = obj;
            cSharpKeywordstemp["foreach"] = obj;
            cSharpKeywordstemp["goto"] = obj;
            cSharpKeywordstemp["if"] = obj;
            cSharpKeywordstemp["implicit"] = obj;
            cSharpKeywordstemp["in"] = obj;
            cSharpKeywordstemp["int"] = obj;
            cSharpKeywordstemp["interface"] = obj;
            cSharpKeywordstemp["internal"] = obj;
            cSharpKeywordstemp["is"] = obj;
            cSharpKeywordstemp["lock"] = obj;
            cSharpKeywordstemp["long"] = obj;
            cSharpKeywordstemp["namespace"] = obj;
            cSharpKeywordstemp["new"] = obj;
            cSharpKeywordstemp["null"] = obj;
            cSharpKeywordstemp["object"] = obj;
            cSharpKeywordstemp["operator"] = obj;
            cSharpKeywordstemp["out"] = obj;
            cSharpKeywordstemp["override"] = obj;
            cSharpKeywordstemp["private"] = obj;
            cSharpKeywordstemp["protected"] = obj;
            cSharpKeywordstemp["public"] = obj;
            cSharpKeywordstemp["readonly"] = obj;
            cSharpKeywordstemp["ref"] = obj;
            cSharpKeywordstemp["return"] = obj;
            cSharpKeywordstemp["sbyte"] = obj;
            cSharpKeywordstemp["sealed"] = obj;
            cSharpKeywordstemp["short"] = obj;
            cSharpKeywordstemp["sizeof"] = obj;
            cSharpKeywordstemp["static"] = obj;
            cSharpKeywordstemp["string"] = obj;
            cSharpKeywordstemp["struct"] = obj;
            cSharpKeywordstemp["switch"] = obj;
            cSharpKeywordstemp["this"] = obj;
            cSharpKeywordstemp["throw"] = obj;
            cSharpKeywordstemp["true"] = obj;
            cSharpKeywordstemp["try"] = obj;
            cSharpKeywordstemp["typeof"] = obj;
            cSharpKeywordstemp["uint"] = obj;
            cSharpKeywordstemp["ulong"] = obj;
            cSharpKeywordstemp["unchecked"] = obj;
            cSharpKeywordstemp["unsafe"] = obj;
            cSharpKeywordstemp["ushort"] = obj;
            cSharpKeywordstemp["using"] = obj;
            cSharpKeywordstemp["virtual"] = obj;
            cSharpKeywordstemp["void"] = obj;
            cSharpKeywordstemp["while"] = obj;
            cSharpKeywords = cSharpKeywordstemp;
        }
 
 
 
        static bool IsValidLanguageIndependentIdentifier(string ident)
         {
             for (int i=0; i<ident.Length; i++)
             {
                 char c = ident[i];
                 UnicodeCategory uc = Char.GetUnicodeCategory(c);
                 // each char must be Lu, Ll, Lt, Lm, Lo, Nd, Mn, Mc, Pc
                 // 
                 switch (uc) 
                 {
                 case UnicodeCategory.UppercaseLetter:        // Lu
                 case UnicodeCategory.LowercaseLetter:        // Ll
                 case UnicodeCategory.TitlecaseLetter:        // Lt
                 case UnicodeCategory.ModifierLetter:         // Lm
                 case UnicodeCategory.OtherLetter:            // Lo
                 case UnicodeCategory.DecimalDigitNumber:     // Nd
                 case UnicodeCategory.NonSpacingMark:         // Mn
                 case UnicodeCategory.SpacingCombiningMark:   // Mc
                 case UnicodeCategory.ConnectorPunctuation:   // Pc
                 break;
                 case UnicodeCategory.LetterNumber:
                 case UnicodeCategory.OtherNumber:
                 case UnicodeCategory.EnclosingMark:
                 case UnicodeCategory.SpaceSeparator:
                 case UnicodeCategory.LineSeparator:
                 case UnicodeCategory.ParagraphSeparator:
                 case UnicodeCategory.Control:
                 case UnicodeCategory.Format:
                 case UnicodeCategory.Surrogate:
                 case UnicodeCategory.PrivateUse:
                 case UnicodeCategory.DashPunctuation:
                 case UnicodeCategory.OpenPunctuation:
                 case UnicodeCategory.ClosePunctuation:
                 case UnicodeCategory.InitialQuotePunctuation:
                 case UnicodeCategory.FinalQuotePunctuation:
                 case UnicodeCategory.OtherPunctuation:
                 case UnicodeCategory.MathSymbol:
                 case UnicodeCategory.CurrencySymbol:
                 case UnicodeCategory.ModifierSymbol:
                 case UnicodeCategory.OtherSymbol:
                 case UnicodeCategory.OtherNotAssigned:
                 return false;
                 default:
                        return false;
                 }
             }
             return true;
        }
 
 
        internal static void CheckValidIdentifier(string ident)
        {
            if (!IsValidLanguageIndependentIdentifier(ident))
                throw new SUDSParserException(
                                             String.Format(CultureInfo.CurrentCulture, CoreChannel.GetResourceString("Remoting_Suds_WsdlInvalidStringSyntax"),
                                                           ident));
        }
 
        // Used when identifier appears in a custom attribute. Need to strip out leading @ for keyword
        internal static string IsValidCSAttr(string identifier)
        {
            string returnstr = IsValidCS(identifier);
            if (returnstr.Length > 0 && returnstr[0] == '@')
                return returnstr.Substring(1);
            else return returnstr;
        }
 
        internal static string IsValidCS(string identifier) {
            if (identifier == null || identifier.Length == 0 || identifier == " ") return identifier;
            string originalIdentifier = identifier;
            int index = identifier.IndexOf('[');
            string arraybrackets = null;
            if (index > -1)
            {
                arraybrackets = identifier.Substring(index);
                identifier = identifier.Substring(0,index);
                // Check arraybrackets
                for (int i=0; i<arraybrackets.Length; i++)
                {
                    switch(arraybrackets[i])
                    {
                    case '[':
                    case ']':
                    case ',':
                    case ' ':
                        break;
                    default:
                        throw new SUDSParserException(
                                             String.Format(CultureInfo.CurrentCulture, CoreChannel.GetResourceString("Remoting_Suds_WsdlInvalidStringSyntax"),
                                                           identifier));
                    }
                }
            }
 
            string[] names = identifier.Split(new char[] {'.'});
            bool newIdent = false;
            StringBuilder sb = new StringBuilder();
 
            for (int i = 0; i < names.Length; i++) 
            {
                if (i > 0) sb.Append(".");
                if (IsCSharpKeyword(names[i])) 
                {
                    sb.Append("@");
                    newIdent = true;
                }
                CheckValidIdentifier(names[i]);
                sb.Append(names[i]);
            }
 
            if (newIdent)
            {
                if (arraybrackets != null)
                    sb.Append(arraybrackets);
                return sb.ToString();
            }
            return originalIdentifier;
        }
 
 
        // Returns true if the atomized strings match
        private static bool MatchingStrings(String left, String right)
        {
            //Util.Log("WsdlParser.MatchingStrings left "+left+" right "+right);
            return((Object) left == (Object) right);
        }
 
        private bool MatchingSchemaStrings(String left)
        {
            Util.Log("WsdlParser.MatchingSchemaStrings left "+left+" _xsdVersion "+((Enum)_xsdVersion).ToString());
 
            if (MatchingStrings(left, s_schemaNamespaceString1999))
            {
                _xsdVersion = XsdVersion.V1999;
                return true;
            }
            else if (MatchingStrings(left, s_schemaNamespaceString2000))
            {
                _xsdVersion = XsdVersion.V2000;
                return true;
            }
            else if (MatchingStrings(left, s_schemaNamespaceString))
            {
                _xsdVersion = XsdVersion.V2001;
                return true;
            }
            else
                return false;
        }
 
        // Atmozie the given string
        internal String Atomize(String str)
        {
            // Always atmoize using the table defined on the
            // current XML parser
            return(_XMLReader.NameTable.Add(str));
        }
 
        // Maps URT types to CSharp types
        private String MapSchemaTypesToCSharpTypes(String xsdType)
        {
            Util.Log("SudsConverter.MapSchemaTypesToCSharpTypes Enter  "+xsdType);
            String stype = xsdType; 
            int index = xsdType.IndexOf('[');
            if (index != -1)
                stype = xsdType.Substring(0, index);
 
            String clrType = SudsConverter.MapXsdToClrTypes(stype);
 
            if (clrType == null)
                throw new SUDSParserException(
                                             String.Format(CultureInfo.CurrentCulture, CoreChannel.GetResourceString("Remoting_Suds_CantResolveTypeInNS"),
                                                           xsdType, s_schemaNamespaceString));
 
            // Handle array types
            if (index != -1)
                clrType = clrType + xsdType.Substring(index);
            Util.Log("SudsConverter.MapSchemaTypesToCSharpTypes Exit Type "+clrType);           
 
            return clrType;
        }
 
        // Return true if the given type is a primitive type
        private bool IsPrimitiveType(String typeNS, String typeName)
        {
            Util.Log("WsdlParser.IsPrimitiveType typeNS "+typeNS+" typeName "+typeName);            
            bool fReturn = false;
            if (MatchingSchemaStrings(typeNS))
            {
                if (!MatchingStrings(typeName, s_urTypeString))
                    fReturn = true;
            }
 
            return(fReturn);
        }
 
        // Looksup a matching namespace
        private URTNamespace LookupNamespace(String name)
        {
            Util.Log("WsdlParser.lookupNamespace name "+name+" number of NS "+_URTNamespaces.Count);            
            for (int i=0;i<_URTNamespaces.Count;i++)
            {
                URTNamespace urtNS = (URTNamespace) _URTNamespaces[i];
                if (WsdlParser.MatchingStrings(urtNS.Name, name))
                //Util.Log("WsdlParser.lookupNamespace search ns "+urtNS.Name+" input "+name);            
                //if (urtNS.Name == name)
                {
                    Util.Log("WsdlParser.lookupNamespace search ns found "+urtNS.GetHashCode()+" "+urtNS.Name+" input "+name);            
                    return(urtNS);
                }
            }
 
            Util.Log("WsdlParser.lookupNamespace search ns Not found "+name);            
            return(null);
        }
        
        // This routine is used when finding and creating namespaces during the resolve phase.
        // These references are from binding section which support encoded rpc. Any namespace
        // not referenced during this phase will be pruned before creating proxy. This will
        // prevent Types not used from being placed in the proxy.
        
        internal URTNamespace AddNewNamespace(String ns)
        {
            Util.Log("WsdlParser.AddNewNamespace name "+ns); 
            if (ns == null)
            return null;
 
            URTNamespace xns = LookupNamespace(ns);
            if (xns == null)
            {
            xns = new URTNamespace(ns, this);
            Util.Log("WsdlParser.AddNewNamespace new namespace "+ns);            
            }
            else
            {
            Util.Log("WsdlParser.AddNewNamespace existing namespace "+ns);            
            }
            if (!xns.IsSystem)
                xns.bReferenced= true;
            return xns;
        }
 
        internal void AddNamespace(URTNamespace xns)
        {
            //Util.Log("WsdlParser.AddNamespace "+xns.GetHashCode()+" "+xns.Namespace);
            _URTNamespaces.Add(xns);
        }       
 
        // Prints the parsed entities
        private void PrintCSC()
        {
            Util.Log("WsdlParser.PrintCSC ");
            int interopCount = 0;
 
            // For interop, recalculate the interop names
            for (int i=0;i<_URTNamespaces.Count;i++)
            {
                URTNamespace urtNS = (URTNamespace) _URTNamespaces[i];
                if (!urtNS.IsEmpty && urtNS.UrtType == UrtType.Interop)
                {
                    if (interopCount == 0)
                        urtNS.EncodedNS = _proxyNamespace;
                    else
                        urtNS.EncodedNS = _proxyNamespace+interopCount;
                    interopCount++;
                    Util.Log("WsdlParser.PrintCSC Interop "+urtNS.EncodedNS+" "+urtNS.Namespace+" urtType "+((Enum)urtNS.UrtType).ToString());                 
                }
            }
 
            for (int i=0;i<_URTNamespaces.Count;i++)
            {
                URTNamespace urtNS = (URTNamespace) _URTNamespaces[i];
                if (!urtNS.IsEmpty && !(urtNS.UrtType == UrtType.UrtSystem || urtNS.UrtType == UrtType.Xsd || urtNS.UrtType == UrtType.None))
                {
                    Util.Log("WsdlParser.PrintCSC fileName urtNS "+urtNS.Namespace+" urtType "+((Enum)urtNS.UrtType).ToString());                 
                    String fileName = urtNS.IsURTNamespace ? urtNS.AssemName : urtNS.EncodedNS;
                    int index = fileName.IndexOf(','); // reduce to simple assembly name
                    if (index > -1)
                    {
                        fileName = fileName.Substring(0,index);
                    }
                    Util.Log("WsdlParser.PrintCSC fileName "+fileName+" "+urtNS.Namespace);                 
                    String completeFileName = "";
 
                    WriterStream output = WriterStream.GetWriterStream(ref _writerStreams, _outputDir, fileName, ref completeFileName);
                    if (completeFileName.Length > 0)
                        _outCodeStreamList.Add(completeFileName);
                    urtNS.PrintCSC(output);
                }
            }
            return;
        }
 
        internal UrtType IsURTExportedType(String name, out String ns, out String assemName)
        {
            Util.Log("WsdlParser.IsURTExportedType Enter "+name);           
            //Console.WriteLine("Parsing " + name);
            UrtType urtType = UrtType.None;
            ns = null;
            assemName = null;
 
            if (MatchingSchemaStrings(name))
            {
                Util.Log("WsdlParser.IsURTExportedType trace 1 "+name);           
                urtType = UrtType.Xsd;
            }
            else
            {
                Util.Log("WsdlParser.IsURTExportedType trace 2 "+name);           
                if (SoapServices.IsClrTypeNamespace(name))
                {
                    SoapServices.DecodeXmlNamespaceForClrTypeNamespace(name, out ns, out assemName);
 
                    if (assemName == null)
                    {
                        assemName = typeof(String).Assembly.GetName().Name;
                        urtType = UrtType.UrtSystem;
                    }
                    else
                        urtType = UrtType.UrtUser;
                }
 
                if (urtType == UrtType.None)
                {
                    ns = name;
                    assemName = ns;
                    urtType = UrtType.Interop;
                }
 
                ns = Atomize(ns);
                assemName = Atomize(assemName);
            }
 
            //Console.WriteLine("NS: " + ns + " Assembly: " + assemName);
            Util.Log("WsdlParser.IsURTExportedType Exit "+((Enum)urtType).ToString());
            return(urtType);
        }
 
        internal String GetTypeString(String curNS, bool bNS, URTNamespace urtNS, String typeName, String typeNS) 
        {
            Util.Log("WsdlParser.GetTypeString Entry curNS "+curNS+" bNS "+bNS+" URTNamespace "+urtNS.Name+" typeName "+typeName+" typeNS "+typeNS);
            String type;
 
            URTComplexType ct = urtNS.LookupComplexType(typeName);
            if (ct != null && ct.IsArray())
            {
                if (ct.GetArray() == null)
                    ct.ResolveArray();
                String arrayName = ct.GetArray();
                URTNamespace arrayNS = ct.GetArrayNS();
                StringBuilder sb = new StringBuilder(50);
                if (arrayNS.EncodedNS != null && Qualify(urtNS.EncodedNS, arrayNS.EncodedNS))
                {
                    sb.Append(WsdlParser.IsValidCSAttr(arrayNS.EncodedNS));
                    sb.Append('.');
                }
                sb.Append(WsdlParser.IsValidCSAttr(arrayName));
                type = sb.ToString();
            }
            else
            {
                String encodedNS = null;
                if (urtNS.UrtType == UrtType.Interop)
                    encodedNS = urtNS.EncodedNS;
                else
                    encodedNS = typeNS;
 
                if (bNS && Qualify(encodedNS, curNS))
                {
                    StringBuilder sb = new StringBuilder(50);
                    if (encodedNS != null)
                    {
                        sb.Append(WsdlParser.IsValidCSAttr(encodedNS));
                        sb.Append('.');
                    }
                    sb.Append(WsdlParser.IsValidCSAttr(typeName));
                    type = sb.ToString();
                }
                else
                {
                    type = typeName;
                }
 
            }
 
            int index = type.IndexOf('+');
            if (index > 0)
            {
                // nested type, replace + with . Should be done earlier when forming names
                if (bNS)
                    type = type.Replace('+', '.');
                else
                    type = type.Substring(0,index);
            }
 
 
            Util.Log("WsdlParser.GetTypeString Exit type "+type);              
            return(type);
        }
 
 
        // Creates and initializes the name table if neccessary
        static private XmlNameTable CreatePrimedNametable()
        {
            Util.Log("WsdlParser.CreatePrimedNametable");           
 
            //Interlocked.Increment(ref s_counter);
            /*if(s_atomizedTable == null)
            {
            // Create a new nametable
            //MTNameTable newTable = new MTNameTable(true);
            }*/
            NameTable newTable = new NameTable();
 
            // Atomically update static location to point to the current table
            /*Object oldTable = Interlocked.CompareExchange(ref s_atomizedTable, newTable, null);
            if(oldTable != null)
            newTable = (MTNameTable) oldTable; */
 
            // Atomize frequently used strings for perf
            // The following ops are not done inside a lock as they are idempotent
            s_emptyString = newTable.Add(String.Empty);
            s_complexTypeString = newTable.Add("complexType");
            s_simpleTypeString = newTable.Add("simpleType");
            s_elementString = newTable.Add("element");
            s_enumerationString = newTable.Add("enumeration");
            s_encodingString = newTable.Add("encoding");
            s_attributeString = newTable.Add("attribute");
            s_attributesString = newTable.Add("attributes");
            s_allString = newTable.Add("all");
            s_sequenceString = newTable.Add("sequence");
            s_choiceString = newTable.Add("choice");
            s_minOccursString = newTable.Add("minOccurs");
            s_maxOccursString = newTable.Add("maxOccurs");
            s_unboundedString = newTable.Add("unbounded");
            s_oneString = newTable.Add("1");
            s_zeroString = newTable.Add("0");
            s_nameString = newTable.Add("name");
            s_typeString = newTable.Add("type");
            s_baseString = newTable.Add("base");
            s_valueString = newTable.Add("value");
            s_interfaceString = newTable.Add("interface");
            s_serviceString = newTable.Add("service");
            s_extendsString = newTable.Add("extends");
            s_addressesString = newTable.Add("addresses");
            s_addressString = newTable.Add("address");
            s_uriString = newTable.Add("uri");
            s_implementsString = newTable.Add("implements");
            s_nestedTypeString = newTable.Add("nestedType");
            s_requestString = newTable.Add("request");
            s_responseString = newTable.Add("response");
            s_requestResponseString = newTable.Add("requestResponse");
            s_messageString = newTable.Add("message");
            s_locationString = newTable.Add("location");
            s_schemaLocationString = newTable.Add("schemaLocation");
            s_importString = newTable.Add("import");
            s_onewayString = newTable.Add("oneway");
            s_includeString = newTable.Add("include");
            s_refString = newTable.Add("ref");
            s_refTypeString = newTable.Add("refType");
            s_referenceString = newTable.Add("Reference");
            s_objectString = newTable.Add("Object");
            s_urTypeString = newTable.Add("anyType");
            s_arrayString = newTable.Add("Array");
            s_sudsString = newTable.Add("suds");
            s_methodString = newTable.Add("method");
            s_useString = newTable.Add("use");
            s_rootTypeString = newTable.Add("rootType");
            s_soapString = newTable.Add("soap");
            s_serviceDescString = newTable.Add("serviceDescription");
            s_schemaString = newTable.Add("schema");
            s_targetNamespaceString = newTable.Add("targetNamespace");
            s_namespaceString = newTable.Add("namespace");
            s_idString = newTable.Add("ID");
            s_soapActionString = newTable.Add("soapAction");
            s_schemaNamespaceString1999 = newTable.Add(SudsConverter.Xsd1999);
            s_instanceNamespaceString1999 = newTable.Add(SudsConverter.Xsi1999);
            s_schemaNamespaceString2000 = newTable.Add(SudsConverter.Xsd2000);
            s_instanceNamespaceString2000 = newTable.Add(SudsConverter.Xsi2000);
            s_schemaNamespaceString = newTable.Add(SudsConverter.Xsd2001);
            s_instanceNamespaceString = newTable.Add(SudsConverter.Xsi2001);
            s_soapNamespaceString = newTable.Add("urn:schemas-xmlsoap-org:soap.v1");
            //s_sudsNamespaceString = newTable.Add("urn:schemas-xmlsoap-org:suds.v1");
            s_sudsNamespaceString = newTable.Add("urn:schemas-xmlsoap-org:soap-sdl-2000-01-25");
            //s_URTNamespaceString = newTable.Add("urn:schamas-xmlsoap-org:urt.v1");
            //s_serviceNamespaceString = newTable.Add("urn:schemas-xmlsoap-org:servicedesc.v1");
            s_serviceNamespaceString = newTable.Add("urn:schemas-xmlsoap-org:sdl.2000-01-25");
 
            // Wsdl strings
            s_definitionsString = newTable.Add("definitions");
            s_wsdlNamespaceString = newTable.Add("http://schemas.xmlsoap.org/wsdl/");
            s_wsdlSoapNamespaceString = newTable.Add("http://schemas.xmlsoap.org/wsdl/soap/");
            s_wsdlSudsNamespaceString = newTable.Add("http://www.w3.org/2000/wsdl/suds");
            s_enumTypeString = newTable.Add("enumType");
            s_typesString = newTable.Add("types");
            s_partString = newTable.Add("part");
            s_portTypeString = newTable.Add("portType");
            s_operationString = newTable.Add("operation");
            s_inputString = newTable.Add("input");
            s_outputString = newTable.Add("output");
            s_bindingString = newTable.Add("binding");
            s_classString = newTable.Add("class");
            s_structString = newTable.Add("struct");
            s_ISerializableString = newTable.Add("ISerializable");
            s_marshalByRefString = newTable.Add("MarshalByRefObject");
            s_delegateString = newTable.Add("Delegate");
            s_servicedComponentString = newTable.Add("ServicedComponent");
            s_comObjectString = newTable.Add("__ComObject");
            s_portString = newTable.Add("port");
            s_styleString = newTable.Add("style");
            s_transportString = newTable.Add("transport");
            s_encodedString = newTable.Add("encoded");
            s_faultString = newTable.Add("fault");
            s_bodyString = newTable.Add("body");
            s_partsString = newTable.Add("parts");
            s_headerString = newTable.Add("header");
            s_encodingStyleString = newTable.Add("encodingStyle");                                  
            s_restrictionString = newTable.Add("restriction");                                  
            s_complexContentString = newTable.Add("complexContent");
            s_soapEncodingString = newTable.Add("http://schemas.xmlsoap.org/soap/encoding/");
            s_arrayTypeString = newTable.Add("arrayType");
            s_parameterOrderString = newTable.Add("parameterOrder");
 
 
            return((XmlNameTable) newTable);
 
            // Enqueue a timer if it has not already been done
            /*Timer timer = new Timer(new TimerCallback(Cleanup), null, 1000, 1000);
            Object existingTimer = Interlocked.CompareExchange(ref s_enqueuedTimer, timer, null);
            if(existingTimer != null)
            timer.Dispose(); */
            //}
 
            //return((XmlNameTable) s_atomizedTable);
        }
 
        // Private fields
        private XmlTextReader _XMLReader;
        private ArrayList _URTNamespaces;       
        private ReaderStream _parsingInput;
        internal bool _bWrappedProxy;
        private String _proxyNamespace;
        private int _proxyNamespaceCount = 0;
        private ReaderStream _readerStreamsWsdl;
        private ReaderStream _readerStreamsXsd;
        private String _outputDir;
        private ArrayList _outCodeStreamList;
        private WriterStream _writerStreams;
        private SchemaBlockType _blockDefault;
        private XsdVersion _xsdVersion;
        private Hashtable wsdlMessages = new Hashtable(10);
        private Hashtable wsdlPortTypes = new Hashtable(10);
        private ArrayList wsdlBindings = new ArrayList(10);
        private ArrayList wsdlServices = new ArrayList(10);
        private Stack _currentReaderStack = new Stack(5);
        private Stack _currentSchemaReaderStack = new Stack(5);
        private XmlNameTable _primedNametable = null;
 
 
        //static private Object s_atomizedTable = null;
        //static private int s_counter = 0;
        //static private Object s_enqueuedTimer = null;
        static private String s_emptyString;
        static private String s_complexTypeString;
        static private String s_simpleTypeString;
        static private String s_elementString;
        static private String s_enumerationString;
        static private String s_encodingString;
        static private String s_attributeString;
        static private String s_attributesString;
        static private String s_allString;
        static private String s_sequenceString;
        static private String s_choiceString;
        static private String s_minOccursString;
        static private String s_maxOccursString;
        static private String s_unboundedString;
        static private String s_oneString;
        static private String s_zeroString;
        static private String s_nameString;
        static private String s_enumTypeString;
        static private String s_typeString;
        static private String s_baseString;
        static private String s_valueString;
        static private String s_interfaceString;
        static private String s_serviceString;
        static private String s_extendsString;
        static private String s_addressesString;
        static private String s_addressString;
        static private String s_uriString;
        static private String s_implementsString;
        static private String s_nestedTypeString;
        static private String s_requestString;
        static private String s_responseString;
        static private String s_requestResponseString;
        static private String s_messageString;
        static private String s_locationString;
        static private String s_schemaLocationString;
        static private String s_importString;
        static private String s_includeString;      
        static private String s_onewayString;
        static private String s_refString;
        static private String s_refTypeString;
        static private String s_referenceString;
        static private String s_arrayString;
        static private String s_objectString;
        static private String s_urTypeString;
        static private String s_methodString;
        static private String s_sudsString;
        static private String s_useString;
        static private String s_rootTypeString;
        static private String s_soapString;
        static private String s_serviceDescString;
        static private String s_schemaString;
        static private String s_targetNamespaceString;
        static private String s_namespaceString;
        static private String s_idString;
        static private String s_soapActionString;
        static private String s_instanceNamespaceString;
        static private String s_schemaNamespaceString;
        static private String s_instanceNamespaceString1999;
        static private String s_schemaNamespaceString1999;
        static private String s_instanceNamespaceString2000;
        static private String s_schemaNamespaceString2000;
        static private String s_soapNamespaceString;
        static private String s_sudsNamespaceString;
        static private String s_serviceNamespaceString;
 
        //Wsdl
        static private String s_definitionsString;
        static private String s_wsdlNamespaceString;
        static private String s_wsdlSoapNamespaceString;
        static private String s_wsdlSudsNamespaceString;
        static private String s_typesString;
        static private String s_partString;
        static private String s_portTypeString;
        static private String s_operationString;
        static private String s_inputString;
        static private String s_outputString;
        static private String s_bindingString;
        static private String s_classString;
        static private String s_structString;
        static private String s_ISerializableString;
        static private String s_marshalByRefString;
        static private String s_delegateString;
        static private String s_servicedComponentString;
        static private String s_comObjectString;
        static private String s_portString;
        static private String s_styleString;
        static private String s_transportString;
        static private String s_encodedString;
        static private String s_faultString;
        static private String s_bodyString;
        static private String s_partsString;
        static private String s_headerString;
        static private String s_encodingStyleString;        
        static private String s_restrictionString;        
        static private String s_complexContentString;        
        static private String s_soapEncodingString;        
        static private String s_arrayTypeString;        
        static private String s_parameterOrderString;
 
 
 
        /***************************************************************
         **
         ** Private classes used by SUDS Parser
         **
         ***************************************************************/
        // Input streams
        internal class ReaderStream
        {
            internal ReaderStream(String location)
            {
                Util.Log("ReaderStream.ReaderStream "+location);
                _location = location;
                _name = String.Empty;
                _targetNS = String.Empty;
                _uniqueNS = null;
                _reader = null;
                _next = null;
            }
            internal String Location
            {
                get { return(_location);}
                set { _location = value;}                
            }
            internal String Name
            {
                set { _name = value;}
            }
            internal String TargetNS
            {
                get { return(_targetNS);}
                set { _targetNS = value;}
            }
            internal URTNamespace UniqueNS
            {
                get { return(_uniqueNS);}
                set { _uniqueNS = value;}
            }
            internal TextReader InputStream
            {
                get { return(_reader);}
                set { _reader = value;}
            }
            internal Uri Uri
            {
                get { return(_uri);}
                set { _uri = value;}
            }
 
            internal static void GetReaderStream(ReaderStream inputStreams, ReaderStream newStream)
            {
                Util.Log("ReaderStream.GetReaderStream "+newStream.Location);             
                ReaderStream input = inputStreams;
                ReaderStream last;
                do
                {
                    Util.Log("ReaderStream.GetReaderStream location match input.location "+input._location+" location "+newStream.Location);             
                    if (input._location == newStream.Location)
                        return;
                    last = input;
                    input = input._next;
                } while (input != null);
 
                input = newStream;
                last._next = input;
 
                return;
            }
            internal static ReaderStream GetNextReaderStream(ReaderStream input)
            {
                Util.Log("ReaderStream.GetNextReaderStream "+input._next);
                return input._next;
            }
 
            private String _location;
            private String _name;
            private String _targetNS;
            private URTNamespace _uniqueNS;
            private TextReader _reader;
            private ReaderStream _next;
            private Uri _uri;            
        }
 
        internal class WriterStream
        {
 
            private WriterStream(String fileName, TextWriter writer)
            {
                Util.Log("WriterStream.WriterStream "+fileName);                
                _fileName = fileName;
                _writer = writer;
            }
            internal TextWriter OutputStream
            {
                get { return(_writer);}
            }
                        
            internal bool GetWrittenTo()
            {
                return _bWrittenTo;
 
            }
 
            internal void SetWrittenTo()
            {
                _bWrittenTo = true;
            }
 
            internal static void Flush(WriterStream writerStream)
            {
                while (writerStream != null)
                {
                    writerStream._writer.Flush();
                    writerStream = writerStream._next;
                }
 
                return;
            }
            
            internal static WriterStream GetWriterStream(ref WriterStream outputStreams, String outputDir, String fileName, ref String completeFileName)
            {
                Util.Log("WriterStream.GetWriterStream "+fileName);                             
                WriterStream output = outputStreams;
                while (output != null)
                {
                    if (output._fileName == fileName)
                        return(output);
                    output = output._next;
                }
 
                String diskFileName = fileName;
                if (diskFileName.EndsWith(".exe", StringComparison.Ordinal) || diskFileName.EndsWith(".dll", StringComparison.Ordinal))
                    diskFileName = diskFileName.Substring(0, diskFileName.Length - 4);
                String _completeFileName = outputDir + diskFileName + ".cs";
                completeFileName = _completeFileName;
                //TextWriter textWriter = new StreamWriter(outputDir + fileName + ".cs", false);
                TextWriter textWriter = new StreamWriter(_completeFileName, false, new UTF8Encoding(false));
                output = new WriterStream(fileName, textWriter);
                output._next = outputStreams;
                outputStreams = output;
                Util.Log("WriterStream.GetWriterStream in fileName "+fileName+" completeFileName "+_completeFileName);                              
                return(output);
            }
 
            internal static void Close(WriterStream outputStreams)
            {
                WriterStream output = outputStreams;
                while (output != null)
                {
                    output._writer.Close();
                    output = output._next;
                }
            }
 
            private String _fileName;
            private TextWriter _writer;
            private WriterStream _next;
            private bool _bWrittenTo = false;            
        }
 
        // Represents a parameter of a method
        [Serializable]
        internal enum URTParamType
        {
            IN, OUT, REF
        }
        internal class URTParam
        {
            internal URTParam(String name, String typeName, String typeNS, String encodedNS,
                              URTParamType pType, bool bEmbedded, WsdlParser parser, URTNamespace urtNamespace)
            {
                Util.Log("URTParam.URTParam name "+name+" typeName "+typeName+" typeNS "+typeNS+" ecodedNS "+encodedNS+" pType "+pType+" bEmbedded "+bEmbedded);
                _name = name;
                _typeName = typeName;
                _typeNS = typeNS;
                _encodedNS = encodedNS;
                _pType = pType;
                _embeddedParam = bEmbedded;
                _parser = parser;
                _urtNamespace = urtNamespace;
 
            }
            public override bool Equals(Object obj)
            {
                //Util.Log("URTParam.Equals ");
                URTParam suppliedParam = (URTParam) obj;
                if (_pType == suppliedParam._pType &&
                    WsdlParser.MatchingStrings(_typeName, suppliedParam._typeName) &&
                    WsdlParser.MatchingStrings(_typeNS, suppliedParam._typeNS))
                    return(true);
 
                return(false);
            }
 
 
            public override int GetHashCode()
            {
                return base.GetHashCode();
            }
            internal URTParamType ParamType
            {
                get { return(_pType);}
                set { _pType = value;}
            }
            internal String Name
            {
                get { return(_name);}
            }
            internal String TypeName
            {
                get { return(_typeName);}
            }
            internal String TypeNS
            {
                get { return(_typeNS);}
            }
 
            internal String GetTypeString(String curNS, bool bNS)
            {
                return _parser.GetTypeString(curNS, bNS, _urtNamespace, _typeName, _encodedNS);
            }
 
            internal void PrintCSC( StringBuilder sb, String curNS)
            {
                Util.Log("URTParam.PrintCSC curNS "+curNS+" name "+_name);                                              
                //if(_embeddedParam)
                //    sb.Append("[Embedded] ");
                sb.Append(PTypeString[(int) _pType]);
                sb.Append(GetTypeString(curNS, true));
                sb.Append(' ');
                sb.Append(WsdlParser.IsValidCS(_name));
                return;
            }
            internal void PrintCSC(StringBuilder sb)
            {
                Util.Log("URTParam.PrintCSC name "+_name);                                              
                sb.Append(PTypeString[(int) _pType]);
                sb.Append(WsdlParser.IsValidCS(_name));
                return;
            }
 
            static private String[] PTypeString = { "", "out ", "ref "};
            private String _name;
            private String _typeName;
            private String _typeNS;
            private String _encodedNS;
            private URTParamType _pType;
            private bool _embeddedParam;
            private URTNamespace _urtNamespace;
            private WsdlParser _parser;
        }
 
        [Flags]
        internal enum MethodPrintEnum
        {
            PrintBody = 0x1,
            InterfaceMethods = 0x2,
            InterfaceInClass = 0x4,
        }
 
        [Flags]
        internal enum MethodFlags
        {
            None = 0x0,
            Public = 0x1,
            Protected = 0x2,
            Override = 0x4,
            New = 0x8,
            Virtual = 0x10,
            Internal = 0x20,
        }
 
 
        // Represents a method
        internal abstract class URTMethod
        {
 
            internal static bool FlagTest(MethodPrintEnum flag, MethodPrintEnum target)
            {
                if ((flag & target) == target)
                    return true;
                else
                    return false;
            }
 
            internal static bool MethodFlagsTest(MethodFlags flag, MethodFlags target)
            {
                if ((flag & target) == target)
                    return true;
                else
                    return false;
            }
 
            internal URTMethod(String name, String soapAction, String methodAttributes, URTComplexType complexType)
            {
                Util.Log("URTMethod.URTMethod name "+name+" soapAction "+soapAction+" attributes "+methodAttributes+" complexType "+complexType);
                _methodName = name;
                _soapAction = soapAction;
                _methodType = null;
                _complexType = complexType;
                int index = name.IndexOf('.');
                _methodFlags = MethodFlags.None;
 
                // set method flags
                if (methodAttributes != null && methodAttributes.Length > 0)
                {
                    String[] attributes = methodAttributes.Split(' ');
                    foreach (String attribute in attributes)
                    {
                        if (attribute == "virtual")
                            _methodFlags |= MethodFlags.Virtual;
                        if (attribute == "new")
                            _methodFlags |= MethodFlags.New;
                        if (attribute == "override")
                            _methodFlags |= MethodFlags.Override;
                        if (attribute == "public")
                            _methodFlags |= MethodFlags.Public;
                        if (attribute == "protected")
                            _methodFlags |= MethodFlags.Protected;
                        if (attribute == "internal")
                            _methodFlags |= MethodFlags.Internal;
                    }
                }
 
                Util.Log("URTMethod.URTMethod methodFlags "+((Enum)_methodFlags).ToString());
            }
 
 
            internal String Name
            {
                get { return(_methodName);}
            }
 
            internal String SoapAction
            {
                get { return(_soapAction);}
            }
            internal MethodFlags MethodFlags
            {
                get { return(_methodFlags);}
                set { _methodFlags = value;}
            }
 
            internal String GetTypeString(String curNS, bool bNS)
            {
                Util.Log("URTMethod.GetTypeString curNS "+curNS+" bNS "+bNS);
                return((_methodType != null) ? _methodType.GetTypeString(curNS, bNS) : "void");
            }
            protected URTParam MethodType
            {
                get { return(_methodType);}
            }
            public override int GetHashCode()
            {
                return base.GetHashCode();
            }           
            public override bool Equals(Object obj)
            {
                URTMethod suppliedMethod = (URTMethod) obj;
                if (WsdlParser.MatchingStrings(_methodName, suppliedMethod._methodName) &&
                    _params.Count == suppliedMethod._params.Count)
                {
                    for (int i=0;i<_params.Count;i++)
                    {
                        if (_params[i].Equals(suppliedMethod._params[i]) == false)
                            return(false);
                    }
 
                    return(true);
                }
 
                return(false);
            }
            internal MethodFlags GetMethodFlags(MethodInfo method)
            {
                return(_methodFlags);
            }
 
            internal void AddParam(URTParam newParam)
            {
                Util.Log("URTMethod.AddParam "+newParam.Name);
                for (int i=0;i<_params.Count;i++)
                {
                    URTParam extParam = (URTParam) _params[i];
                    if (WsdlParser.MatchingStrings(extParam.Name, newParam.Name))
                    {
                        if (extParam.ParamType == URTParamType.IN &&
                            newParam.ParamType == URTParamType.OUT &&
                            WsdlParser.MatchingStrings(extParam.TypeName, newParam.TypeName) &&
                            WsdlParser.MatchingStrings(extParam.TypeNS, newParam.TypeNS))
                        {
                            extParam.ParamType = URTParamType.REF;
                            return;
                        }
 
                        throw new SUDSParserException(CoreChannel.GetResourceString("Remoting_Suds_DuplicateParameter"));
                    }
                }
 
                // Find parameter position
                int paramPosition = -1;
                if (_paramNamesOrder != null)
                {
                    // Parameter order find the parameter position or determine if the parameter is a return value
                    for (int i=0; i<_paramNamesOrder.Length; i++)
                    {
                        if (_paramNamesOrder[i] == newParam.Name)
                        {
                            paramPosition = i;
                            break;
                        }
                    }
 
                    if (paramPosition == -1)
                    {
                        // return value
                        _methodType = newParam;
                    }
                    else
                    {
                        // Parameter, add the correct position
                        //_params[paramPosition] = newParam; // _params array list is the size of the parameters.
                        _params.Add(newParam);
                        _paramPosition.Add(paramPosition);
                    }
                }
                else
                {
                    // no parameterOrder in wsdl, do the best we can to determine if there is a return value
                    if ((_methodType == null) && (newParam.ParamType == URTParamType.OUT))
                    {
                        // return value
                        _methodType = newParam;
                    }
                    else
                    {
                        // parameter put as the next parameter
                        _params.Add(newParam);
                    }
                }
            }
 
            internal void ResolveMethodAttributes()
            {
                Util.Log("URTMethod.ResolveMethodAttributes "+Name+" MethodFlags "+((Enum)_methodFlags).ToString());
                if (!(MethodFlagsTest(_methodFlags,MethodFlags.Override) || MethodFlagsTest(_methodFlags,MethodFlags.New)))
                    FindMethodAttributes();
            }
 
            private void FindMethodAttributes()
            {
                Util.Log("URTMethod.FindMethodAttributes "+Name+" complexType "+_complexType);
                if (_complexType == null)
                    return;
 
                Util.Log("URTMethod.FindMethodAttributes "+_complexType.Name);
 
                ArrayList inherit = _complexType.Inherit;
                Type baseType = null;
                if (inherit == null)
                {
                    inherit = new ArrayList();
                    if (_complexType.SUDSType == SUDSType.ClientProxy)
                        baseType = typeof(System.Runtime.Remoting.Services.RemotingClientProxy);
                    else if (_complexType.SudsUse == SudsUse.MarshalByRef)
                        baseType = typeof(MarshalByRefObject);
                    else if (_complexType.SudsUse == SudsUse.ServicedComponent)
                        baseType = typeof(MarshalByRefObject);
 
                    if (baseType == null)
                        return;
 
                    while (baseType != null)
                    {
                        Util.Log("URTMethod.FindMethodAttributes baseType Enter "+baseType);
                        inherit.Add(baseType);
                        baseType = baseType.BaseType;
                    }
 
                    _complexType.Inherit = inherit;
                }
 
                BindingFlags bFlags = BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
 
                bool bVirtual = MethodFlagsTest(_methodFlags, MethodFlags.Virtual);
                Util.Log("URTMethod.FindMethodAttributes "+Name+" bVirtual "+bVirtual);
 
                // See if method hides inherited methods
                bool bfound = false;
                for (int j=0; j<inherit.Count; j++)
                {
                    baseType = (Type)inherit[j];
                    MethodInfo[] baseInfos = null;
                    try
                    {
                        MethodInfo methodInfo = baseType.GetMethod(Name, bFlags);
                        if (methodInfo != null)
                        {
                            baseInfos = new MethodInfo[1];
                            baseInfos[0] = methodInfo;
                        }
                    }
                    catch {
                        // Ambiguous match, overloaded methos
                        baseInfos = baseType.GetMethods(bFlags);
                    }
 
                    if (baseInfos != null)
                    {
                        foreach (MethodBase baseInfo in baseInfos)
                        {
                            if (baseInfo != null && 
                                baseInfo.Name == Name && 
                                (baseInfo.IsFamily || baseInfo.IsPublic || baseInfo.IsAssembly) 
                                && IsSignature(baseInfo))
                            {
                                bfound = true;
 
                                // Change attribute to match new hiearchy
                                if (!baseInfo.IsPublic)
                                {
                                    if (baseInfo.IsAssembly)
                                    {
                                        _methodFlags &= ~(MethodFlags.Public);
                                        _methodFlags |= MethodFlags.Internal;
                                    }
                                    else if (baseInfo.IsFamily)
                                    {
                                        _methodFlags &= ~(MethodFlags.Public);
                                        _methodFlags |= MethodFlags.Protected;
                                    }
                                }
 
                                // Hides
                                if (baseInfo.IsFinal)
                                    _methodFlags |= MethodFlags.New;
                                else if (baseInfo.IsVirtual && bVirtual)
                                    _methodFlags |= MethodFlags.Override;
                                else
                                    _methodFlags |= MethodFlags.New;
                                break;
                            }
                        }
                    }
                    if (bfound)
                        break;
                }
 
                Util.Log("URTMethod.FindMethodAttributes Exit "+Name+" "+((Enum)_methodFlags).ToString());
            }
 
            private bool IsSignature(MethodBase baseInfo)
            {
                ParameterInfo[] paramInfos = baseInfo.GetParameters();
                Util.Log("URTMethod.IsSignature  param length "+paramInfos.Length+" URTParams length "+_params.Count);
 
                if (_params.Count != paramInfos.Length)
                    return false;
 
                bool bsig = true;
 
                for (int i=0; i<paramInfos.Length; i++)
                {
                    URTParam param = (URTParam)_params[i];
                    if (param.GetTypeString(null, true) != paramInfos[i].ParameterType.FullName)
                    {
                        bsig = false;
                        break;
 
                    }
                }
 
                return bsig;
            }
 
            internal void PrintSignature(StringBuilder sb, String curNS)
            {
                Util.Log("URTMethod.PrintSignature curNS "+curNS);              
                for (int i=0;i<_params.Count;i++)
                {
                    if (i != 0)
                        sb.Append(", ");
                    Util.Log("URTMethod.PrintSignature Invoke _params PrintCSC");                               
                    ((URTParam) _params[i]).PrintCSC(sb, curNS);
                }
 
                return;
            }
            /*
            internal abstract void PrintCSC(TextWriter textWriter, String indentation,
                                            String namePrefix, String curNS, MethodPrintEnum methodPrintEnum,
                                            bool bURTType, String bodyPrefix, StringBuilder sb);
                                            */
 
            internal virtual void PrintCSC(TextWriter textWriter, String indentation,
                                           String namePrefix, String curNS, MethodPrintEnum methodPrintEnum, bool bURTType,
                                           String bodyPrefix, StringBuilder sb)
            {
                Util.Log("URTMethod.PrintCSC name "+_methodName+" namePrefix "+namePrefix+" curNS "+curNS+" MethodPrintEnum "+((Enum)methodPrintEnum).ToString());
 
                // Check for class methods
                sb.Length = 0;
                sb.Append(indentation);
 
                if (Name == "Finalize")
                    return;
 
                if (FlagTest(methodPrintEnum, MethodPrintEnum.InterfaceInClass))
                    sb.Append("public ");
                else if (MethodFlagsTest(_methodFlags, MethodFlags.Public))
                    sb.Append("public ");
                else if (MethodFlagsTest(_methodFlags, MethodFlags.Protected))
                    sb.Append("protected ");
                else if (MethodFlagsTest(_methodFlags, MethodFlags.Internal))
                    sb.Append("internal ");
 
                if (MethodFlagsTest(_methodFlags, MethodFlags.Override))
                    sb.Append("override ");
 
                else if (MethodFlagsTest(_methodFlags, MethodFlags.Virtual))
                    sb.Append("virtual ");
 
                if (MethodFlagsTest(_methodFlags, MethodFlags.New))
                    sb.Append("new ");
 
                sb.Append(WsdlParser.IsValidCSAttr(GetTypeString(curNS, true)));
 
                if (FlagTest(methodPrintEnum, MethodPrintEnum.InterfaceInClass))
                    sb.Append(" ");
                else
                    sb.Append(WsdlParser.IsValidCSAttr(namePrefix));
                if (_wsdlMethodInfo.bProperty)
                    sb.Append(WsdlParser.IsValidCS(_wsdlMethodInfo.propertyName));
                else
                {
                    sb.Append(WsdlParser.IsValidCS(_methodName));
 
                    sb.Append('(');
                    if (_params.Count > 0)
                    {
                        Util.Log("URTMethod.PrintCSC Invoke _params[0] 1 PrintCSC");
                        ((URTParam) _params[0]).PrintCSC(sb, curNS);
                        for (int i=1;i<_params.Count;i++)
                        {
                            sb.Append(", ");
                            Util.Log("URTMethod.PrintCSC Invoke _params 2 PrintCSC "+i);                       
                            ((URTParam) _params[i]).PrintCSC(sb, curNS);
                        }
                    }
                    sb.Append(')');
                }
 
                if (_wsdlMethodInfo.bProperty && FlagTest(methodPrintEnum, MethodPrintEnum.InterfaceMethods))
                {
                    sb.Append("{");
                    if (_wsdlMethodInfo.bGet)
                        sb.Append(" get; ");
                    if (_wsdlMethodInfo.bSet)
                        sb.Append(" set; ");
                    sb.Append("}");
                }
                else if (!FlagTest(methodPrintEnum, MethodPrintEnum.PrintBody))
                    sb.Append(';');
 
                textWriter.WriteLine(sb); 
 
                if (_wsdlMethodInfo.bProperty && FlagTest(methodPrintEnum, MethodPrintEnum.PrintBody))
                    PrintPropertyBody(textWriter,indentation, sb, bodyPrefix);
 
                else if (FlagTest(methodPrintEnum, MethodPrintEnum.PrintBody))
                {
                    sb.Length = 0;
                    sb.Append(indentation);
                    sb.Append('{');
                    textWriter.WriteLine(sb);
 
                    String newIndentation = indentation + "    ";
                    if (bodyPrefix == null)
                    {
                        for (int i=0;i<_params.Count;i++)
                        {
                            URTParam param = (URTParam) _params[i];
                            if (param.ParamType == URTParamType.OUT)
                            {
                                sb.Length = 0;
                                sb.Append(newIndentation);
                                sb.Append(WsdlParser.IsValidCS(param.Name));
                                sb.Append(" = ");
                                sb.Append(ValueString(param.GetTypeString(curNS, true)));
                                sb.Append(';');
                                textWriter.WriteLine(sb);
                            }
                        }
                        Util.Log("URTMethod.PrintCSC return print");
                        sb.Length = 0;
                        sb.Append(newIndentation);
                        sb.Append("return");
                        String returnString = ValueString(GetTypeString(curNS, true));
                        if (returnString != null)
                        {
                            sb.Append('(');
                            sb.Append(returnString);
                            sb.Append(')');
                        }
                        sb.Append(';');
                    }
                    else
                    {
                        sb.Length = 0;
                        sb.Append(newIndentation);
                        if (ValueString(GetTypeString(curNS, true)) != null)
                            sb.Append("return ");
                        PrintMethodName(sb, bodyPrefix, _methodName);
                        //sb.Append(bodyPrefix);
                        //sb.Append(_methodName);
                        sb.Append('(');
                        if (_params.Count > 0)
                        {
                            Util.Log("URTMethod.PrintCSC Invoke _params[0] 3 PrintCSC");                                                    
                            ((URTParam) _params[0]).PrintCSC(sb);
                            for (int i=1;i<_params.Count;i++)
                            {
                                sb.Append(", ");
                                Util.Log("URTMethod.PrintCSC Invoke _params 4 PrintCSC");                                                       
                                ((URTParam) _params[i]).PrintCSC(sb);
                            }
                        }
                        sb.Append(");");
                    }
                    textWriter.WriteLine(sb);
 
                    textWriter.Write(indentation);
                    textWriter.WriteLine('}');
                }
            }
 
            private void PrintSoapAction(String action, StringBuilder sb)
            {
                sb.Append("[SoapMethod(SoapAction=");
                sb.Append(WsdlParser.IsValidUrl(action));
                sb.Append(")]");
            }
 
            private void PrintPropertyBody(TextWriter textWriter, String indentation, StringBuilder sb, String bodyPrefix)
            {
#if false
                [SoapMethod(SoapAction="http://schemas.microsoft.com/clr/nsassem/Testing.TestSimpleObject/test12#get_Value")]
                get{return ((TestSimpleObject) _tp).Value;}
 
                [SoapMethod(SoapAction="http://schemas.microsoft.com/clr/nsassem/Testing.TestSimpleObject/test12#set_Value")]
                set{((TestSimpleObject) _tp).Value = value;}
#endif
 
                sb.Length = 0;
                sb.Append(indentation);
                sb.Append('{');
                textWriter.WriteLine(sb);
 
                String newIndentation = indentation + "    ";
                sb.Length = 0;
                sb.Append(newIndentation);
                if (_wsdlMethodInfo.bGet)
                {
                    sb.Length = 0;
                    sb.Append(newIndentation);
                    PrintSoapAction(_wsdlMethodInfo.soapActionGet, sb);
                    textWriter.WriteLine(sb);
 
                    sb.Length = 0;
                    sb.Append(newIndentation);
                    sb.Append("get{return ");
                    PrintMethodName(sb, bodyPrefix, _wsdlMethodInfo.propertyName);
                    //sb.Append(bodyPrefix);
                    //sb.Append(_wsdlMethodInfo.propertyName);
                    sb.Append(";}");
                    textWriter.WriteLine(sb);
                }
 
                if (_wsdlMethodInfo.bSet)
                {
                    if (_wsdlMethodInfo.bGet)
                        textWriter.WriteLine();
 
                    sb.Length = 0;
                    sb.Append(newIndentation);
                    PrintSoapAction(_wsdlMethodInfo.soapActionSet, sb);
                    textWriter.WriteLine(sb);
 
                    sb.Length = 0;
                    sb.Append(newIndentation);
                    sb.Append("set{");
                    PrintMethodName(sb, bodyPrefix, _wsdlMethodInfo.propertyName);
                    //sb.Append(bodyPrefix);
                    //sb.Append(_wsdlMethodInfo.propertyName);
                    sb.Append("= value;}");
                    textWriter.WriteLine(sb);
                }
 
                sb.Length = 0;
                sb.Append(indentation);
                sb.Append('}');
                textWriter.WriteLine(sb);
            }
 
            private void PrintMethodName(StringBuilder sb, String bodyPrefix, String name)
            {
                int index = name.LastIndexOf('.');
                if (index < 0)
                {
                    sb.Append(bodyPrefix);
                    sb.Append(WsdlParser.IsValidCS(name));
                }
                else
                {
                    // interface name, need to reconstruct bodyPrefix and strip name qualifier
                    String iface = name.Substring(0,index);
                    String methodName = name.Substring(index+1);
                    if (bodyPrefix == null)
                    {
                        // Non-wrapped proxy
                        sb.Append("(");
                        sb.Append(WsdlParser.IsValidCS(iface));
                        sb.Append(")");
                        sb.Append(WsdlParser.IsValidCS(methodName));
                    }
                    else
                    {
                        // wrapped proxy
                        sb.Append("((");
                        sb.Append(WsdlParser.IsValidCS(iface));
                        sb.Append(") _tp).");
                        sb.Append(WsdlParser.IsValidCS(methodName));
                    }
                }
            }
 
            // Returns string that is appropriate for the return type
            internal static String ValueString(String paramType)
            {
                String valueString;
                if (paramType == "void")
                    valueString = null;
                else if (paramType == "bool")
                    valueString = "false";
                else if (paramType == "string")
                    valueString = "null";
                else if (paramType == "sbyte" ||
                         paramType == "byte" ||
                         paramType == "short" ||
                         paramType == "ushort" ||
                         paramType == "int" ||
                         paramType == "uint" ||
                         paramType == "long" ||
                         paramType == "ulong")
                    valueString = "1";
                else if (paramType == "float" ||
                         paramType == "exfloat")
                    valueString = "(float)1.0";
                else if (paramType == "double" ||
                         paramType == "exdouble")
                    valueString = "1.0";
                else
                {
                    StringBuilder sb = new StringBuilder(50);
                    sb.Append('(');
                    sb.Append(WsdlParser.IsValidCS(paramType));
                    sb.Append(") (Object) null");
                    valueString = sb.ToString();
                }
                Util.Log("URTMethod.ValueString paramType "+paramType+" valueString "+valueString);                             
                return(valueString);
            }
 
            // This method is called when the parsing is complete
            // and is useful for derived types
            internal abstract void ResolveTypes(WsdlParser parser);
 
 
            // Helper method used by Resolve
            protected void ResolveWsdlParams(WsdlParser parser, String targetNS, String targetName,
                                             bool bRequest, WsdlMethodInfo wsdlMethodInfo)
            {
                Util.Log("URTMethod.ResolveWsdlParams targetName "+targetName+" targetNS "+targetNS+" bRequest "+bRequest+" wsdlMethodInfo "+wsdlMethodInfo);                               
                _wsdlMethodInfo = wsdlMethodInfo;
                _paramNamesOrder = _wsdlMethodInfo.paramNamesOrder;
 
                int length;
                if (_wsdlMethodInfo.bProperty)
                    length = 1;
                else if (bRequest)
                    length = wsdlMethodInfo.inputNames.Length;
                else
                    length = wsdlMethodInfo.outputNames.Length;
 
                for (int i=0; i<length; i++)
                {
                    String element = null;
                    String elementNs = null;
                    String name = null;
                    String nameNs = null;
                    String typeName = null;;
                    String typeNameNs = null;;
                    URTParamType pType;
                    if (_wsdlMethodInfo.bProperty)
                    {
                        typeName = wsdlMethodInfo.propertyType;
                        typeNameNs = wsdlMethodInfo.propertyNs;
                        pType = URTParamType.OUT;
                    }
                    else if (bRequest && !_wsdlMethodInfo.bProperty)
                    {
                        element = wsdlMethodInfo.inputElements[i];
                        elementNs = wsdlMethodInfo.inputElementsNs[i];
                        name = wsdlMethodInfo.inputNames[i];
                        nameNs = wsdlMethodInfo.inputNamesNs[i];
                        typeName = wsdlMethodInfo.inputTypes[i];
                        typeNameNs = wsdlMethodInfo.inputTypesNs[i];
 
                        pType = URTParamType.IN;
                    }
                    else
                    {
                        element = wsdlMethodInfo.outputElements[i];
                        elementNs = wsdlMethodInfo.outputElementsNs[i];
                        name = wsdlMethodInfo.outputNames[i];
                        nameNs = wsdlMethodInfo.outputNamesNs[i];
                        typeName = wsdlMethodInfo.outputTypes[i];
                        typeNameNs = wsdlMethodInfo.outputTypesNs[i];
                        pType = URTParamType.OUT;
                    }
 
                    String actualType;
                    String actualTypeNs;
                    if ((element == null) || element.Length == 0)
                    {
                        actualType = typeName;
                        actualTypeNs = typeNameNs;
                    }
                    else
                    {
                        actualType = element;
                        actualTypeNs = elementNs;
                    }
 
                    Util.Log("URTMethod.ResolveWsdlParams actualType "+actualType+" actualTypeNs "+actualTypeNs);
                    URTNamespace ns = parser.LookupNamespace(actualTypeNs);
                    if (ns == null)
                    {
                        throw new SUDSParserException(
                                                     String.Format(CultureInfo.CurrentCulture, CoreChannel.GetResourceString("Remoting_Suds_CantResolveSchemaNS"),
                                                                   actualTypeNs, actualType));
                    }
 
                    URTComplexType ct = ns.LookupComplexType(actualType);
 
                    if (ct != null && ct.IsArray())
                    {
                        if (ct.GetArray() == null)
                            ct.ResolveArray();
                        String arrayName = ct.GetArray();
                        URTNamespace arrayNS = ct.GetArrayNS();
                        AddParam(new URTParam(name, arrayName, arrayNS.Name, arrayNS.EncodedNS, pType, true, parser, arrayNS));
                    }
                    else
                    {
                        Util.Log("URTMethod.ResolveWsdlParams actualType 2 UrtType "+((Enum)ns.UrtType).ToString());
                        if (ns.UrtType == UrtType.Xsd)
                        {
                            String clrtypeName = parser.MapSchemaTypesToCSharpTypes(actualType);
                            AddParam(new URTParam(name, clrtypeName, ns.Namespace, ns.EncodedNS, pType, true, parser, ns));
                        }
                        else
                        {
                            String foundTypeName = null;
                            if (ct != null)
                            {
                                foundTypeName = ct.Name;
                            }
                            else
                            {
                                URTSimpleType stype = ns.LookupSimpleType(actualType);
                                if (stype != null)
                                {
                                    foundTypeName = stype.Name;
                                }
                                else
                                {
                                    foundTypeName = actualType; 
 
                                    /*
                                    throw new SUDSParserException(
                                        String.Format(CoreChannel.GetResourceString("Remoting_Suds_CantResolveTypeInNS"),
                                                      actualType, ns.Name));
                                                      */
                                }
                            }
                            //typeNS.RemoveComplexType(type);
                            AddParam(new URTParam(name, foundTypeName, ns.Namespace, ns.EncodedNS, pType, true, parser, ns));
                        }
                    }
                }
            }
 
 
            // Fields
            private String _methodName;
            private String _soapAction;
            private URTParam _methodType;
            internal URTComplexType _complexType;
            protected String[] _paramNamesOrder; // parameterOrder names from wsdl 
            protected ArrayList _params = new ArrayList();
            protected ArrayList _paramPosition = new ArrayList();
            private MethodFlags _methodFlags;
            private WsdlMethodInfo _wsdlMethodInfo;
        }
 
        // Repesents a request response method
        internal class RRMethod : URTMethod
        {
            // Constructor
 
            internal RRMethod(WsdlMethodInfo wsdlMethodInfo, URTComplexType complexType) 
            : base (wsdlMethodInfo.methodName, wsdlMethodInfo.soapAction, wsdlMethodInfo.methodAttributes, complexType)
            {
                Util.Log("RRMethod.RRMethod WsdlMethodInfo name "+wsdlMethodInfo.methodName+" soapAction "+wsdlMethodInfo.soapAction);
                _wsdlMethodInfo = wsdlMethodInfo;
                _requestElementName = null;
                _requestElementNS = null;
                _responseElementName = null;
                _responseElementNS = null;
            }
 
            // Adds the request element
            internal void AddRequest(String name, String ns)
            {
                Util.Log("RRMethod.AddRequest name "+name+" ns "+ns);               
                _requestElementName = name;
                _requestElementNS = ns;
            }
 
            // Adds the response element
            internal void AddResponse(String name, String ns)
            {
                Util.Log("RRMethod.AddResponse name "+name+" ns "+ns);                              
                _responseElementName = name;
                _responseElementNS = ns;
            }
 
            // Resolves the method
            internal override void ResolveTypes(WsdlParser parser)
            {
                Util.Log("RRMethod.ResolveTypes "+_requestElementName+" "+_responseElementName);
                ResolveWsdlParams(parser, _requestElementNS, _requestElementName, true, _wsdlMethodInfo);
                ResolveWsdlParams(parser, _responseElementNS, _responseElementName, false, _wsdlMethodInfo);
 
                if (_paramNamesOrder != null)
                {
                    // reorder parameters if there is a parameter order
                    Object[] paramsInOrder = new Object[_params.Count];
                    for (int i=0; i<_params.Count; i++)
                    {
                        paramsInOrder[(int)_paramPosition[i]] = _params[i];
                    }
                    _params =  new ArrayList(paramsInOrder);
                }
 
                ResolveMethodAttributes(); //Needs to be after param order
 
                return;
            }
 
            internal override void PrintCSC(TextWriter textWriter, String indentation,
                                            String namePrefix, String curNS, MethodPrintEnum methodPrintEnum,
                                            bool bURTType, String bodyPrefix, StringBuilder sb)
            {
                Util.Log("RRMethod.PrintCSC name "+_requestElementName+" namePrefix "+namePrefix+" curNS "+curNS+" methodPrintEnum "+((Enum)methodPrintEnum).ToString());
                //if(bURTType == false)
 
                // Don't want to generate a Finalize or destructor method
                if (Name == "Finalize")
                    return;
 
                bool bSoapAction = false;
                if (SoapAction != null)
                    bSoapAction = true;
 
                if ((bSoapAction || !bURTType) && !_wsdlMethodInfo.bProperty)
                {
                    sb.Length = 0;
                    sb.Append(indentation);
                    sb.Append("[SoapMethod(");
 
                    if (bSoapAction)
                    {
                        sb.Append("SoapAction=");
                        sb.Append(WsdlParser.IsValidUrl(SoapAction));
                    }
                    if (!bURTType)
                    {
                        if (bSoapAction)
                            sb.Append(",");
 
                        sb.Append("ResponseXmlElementName=");
                        sb.Append(WsdlParser.IsValidUrl(_responseElementName));
                        if (MethodType != null)
                        {
                            sb.Append(", ReturnXmlElementName=");
                            sb.Append(WsdlParser.IsValidUrl(MethodType.Name));
                        }
                        sb.Append(", XmlNamespace=");
                        sb.Append(WsdlParser.IsValidUrl(_wsdlMethodInfo.inputMethodNameNs)); 
                        sb.Append(", ResponseXmlNamespace=");
                        sb.Append(WsdlParser.IsValidUrl(_wsdlMethodInfo.outputMethodNameNs)); 
                    }
                    sb.Append(")]");
                    textWriter.WriteLine(sb);                   
                }
 
                Util.Log("RRMethod.PrintCSC Invoke base PrintCSC");                                     
                base.PrintCSC(textWriter, indentation, namePrefix, curNS, methodPrintEnum, bURTType,
                              bodyPrefix, sb);
                return;
            }
 
            // Fields
            private String _requestElementName;
            private String _requestElementNS;
            //private String _requestTypeName;
            //private String _requestTypeNS;
            private String _responseElementName;
            private String _responseElementNS;
            private WsdlMethodInfo _wsdlMethodInfo;
            //private String _responseTypeName;
            //private String _responseTypeNS;
        }
 
        // Represents a oneway method
        internal class OnewayMethod : URTMethod
        {
            // Constructor
            internal OnewayMethod(String name, String soapAction, URTComplexType complexType)
            : base(name, soapAction, null, complexType)
            {
                Util.Log("OnewayMethod.OnewayMethod name "+name+" soapAction "+soapAction);
                _messageElementName = null;
                _messageElementNS = null;
                //_messageTypeName = null;
                //_messageTypeNS = null;
            }
 
            internal OnewayMethod(WsdlMethodInfo wsdlMethodInfo, URTComplexType complexType) 
            : base (wsdlMethodInfo.methodName, wsdlMethodInfo.soapAction, wsdlMethodInfo.methodAttributes, complexType)
            {
                Util.Log("OnewayMethod.OnewayMethod WsdlMethodInfo name "+wsdlMethodInfo.methodName+" soapAction "+wsdlMethodInfo.soapAction);
                _wsdlMethodInfo = wsdlMethodInfo;
                _messageElementName = null;
                _messageElementNS = null;
            }
 
 
            // Adds the request element
            internal void AddMessage(String name, String ns)
            {
                Util.Log("OnewayMethod.AddMessage name "+name+" ns "+ns);               
                _messageElementName = name;
                _messageElementNS = ns;
            }
 
            // Resolves the method
            internal override void ResolveTypes(WsdlParser parser)
            {
                Util.Log("OnewayMethod.ResolveTypes name "+ _messageElementName);
                ResolveWsdlParams(parser, _messageElementNS, _messageElementName, true, _wsdlMethodInfo);
                if (_paramNamesOrder != null)
                {
                    // reorder parameters if there is a parameter order
                    Object[] paramsInOrder = new Object[_params.Count];
                    for (int i=0; i<_params.Count; i++)
                    {
                        paramsInOrder[(int)_paramPosition[i]] = _params[i];
                    }
                    _params =  new ArrayList(paramsInOrder);
                }
 
                ResolveMethodAttributes(); //Needs to be after param order
 
                return;
            }
 
 
 
            // Writes the oneway attribute and delegates to the base implementation
            internal override void PrintCSC(TextWriter textWriter, String indentation,
                                            String namePrefix, String curNS, MethodPrintEnum methodPrintEnum,
                                            bool bURTType, String bodyPrefix, StringBuilder sb)
            {
                Util.Log("OnewayMethod.PrintCSC name "+_messageElementName+" namePrefix "+namePrefix+" curNS "+curNS+" methodPrintEnum "+((Enum)methodPrintEnum).ToString());
 
                if (Name == "Finalize")
                    return;
 
                bool bSoapAction = false;
                if (SoapAction != null)
                    bSoapAction = true;
 
                if (!(bSoapAction || !bURTType))
                {
                    textWriter.Write(indentation);
                    textWriter.WriteLine("[OneWay]");
                }
                else
                {
                    sb.Length = 0;
                    sb.Append(indentation);
                    sb.Append("[OneWay, SoapMethod(");
 
                    if (bSoapAction)
                    {
                        sb.Append("SoapAction=");
                        sb.Append(WsdlParser.IsValidUrl(SoapAction));
                    }
                    if (!bURTType)
                    {
                        if (bSoapAction)
                            sb.Append(",");
 
                        sb.Append("XmlNamespace=");
                        sb.Append(WsdlParser.IsValidUrl(_wsdlMethodInfo.inputMethodNameNs)); 
                        //sb.Append(_messageElementNS);
                    }
                    sb.Append(")]");
                    textWriter.WriteLine(sb);                   
                }
 
 
                Util.Log("OnewayMethod.PrintCSC Invoke base PrintCSC");                                                     
                base.PrintCSC(textWriter, indentation, namePrefix, curNS, methodPrintEnum, bURTType,
                              bodyPrefix, sb);
 
                return;
            }
 
            // Fields
            private String _messageElementName;
            private String _messageElementNS;
            private WsdlMethodInfo _wsdlMethodInfo;
            //private String _messageTypeName;
            //private String _messageTypeNS;
        }
 
        // Base class for interfaces
        internal abstract class BaseInterface
        {
            internal BaseInterface(String name, String urlNS, String ns, String encodedNS, WsdlParser parser)
            {
                Util.Log("BaseInterface.BaseInterface");
                _name = name;
                _urlNS = urlNS;
                _namespace = ns;
                _encodedNS = encodedNS;
                _parser = parser;
            }
            internal String Name
            {
                get { return(_name);}
            }
            internal String UrlNS
            {
                get { return(_urlNS);}
            }
            internal String Namespace
            {
                get { return(_namespace);}
            }
 
            internal bool IsURTInterface
            {
                get { return((Object) _namespace == (Object) _encodedNS);}
            }
            internal String GetName(String curNS)
            {
                String name;
                if (_parser.Qualify(_namespace, curNS))
                {
                    StringBuilder sb = new StringBuilder(_encodedNS, 50);
                    sb.Append('.');
                    sb.Append(WsdlParser.IsValidCS(_name));
                    name = sb.ToString();
                }
                else
                    name = _name;
 
                Util.Log("BaseInterface.GetName curNS "+curNS);
                return(name);
            }
            internal abstract void PrintClassMethods(TextWriter textWriter,
                                                     String indentation,
                                                     String curNS,
                                                     ArrayList printedIFaces,
                                                     bool bProxy, StringBuilder sb);
            private String _name;
            private String _urlNS;
            private String _namespace;
            private String _encodedNS;
            private WsdlParser _parser;
        }
 
        // Represents a system interface
        internal class SystemInterface : BaseInterface
        {
            internal SystemInterface(String name, String urlNS, String ns, WsdlParser parser, String assemName)
            : base(name, urlNS, ns, ns, parser)
            {
                Util.Log("SystemInterface.SystemInterface");                
                Debug.Assert(ns.StartsWith("System", StringComparison.Ordinal), "Invalid System type");
                String fullName = ns + '.' + name;
 
                Assembly assem = null;
                if (assemName == null)
                    assem = typeof(string).Assembly;
                else
#pragma warning disable 618
                    assem = Assembly.LoadWithPartialName(assemName, null);
#pragma warning restore 618
 
                if (assem == null)
                    throw new SUDSParserException(String.Format(CultureInfo.CurrentCulture, CoreChannel.GetResourceString("Remoting_Suds_AssemblyNotFound"), assemName));
 
                _type = assem.GetType(fullName, true);
            }
            internal override void PrintClassMethods(TextWriter textWriter,
                                                     String indentation,
                                                     String curNS,
                                                     ArrayList printedIFaces,
                                                     bool bProxy,
                                                     StringBuilder sb)
            {
                Util.Log("SystemInterface.PrintClassMethods "+curNS+" bProxy "+bProxy);                             
                // Return if the interfaces have already been printed
                int i;
                for (i=0;i<printedIFaces.Count;i++)
                {
                    if (printedIFaces[i] is SystemInterface)
                    {
                        SystemInterface iface = (SystemInterface) printedIFaces[i];
                        if (iface._type == _type)
                            return;
                    }
                }
                printedIFaces.Add(this);
 
                // Count of implemented methods
                BindingFlags bFlags = BindingFlags.DeclaredOnly | BindingFlags.Instance |
                                      BindingFlags.Public;// | BindingFlags.NonPublic;
                ArrayList types = new ArrayList();
                sb.Length = 0;
                types.Add(_type);
                i=0;
                int j=1;
                while (i<j)
                {
                    Type type = (Type) types[i];
                    MethodInfo[] methods = type.GetMethods(bFlags);
                    Type[] iFaces = type.GetInterfaces();
                    for (int k=0;k<iFaces.Length;k++)
                    {
                        for (int l=0;l<j;l++)
                        {
                            if (type == iFaces[k])
                                goto Loopback;
                        }
                        types.Add(iFaces[k]);
                        j++;
                        Loopback:
                        continue;
                    }
 
                    for (int k=0;k<methods.Length;k++)
                    {
                        MethodInfo method = methods[k];
                        sb.Length = 0;
                        sb.Append(indentation);
                        sb.Append(CSharpTypeString(method.ReturnType.FullName));
                        sb.Append(' ');
                        sb.Append(WsdlParser.IsValidCS(type.FullName));
                        sb.Append('.');
                        sb.Append(WsdlParser.IsValidCS(method.Name));
                        sb.Append('(');
                        ParameterInfo[] parameters = method.GetParameters();
                        for (int l=0;l<parameters.Length;l++)
                        {
                            if (l != 0)
                                sb.Append(", ");
                            ParameterInfo param = parameters[l];
                            Type parameterType = param.ParameterType;
                            if (param.IsIn)
                                sb.Append("in ");
                            else if (param.IsOut)
                                sb.Append("out ");
                            else if (parameterType.IsByRef)
                            {
                                sb.Append("ref ");
                                parameterType = parameterType.GetElementType();
                            }
                            sb.Append(CSharpTypeString(parameterType.FullName));
                            sb.Append(' ');
                            sb.Append(WsdlParser.IsValidCS(param.Name));
                        }
                        sb.Append(')');
                        textWriter.WriteLine(sb);
 
                        textWriter.Write(indentation);
                        textWriter.WriteLine('{');
 
                        String newIndentation = indentation + "    ";
                        if (bProxy == false)
                        {
                            for (int l=0;l<parameters.Length;l++)
                            {
                                ParameterInfo param = parameters[l];
                                Type parameterType = param.ParameterType;
                                if (param.IsOut)
                                {
                                    sb.Length = 0;
                                    sb.Append(newIndentation);
                                    sb.Append(WsdlParser.IsValidCS(param.Name));
                                    sb.Append(URTMethod.ValueString(CSharpTypeString(param.ParameterType.FullName)));
                                    sb.Append(';');
                                    textWriter.WriteLine(sb);
                                }
                            }
 
                            Util.Log("SystemInterface.PrintClassMethods return 1 print");                           
                            sb.Length = 0;
                            sb.Append(newIndentation);
                            sb.Append("return");
                            String valueString = URTMethod.ValueString(CSharpTypeString(method.ReturnType.FullName));
                            if (valueString != null)
                            {
                                sb.Append('(');
                                sb.Append(valueString);
                                sb.Append(')');
                            }
                            sb.Append(';');
                        }
                        else
                        {
                            Util.Log("SystemInterface.PrintClassMethods return 2 print");                                                       
                            sb.Length = 0;
                            sb.Append(newIndentation);
                            sb.Append("return((");
                            sb.Append(WsdlParser.IsValidCS(type.FullName));
                            sb.Append(") _tp).");
                            sb.Append(WsdlParser.IsValidCS(method.Name));
                            sb.Append('(');
                            if (parameters.Length > 0)
                            {
                                int lastParameter = parameters.Length-1;
                                for (int l=0;l<parameters.Length;l++)
                                {
                                    ParameterInfo param = parameters[0];
                                    Type parameterType = param.ParameterType;
                                    if (param.IsIn)
                                        sb.Append("in ");
                                    else if (param.IsOut)
                                        sb.Append("out ");
                                    else if (parameterType.IsByRef)
                                        sb.Append("ref ");
                                    sb.Append(WsdlParser.IsValidCS(param.Name));
                                    if (l < lastParameter)
                                        sb.Append(", ");
                                }
                            }
                            sb.Append(");");
                        }
                        textWriter.WriteLine(sb);
 
                        textWriter.Write(indentation);
                        textWriter.WriteLine('}');
                    }
 
                    ++i;
                }
 
                return;
            }
            private static String CSharpTypeString(String typeName)
            {
                Util.Log("SystemInterface.CSharpTypeString typeName "+typeName);                                                
                String CSCTypeName = typeName;
                if (typeName == "System.SByte")
                    CSCTypeName = "sbyte";
                else if (typeName == "System.byte")
                    CSCTypeName = "byte";
                else if (typeName == "System.Int16")
                    CSCTypeName = "short";
                else if (typeName == "System.UInt16")
                    CSCTypeName = "ushort";
                else if (typeName == "System.Int32")
                    CSCTypeName = "int";
                else if (typeName == "System.UInt32")
                    CSCTypeName = "uint";
                else if (typeName == "System.Int64")
                    CSCTypeName = "long";
                else if (typeName == "System.UInt64")
                    CSCTypeName = "ulong";
                else if (typeName == "System.Char")
                    CSCTypeName = "char";
                else if (typeName == "System.Single")
                    CSCTypeName = "float";
                else if (typeName == "System.Double")
                    CSCTypeName = "double";
                else if (typeName == "System.Boolean")
                    CSCTypeName = "boolean";
                else if (typeName == "System.Void")
                    CSCTypeName = "void";
                else if (typeName == "System.String")
                    CSCTypeName = "String";
 
                return(WsdlParser.IsValidCSAttr(CSCTypeName));
            }
 
            Type _type;
        }
 
        // Represents an interface
 
        internal class URTInterface : BaseInterface
        {
            internal URTInterface(String name, String urlNS, String ns, String encodedNS, WsdlParser parser)
            : base(name, urlNS, ns, encodedNS, parser)
            {
                Util.Log("URTInterface.URTInterface name "+name+" ns "+ns+" encodedNS "+encodedNS);                                             
                _baseIFaces = new ArrayList();
                _baseIFaceNames = new ArrayList();
                _extendsInterface = new ArrayList();
                _methods = new ArrayList();
                _parser = parser;
            }
            internal void Extends(String baseName, String baseNS, WsdlParser parser)
            {
                Util.Log("URTInterface.Extends baseName "+baseName+" baseNSf "+baseNS);
                _baseIFaceNames.Add(baseName);
                _baseIFaceNames.Add(baseNS);
                // Urt namespace will not have schema, they need to be recorded.
                URTNamespace parsingNamespace = parser.AddNewNamespace(baseNS);
                /*
                if (parsingNamespace == null)
                {
                    parsingNamespace = new URTNamespace(baseNS, parser);
                }
                */
 
                URTInterface parsingInterface = parsingNamespace.LookupInterface(baseName);         
                if (parsingInterface == null)
                {
                    parsingInterface = new URTInterface(baseName, parsingNamespace.Name, parsingNamespace.Namespace, parsingNamespace.EncodedNS, parser);                  
                    parsingNamespace.AddInterface(parsingInterface);
                }
                _extendsInterface.Add(parsingInterface);
            }
 
            internal void AddMethod(URTMethod method)
            {
                Util.Log("URTInterface.AddMethod method "+method.Name);
                _methods.Add(method);
                method.MethodFlags = MethodFlags.None; // method names don't have public modifiers
            }
 
            // Check if interface method occurs up the inheritance hierarchy
            internal void NewNeeded(URTMethod method)
            {
                Util.Log("URTInterface.NewNeeded Enter interface "+Name+" method "+method.Name);
                foreach (URTInterface urtInterface in _extendsInterface)
                {
                    urtInterface.CheckIfNewNeeded(method);
                    if (URTMethod.MethodFlagsTest(method.MethodFlags, MethodFlags.New))
                        break;
 
                }
                Util.Log("URTInterface.NewNeeded Exit interface "+Name+" method "+method.Name+" "+((Enum)method.MethodFlags).ToString());
            }
 
            // Check this interface for method
            private void CheckIfNewNeeded(URTMethod method)
            {
                foreach (URTMethod urtMethod in _methods)
                {
                    if (urtMethod.Name == method.Name)
                    {
                        method.MethodFlags |= MethodFlags.New;
                        break;
                    }
                }
 
                if (URTMethod.MethodFlagsTest(method.MethodFlags, MethodFlags.New))
                    NewNeeded(method);
            }
 
            internal void ResolveTypes(WsdlParser parser)
            {
                Util.Log("URTInterface.ResolveTypes "+Name);                
                for (int i=0;i<_baseIFaceNames.Count;i=i+2)
                {
                    String baseIFaceName = (String) _baseIFaceNames[i];
                    String baseIFaceXmlNS = (String) _baseIFaceNames[i+1];
                    String baseIFaceNS, baseIFaceAssemName;
                    BaseInterface iFace;
                    UrtType iType = parser.IsURTExportedType(baseIFaceXmlNS, out baseIFaceNS,
                                                             out baseIFaceAssemName);
 
                    Util.Log("URTInterface.ResolveTypes Is System "+Name+" iType "+((Enum)iType).ToString()+" baseIFaceNS "+baseIFaceNS);                                   
                    if ((iType != UrtType.Interop) && baseIFaceNS.StartsWith("System", StringComparison.Ordinal))
                    {
                        iFace = new SystemInterface(baseIFaceName, baseIFaceXmlNS, baseIFaceNS, _parser, baseIFaceAssemName);
                    }
                    else
                    {
                        URTNamespace ns = parser.LookupNamespace(baseIFaceXmlNS);
                        if (ns == null)
                        {
                            throw new SUDSParserException(
                                                         String.Format(CultureInfo.CurrentCulture, CoreChannel.GetResourceString("Remoting_Suds_CantResolveSchemaNS"),
                                                                       baseIFaceXmlNS, baseIFaceName));
                        }
                        iFace = ns.LookupInterface(baseIFaceName);
                        if (iFace == null)
                        {
                            throw new SUDSParserException(
                                                         String.Format(CultureInfo.CurrentCulture, CoreChannel.GetResourceString("Remoting_Suds_CantResolveTypeInNS"),
                                                                       baseIFaceName, baseIFaceXmlNS));
                        }
                    }
                    _baseIFaces.Add(iFace);
                }
                for (int i=0;i<_methods.Count;i++)
                    ((URTMethod) _methods[i]).ResolveTypes(parser);
            }
            internal void PrintCSC(TextWriter textWriter, String indentation,
                                   String curNS, StringBuilder sb)
            {
                Util.Log("URTInterface.PrintCSC name "+Name+" curNS "+curNS);               
                bool bURTType = IsURTInterface;
 
                sb.Length = 0;
                sb.Append("\n"); 
                sb.Append(indentation);
                sb.Append("[SoapType(");
 
                if (_parser._xsdVersion == XsdVersion.V1999)
                {
                    sb.Append("SoapOptions=SoapOption.Option1|SoapOption.AlwaysIncludeTypes|SoapOption.XsdString|SoapOption.EmbedAll,");
                }
                else if (_parser._xsdVersion == XsdVersion.V2000)
                {
                    sb.Append("SoapOptions=SoapOption.Option2|SoapOption.AlwaysIncludeTypes|SoapOption.XsdString|SoapOption.EmbedAll,");
                }
 
                if (!bURTType)
                {
                    sb.Append("XmlElementName=");
                    sb.Append(WsdlParser.IsValidUrl(Name));
                    sb.Append(", XmlNamespace=");
                    sb.Append(WsdlParser.IsValidUrl(Namespace));
                    sb.Append(", XmlTypeName=");
                    sb.Append(WsdlParser.IsValidUrl(Name));
                    sb.Append(", XmlTypeNamespace=");
                    sb.Append(WsdlParser.IsValidUrl(Namespace));
                }
                else
                {
                    // Need namespace for clr type because proxy dll might have a different name than server dll
                    sb.Append("XmlNamespace=");
                    sb.Append(WsdlParser.IsValidUrl(UrlNS));
                    sb.Append(", XmlTypeNamespace=");
                    sb.Append(WsdlParser.IsValidUrl(UrlNS));
                }
 
                sb.Append(")]");
                sb.Append("[ComVisible(true)]");
                textWriter.WriteLine(sb);
 
                sb.Length = 0;
                sb.Append(indentation);
                sb.Append("public interface ");
                sb.Append(WsdlParser.IsValidCS(Name));
 
                if (_baseIFaces.Count > 0)
                    sb.Append(" : ");
 
                if (_baseIFaces.Count > 0)
                {
                    sb.Append(WsdlParser.IsValidCSAttr(((BaseInterface) _baseIFaces[0]).GetName(curNS)));
                    for (int i=1;i<_baseIFaces.Count;i++)
                    {
                        sb.Append(", ");
                        sb.Append(WsdlParser.IsValidCSAttr(((BaseInterface) _baseIFaces[i]).GetName(curNS)));
                    }
                }
 
                textWriter.WriteLine(sb);
 
                textWriter.Write(indentation);
                textWriter.WriteLine('{');
 
                String newIndentation = indentation + "    ";
                String namePrefix = " ";
                Util.Log("URTInterface.PrintCSC method count "+_methods.Count);
 
                for (int i=0;i<_methods.Count;i++)
                {
                    Util.Log("URTInterface.PrintCSC Invoke methods in Interface PrintCSC "+Name+" methodName "+((URTMethod) _methods[i]).Name);
                    NewNeeded((URTMethod)_methods[i]);
                    ((URTMethod) _methods[i]).PrintCSC(textWriter, newIndentation,
                                                       namePrefix, curNS, MethodPrintEnum.InterfaceMethods, bURTType,
                                                       null, sb);
                }
                textWriter.Write(indentation);
                textWriter.WriteLine('}');
            }
 
            // No longer used
            internal override void PrintClassMethods(TextWriter textWriter,
                                                     String indentation,
                                                     String curNS,
                                                     ArrayList printedIFaces,
                                                     bool bProxy,
                                                     StringBuilder sb)
            {
                Util.Log("URTInterface.PrintClassMethods method "+Name+" curNS "+curNS+" bProxy "+bProxy);              
                // Return if the interface has already been printed
                for (int i=0;i<printedIFaces.Count;i++)
                {
                    if (printedIFaces[i] == this)
                    {
                        Util.Log("URTInterface.PrintClassMethods printedIFaces return "+Name);
                        return;
                    }
                }
                Util.Log("URTInterface.PrintClassMethods method 2 "+Name+" _methods.Count "+_methods.Count);                
                printedIFaces.Add(this);
                sb.Length = 0;
                sb.Append(indentation);
                if (_methods.Count > 0)
                {
                    sb.Append("// ");
                    sb.Append(WsdlParser.IsValidCS(Name));
                    sb.Append(" interface Methods");
                    textWriter.WriteLine(sb);
 
                    sb.Length = 0;
                    sb.Append(' ');
                    String ifaceName = GetName(curNS);
                    sb.Append(WsdlParser.IsValidCS(ifaceName));
                    sb.Append('.');
                    String namePrefix = sb.ToString();
 
                    String bodyPrefix = null;
                    if (bProxy)
                    {
                        sb.Length = 0;
                        sb.Append("((");
                        sb.Append(WsdlParser.IsValidCS(ifaceName));
                        sb.Append(") _tp).");
                        bodyPrefix = sb.ToString();
                    }
 
                    MethodPrintEnum methodPrintEnum = MethodPrintEnum.PrintBody | MethodPrintEnum.InterfaceInClass;
                    for (int i=0;i<_methods.Count;i++)
                    {
                        Util.Log("URTInterface.PrintClassMethods URTMethod invoke interface methods in class PrintCSC "+Name+" methodName "+((URTMethod) _methods[i]));
 
                        ((URTMethod) _methods[i]).PrintCSC(textWriter, indentation,
                                                           namePrefix, curNS, methodPrintEnum,
                                                           true, bodyPrefix, sb); 
                    }
                }
 
                for (int i=0;i<_baseIFaces.Count;i++)
                {
                    Util.Log("URTInterface.PrintClassMethods BaseIFaces "+Name);
                    ((BaseInterface) _baseIFaces[i]).PrintClassMethods(textWriter,
                                                                       indentation,
                                                                       curNS,
                                                                       printedIFaces,
                                                                       bProxy, sb);
                }
            }
 
            private WsdlParser _parser;
            private ArrayList _baseIFaces;
            private ArrayList _baseIFaceNames;
            private ArrayList _methods;
            private ArrayList _extendsInterface;
        }
 
        // Represents a field of a type
        internal class URTField
        {
            internal URTField(String name, String typeName, String xmlNS, WsdlParser parser,
                              bool bPrimitive, bool bEmbedded, bool bAttribute, bool bOptional,
                              bool bArray, String arraySize, URTNamespace urtNamespace)
            {
                Util.Log("URTField.URTField "+name+" typeName "+typeName+" xmlNS "+xmlNS+" bPrimitive "+bPrimitive+" bEmbedded "+bEmbedded+" bAttribute "+bAttribute);
                _name = name;
                _typeName = typeName;
                _parser = parser;
                String typeAssemName;
 
                UrtType urtType = parser.IsURTExportedType(xmlNS, out _typeNS, out typeAssemName);
                if (urtType == UrtType.Interop)
                    _encodedNS = urtNamespace.EncodedNS;
                else
                    _encodedNS = _typeNS;
                _primitiveField = bPrimitive;
                _embeddedField = bEmbedded;
                _attributeField = bAttribute;
                _optionalField = bOptional;
                _arrayField = bArray;
                _arraySize = arraySize;
                _urtNamespace = urtNamespace;
            }
            internal String TypeName
            {
                get
                {
                    if (_arrayField)
                        return(_typeName + "[]");
                    return(_typeName);
                }
            }
            internal String TypeNS
            {
                get { return(_typeNS);}
            }
            internal bool IsPrimitive
            {
                get { return(_primitiveField);}
            }
            internal bool IsArray
            {
                get { return(_arrayField);}
            }
            internal String GetTypeString(String curNS, bool bNS)
            {
                return _parser.GetTypeString (curNS, bNS, _urtNamespace, TypeName, _typeNS);
            }
 
            internal void PrintCSC(TextWriter textWriter, String indentation,
                                   String curNS, StringBuilder sb)
            {
                Util.Log("URTField.PrintCSC name "+_name+" curNS"+curNS);               
                if (_embeddedField)
                {
                    textWriter.Write(indentation);
                    textWriter.WriteLine("[SoapField(Embedded=true)]");
                }
 
                sb.Length = 0;
                sb.Append(indentation);
                sb.Append("public ");
                sb.Append(WsdlParser.IsValidCSAttr(GetTypeString(curNS, true))); 
                sb.Append(' ');
                sb.Append(WsdlParser.IsValidCS(_name));
                sb.Append(';');
                textWriter.WriteLine(sb);
            }
 
            private String _name;
            private String _typeName;
            private String _typeNS;
            private String _encodedNS;
            private bool _primitiveField;
            private bool _embeddedField;
            private bool _attributeField;
            private bool _optionalField;
            private bool _arrayField;
            private String _arraySize;
            private WsdlParser _parser;
            private URTNamespace _urtNamespace;
        }
 
        internal abstract class SchemaFacet
        {
            protected SchemaFacet()
            {
            }
            internal virtual void ResolveTypes(WsdlParser parser)
            {
            }
            internal abstract void PrintCSC(TextWriter textWriter, String newIndentation,
                                            String curNS, StringBuilder sb);
        }
 
        internal class EnumFacet : SchemaFacet
        {
            internal EnumFacet(String valueString, int value)
            : base()
            {
                Util.Log("EnumFacet.EnumFacet valueString "+valueString+" value "+value);               
                _valueString = valueString;
                _value = value;
            }
            internal override void PrintCSC(TextWriter textWriter, String newIndentation,
                                            String curNS, StringBuilder sb)
            {
                Util.Log("EnumFacet.PrintCSC _valueString "+_valueString+" value "+_value+" curNS "+curNS);
                sb.Length = 0;
                sb.Append(newIndentation);
                sb.Append(WsdlParser.IsValidCS(_valueString));
                sb.Append(" = ");
                sb.Append(_value);
                sb.Append(',');
                textWriter.WriteLine(sb);
                return;
            }
 
            private String _valueString;
            private int _value;
        }
 
        // Represents a Base type
        internal abstract class BaseType
        {
            internal BaseType(String name, String urlNS, String ns, String encodedNS)
            {
                _searchName = name;
                _name = name;
                _urlNS = urlNS;
                _namespace = ns;
                _elementName = _name;
                _elementNS = ns;
                _encodedNS = encodedNS;
                Util.Log("BaseType.BaseType in name "+name+" storedname "+_name+" nested "+_bNestedType);
            }
            internal String Name
            {
                get { return(_name);}
                set { _name = value;}
            }
 
            internal String SearchName
            {
                get { return(_searchName);}
                set { _searchName = value;}
            }
 
            internal String OuterTypeName
            {
                set { _outerTypeName = value;}
 
 
            }
 
            internal String NestedTypeName
            {
                get { return(_nestedTypeName);}
                set { _nestedTypeName = value;}
            }
 
            internal String FullNestedTypeName
            {
                set { _fullNestedTypeName = value;}
            }
 
            internal bool bNestedType
            {
                get { return(_bNestedType);}
                set { _bNestedType = value;}
            }
 
            internal bool bNestedTypePrint
            {
                get { return(_bNestedTypePrint);}
                set { _bNestedTypePrint = value;}
            }
 
            internal String UrlNS
            {
                get { return(_urlNS);}
            }
 
            internal String Namespace
            {
                get { return(_namespace);}
            }
 
            internal String ElementName
            {
                set { _elementName = value;}
            }
            internal String ElementNS
            {
                set { _elementNS = value;}
            }
 
            internal bool IsURTType
            {
                get {
                    Util.Log("BaseType.IsURTType _namespace "+_namespace+" _encodedNS "+_encodedNS+" "+((Object) _namespace == (Object) _encodedNS));
                    return((Object) _namespace == (Object) _encodedNS);}
            }
 
            internal virtual String GetName(String curNS)
            {
                String name;
                if (MatchingStrings(_namespace, curNS))
                    name = _name;
                else
                {
                    StringBuilder sb = new StringBuilder(_encodedNS, 50);
                    sb.Append('.');
                    sb.Append(WsdlParser.IsValidCS(_name));
                    name = sb.ToString();
                }
 
                return(name);
            }
            internal abstract MethodFlags GetMethodFlags(URTMethod method);
            internal abstract bool IsEmittableFieldType
            {
                get;
            }
            internal abstract String FieldName
            {
                get;
            }
 
            internal abstract String FieldNamespace
            {
                get;
            }
 
            internal abstract bool PrimitiveField
            {
                get;
            }
 
            private String _name;
            private String _searchName;
            private String _urlNS;
            private String _namespace;
            private String _elementName;
            private String _elementNS;
            private String _encodedNS;
            internal ArrayList _nestedTypes; // nested types within this type
            internal String _nestedTypeName;  //If this type is nested, name of nested type (without + mangle)
            internal String _fullNestedTypeName; //If this type is nested, name of nested type (without + mangle) with outer class qualifier
            internal String _outerTypeName;
            internal bool _bNestedType = false; //Contains nested types
            internal bool _bNestedTypePrint = false;
        }
 
        // Representa a system type
        internal class SystemType : BaseType
        {
            internal SystemType(String name, String urlNS, String ns, String assemName)
            : base(name, urlNS, ns, ns)
            {
                Util.Log("SystemType.SystemType name "+name+" ns "+ns+" assemName "+assemName);             
                Debug.Assert(ns.StartsWith("System", StringComparison.Ordinal), "Invalid System type");
 
                String fullName = ns + '.' + name;
 
                Assembly assem = null;
                if (assemName == null)
                    assem = typeof(string).Assembly;
                else
#pragma warning disable 618
                    assem = Assembly.LoadWithPartialName(assemName, null);
#pragma warning restore 618
 
                if (assem == null)
                    throw new SUDSParserException(String.Format(CultureInfo.CurrentCulture, CoreChannel.GetResourceString("Remoting_Suds_AssemblyNotFound"), assemName));
 
                _type = assem.GetType(fullName, true);
            }
            internal override MethodFlags GetMethodFlags(URTMethod method)
            {
                BindingFlags bFlags = BindingFlags.DeclaredOnly | BindingFlags.Instance |
                                      BindingFlags.Public | BindingFlags.NonPublic;
                Type type = _type;
                while (type != null)
                {
                    MethodInfo[] methods = type.GetMethods(bFlags);
                    for (int i=0;i<methods.Length;i++)
                    {
                        MethodFlags methodFlags = method.GetMethodFlags(methods[i]);
                        if (methodFlags != 0)
                            return(methodFlags);
                    }
                    type = type.BaseType;
                }
 
                return(0);
            }
            internal override bool IsEmittableFieldType
            {
                get { return(true);}
            }
 
            internal override String FieldName
            {
                get { return(null);}
            }
            internal override String FieldNamespace
            {
                get { return(null);}
            }
            internal override bool PrimitiveField
            {
                get { return(false);}
            }
 
            private Type _type;
        }
 
        // Represents a simple type
        internal class URTSimpleType : BaseType
        {
            internal URTSimpleType(String name, String urlNS, String ns, String encodedNS, bool bAnonymous, WsdlParser parser)
            : base(name, urlNS, ns, encodedNS)
            {
                Util.Log("URTSimpleType.URTSimpleType name "+name+" ns "+ns+" encodedNS "+encodedNS+" bAnonymous "+bAnonymous);
                _baseTypeName = null;
                _baseTypeXmlNS = null;
                _baseType = null;
                _fieldString = null;
                _facets = new ArrayList();
                _bEnum = false;
                _bAnonymous = bAnonymous;
                _encoding = null;
                _parser = parser;
            }
 
            internal void Extends(String baseTypeName, String baseTypeNS)
            {
                Util.Log("URTSimpleType.Extends baseTypeName "+baseTypeName+" baseTypeNS "+baseTypeNS);
                _baseTypeName = baseTypeName;
                _baseTypeXmlNS = baseTypeNS;
 
            }
 
            internal bool IsEnum
            {
                get { return(_bEnum);}
                set { _bEnum = value;}
            }
 
            internal String EnumType
            {
                set {
                    String typeName = value;
                    String typeNS = _parser.ParseQName(ref typeName);
                    if (typeName != null && typeName.Length > 0)
                        _enumType = MapToEnumType(_parser.MapSchemaTypesToCSharpTypes(typeName));
 
                }
            }
 
            private String MapToEnumType(String type)
            {
                String etype = null;
                if (type == "Byte")
                    etype = "byte";
                else if (type == "SByte")
                    etype = "sbyte";
                else if (type == "Int16")
                    etype = "short";
                else if (type == "UInt16")
                    etype = "ushort";
                else if (type == "Int32")
                    etype = "int";
                else if (type == "UInt32")
                    etype = "uint";
                else if (type == "Int64")
                    etype = "long";
                else if (type == "UInt64")
                    etype = "ulong";
                else
                    throw new SUDSParserException(
                                                 String.Format(CultureInfo.CurrentCulture, CoreChannel.GetResourceString("Remoting_Suds_InvalidEnumType"), type));
 
                return etype;
            }
 
            internal void AddFacet(SchemaFacet facet)
            {
                Util.Log("URTSimpleType.AddFacet");
                _facets.Add(facet);
            }
 
            internal override bool IsEmittableFieldType
            {
                get
                {
                    if (_fieldString == null)
                    {
                        if ((_bAnonymous == true) &&
                            (_facets.Count == 0) &&
                            (_encoding != null) &&
                            (_baseTypeName == "binary") &&
                            (_parser.MatchingSchemaStrings(_baseTypeXmlNS)))
                            _fieldString = "byte[]";
                        else
                            _fieldString = String.Empty;
                    }
 
                    return(_fieldString != String.Empty);
                }
            }
            internal override String FieldName
            {
                get { return(_fieldString);}
            }
 
            internal override String FieldNamespace
            {
                get { 
                    String schemaStr = null;
                    if (_parser._xsdVersion == XsdVersion.V1999)
                        schemaStr = s_schemaNamespaceString1999;
                    else if (_parser._xsdVersion == XsdVersion.V2000)
                        schemaStr = s_schemaNamespaceString2000;
                    else if (_parser._xsdVersion == XsdVersion.V2001)
                        schemaStr = s_schemaNamespaceString;
                    return schemaStr;
                }
            }
 
            internal override bool PrimitiveField
            {
                get { return(true);}
            }
 
            internal override String GetName(String curNS)
            {
                if ((_fieldString != null) && (_fieldString != String.Empty))
                    return(_fieldString);
 
                Util.Log("URTSimpleType.GetName curNS "+curNS+" return "+base.GetName(curNS));              
                return(base.GetName(curNS));
            }
 
            internal void PrintCSC(TextWriter textWriter, String indentation,
                                   String curNS, StringBuilder sb)
            {
                Util.Log("URTSimpleType.PrintCSC name "+Name+" curNS "+curNS);                              
 
                // Print only if the type is not an emittable field type
                if (IsEmittableFieldType == true)
                    return;
 
                if (bNestedType && !bNestedTypePrint)
                    return;
 
                // Handle encoding
                if (_encoding != null)
                {
                    // sb.Length = 0;
                    // sb.Append(indentation);
                }
 
                sb.Length = 0;
                sb.Append("\n"); 
                sb.Append(indentation);
                sb.Append("[");
                sb.Append("Serializable, ");
                sb.Append("SoapType(");
 
                if (_parser._xsdVersion == XsdVersion.V1999)
                {
                    sb.Append("SoapOptions=SoapOption.Option1|SoapOption.AlwaysIncludeTypes|SoapOption.XsdString|SoapOption.EmbedAll,");
                }
                else if (_parser._xsdVersion == XsdVersion.V2000)
                {
                    sb.Append("SoapOptions=SoapOption.Option2|SoapOption.AlwaysIncludeTypes|SoapOption.XsdString|SoapOption.EmbedAll,");
                }
 
                // Need namespace for clr type because proxy dll might have a different name than server dll
                sb.Append("XmlNamespace=");
                sb.Append(WsdlParser.IsValidUrl(UrlNS));
                sb.Append(", XmlTypeNamespace=");
                sb.Append(WsdlParser.IsValidUrl(UrlNS)); 
 
                sb.Append(")]");
                textWriter.WriteLine(sb);
 
 
                // Print type
                sb.Length = 0;
                sb.Append(indentation);
 
                // Handle Enum case
                if (IsEnum)
                    sb.Append("public enum ");
                else
                    sb.Append("public class ");
 
                if (_bNestedType)
                    sb.Append(WsdlParser.IsValidCS(NestedTypeName));
                else
                    sb.Append(WsdlParser.IsValidCS(Name));
                if (_baseType != null)
                {
                    sb.Append(" : ");
                    sb.Append(WsdlParser.IsValidCSAttr(_baseType.GetName(curNS)));
                }
                else if (IsEnum && _enumType != null && _enumType.Length > 0)
                {
                    sb.Append(" : ");
                    sb.Append(WsdlParser.IsValidCSAttr(_enumType));
                }
 
                textWriter.WriteLine(sb);
 
                textWriter.Write(indentation);
                textWriter.WriteLine('{');
 
                String newIndentation = indentation + "    ";
                for (int i=0;i<_facets.Count;i++)
                {
                    Util.Log("URTSimpleType.PrintCSC Invoke _facets PrintCSC ");                                                                                                        
                    ((SchemaFacet) _facets[i]).PrintCSC(textWriter, newIndentation, curNS, sb);
                }
 
                textWriter.Write(indentation);
                textWriter.WriteLine('}');
                return;
            }
 
            internal override MethodFlags GetMethodFlags(URTMethod method)
            {
                Debug.Assert(false, "GetMethodFlags called on a SimpleSchemaType");
                return(0);
            }
 
            private String _baseTypeName;
            private String _baseTypeXmlNS;
            private BaseType _baseType;
            private String _fieldString;
            private bool  _bEnum;
            private bool _bAnonymous;
            private String _encoding;
            private ArrayList _facets;
            private String _enumType;
            private WsdlParser _parser;
        }
 
        // Represents a complex type
        internal class URTComplexType : BaseType
        {
            internal URTComplexType(String name, String urlNS, String ns, String encodedNS,
                                    SchemaBlockType blockDefault, bool bSUDSType, bool bAnonymous, WsdlParser parser, URTNamespace xns)
            : base(name, urlNS, ns, encodedNS)
            {
                Util.Log("URTComplexType.URTComplexType name "+this.GetHashCode()+" "+name+" urlNS "+urlNS+" ns "+ns+" encodedNS "+encodedNS+" bSUDStype "+bSUDSType+" bAnonymous "+bAnonymous);
                _baseTypeName = null;
                _baseTypeXmlNS = null;
                _baseType = null;
                _connectURLs = null;
                _bStruct = !bSUDSType;
                _blockType = blockDefault;
                _bSUDSType = bSUDSType;
                _bAnonymous = bAnonymous;
                Debug.Assert(bAnonymous == false || _bSUDSType == false);
                _fieldString = null;
                _fields = new ArrayList();
                _methods = new ArrayList();
                _implIFaces = new ArrayList();
                _implIFaceNames = new ArrayList();
                _sudsType = SUDSType.None;              
                _parser = parser;
 
                int index = name.IndexOf('+');
                if (index > 0)
                {
                    // Nested type see if outer type has been added to namespace
                    String outerType = parser.Atomize(name.Substring(0,index));
                    URTComplexType cs = xns.LookupComplexType(outerType);
                    if (cs == null)
                    {
                        URTComplexType newCs = new URTComplexType(outerType, urlNS, ns, encodedNS, blockDefault, bSUDSType, bAnonymous, parser, xns);
                        Util.Log("URTComplexType.URTComplexType add outerType to namespace "+outerType+" nestedname "+name);
                        xns.AddComplexType(newCs);
                    }
                }
 
 
                if (xns.UrtType == UrtType.Interop)
                {
                    // Interop class names can have '.', replace these with '_', and set wire name to original type name.
                    index = name.LastIndexOf('.');
                    if (index > -1)
                    {
                        // class names can't have '.' so replace with '$'. Use xmlType attribute to send original name on wire.
                        _wireType = name;
                        Name = name.Replace(".", "_");
                        SearchName = name;
                    }
                }
 
            }
 
            internal void AddNestedType(BaseType ct)
            {
                if (_nestedTypes == null)
                    _nestedTypes = new ArrayList(10);
 
                _nestedTypes.Add(ct);
            }
 
            internal void Extends(String baseTypeName, String baseTypeNS)
            {
                Util.Log("URTComplexType.Extends baseTypeName "+baseTypeName+" baseTypeNS "+baseTypeNS);
                _baseTypeName = baseTypeName;
                _baseTypeXmlNS = baseTypeNS;
            }
            internal void Implements(String iFaceName, String iFaceNS, WsdlParser parser)
            {
                Util.Log("URTComplexType.Implements IFaceName "+iFaceName+" iFaceNS "+iFaceNS);
                _implIFaceNames.Add(iFaceName);
                _implIFaceNames.Add(iFaceNS);
                // Urt namespace will not have schema, they need to be recorded.
                URTNamespace parsingNamespace = parser.AddNewNamespace(iFaceNS);
                /*
                if (parsingNamespace == null)
                {
                    parsingNamespace = new URTNamespace(iFaceNS, parser);
                }
                */
 
                URTInterface parsingInterface = parsingNamespace.LookupInterface(iFaceName);            
                if (parsingInterface == null)
                {
                    parsingInterface = new URTInterface(iFaceName, parsingNamespace.Name, parsingNamespace.Namespace, parsingNamespace.EncodedNS, _parser);                    
                    parsingNamespace.AddInterface(parsingInterface);
                }
            }
 
            internal ArrayList ConnectURLs
            {
                set {
                    _connectURLs = value;
                }
            }
            internal bool IsStruct
            {
                set { _bStruct = value;}
            }
            internal bool IsSUDSType
            {
                get { return(_bSUDSType);}
                set {_bSUDSType = value; _bStruct = !value;}
            }
            internal SUDSType SUDSType
            {
                get { return(_sudsType);}
                set { _sudsType = value;}
            }
            internal SudsUse SudsUse
            {
                get { return(_sudsUse);}
                set { _sudsUse = value;}
            }
 
            internal bool IsValueType
            {
                set {_bValueType = value;}
            }
 
            internal SchemaBlockType BlockType
            {
                set { _blockType = value;}
            }
 
            internal String WireType
            {
                get { return(_wireType);}
            }
 
            internal ArrayList Inherit
            {
                get { return(_inherit);}
                set { _inherit = value;}
            }
 
            internal bool IsArray()
            {
                Util.Log("URTComplexType.IsArray "+this.GetHashCode()+" "+Name+" IsArray "+_arrayType);            
                if (_arrayType != null)
                    return true;
                else
                    return false;
            }
            internal String GetArray()
            {
                return _clrarray;
            }
            internal URTNamespace GetArrayNS()
            {
                return _arrayNS;
            }
 
            internal String GetClassName()
            {
                String cname = null;
                if (_bNameMethodConflict)
                    cname = "C"+Name; // Class name generated from a non-Suds wsdl and a method name and portType conflicted.
                else
                    cname = Name;
                return cname;
            }
 
            internal bool IsPrint
            {
                get {return _bprint;}
                set {_bprint = value;}
            }
 
            internal override bool IsEmittableFieldType
            {
                get
                {
                    Util.Log("URTComplexType.IsEmittableFieldType _fieldString "+_fieldString+" _bAnonymous "+_bAnonymous+" _fields.Count "+_fields.Count);
                    if (_fieldString == null)
                    {
                        if ((_bAnonymous == true) &&
                            (_fields.Count == 1))
                        {
                            URTField field = (URTField) _fields[0];
                            if (field.IsArray)
                            {
                                _fieldString = field.TypeName;
                                return(true);
                            }
                        }
                        _fieldString = String.Empty;
                    }
 
                    return(_fieldString != String.Empty);
                }
            }
            internal override String FieldName
            {
                get { return(_fieldString);}
            }
            internal override String FieldNamespace
            {
                get { return(((URTField) _fields[0]).TypeNS);}
            }
            internal override bool PrimitiveField
            {
                get { return((((URTField) _fields[0]).IsPrimitive));}
            }
            internal override String GetName(String curNS)
            {
                if ((_fieldString != null) && (_fieldString != String.Empty))
                    return(_fieldString);
 
                return(base.GetName(curNS));
            }
            internal ArrayList Fields
            {
                get { return _fields;}
            }
 
            internal void AddField(URTField field)
            {
                Util.Log("URTComplexType.AddField");
                _fields.Add(field);
            }
            internal void AddMethod(URTMethod method)
            {
                Util.Log("URTComplexType.AddMethod "+method);               
                if (method.Name == Name)
                {
                    // Type generated from an non-suds wsdl. Append the class name with a C when printing.
                    _bNameMethodConflict = true;
                }
                _methods.Add(method);
                int index = method.Name.IndexOf('.');
                if (index > 0)
                    method.MethodFlags = MethodFlags.None; //interface qualfied method names have no method modifier
                else
                    method.MethodFlags = method.MethodFlags |= MethodFlags.Public; // method names are public for this version of wsdl
 
            }
            private URTMethod GetMethod(String name)
            {
                Util.Log("URTComplexType.GetMethod "+name+" count "+_methods.Count+" Name "+Name+" base ns "+_baseTypeXmlNS+" base name "+_baseTypeName);                             
                for (int i=0;i<_methods.Count;i++)
                {
                    URTMethod method = (URTMethod) _methods[i];
                    Util.Log("URTComplexType.GetMethod interate "+method.Name);                             
                    if (method.Name == name)
                        return(method);
                }
 
                return(null);
            }
            internal void ResolveTypes(WsdlParser parser)
            {
                Util.Log("URTComplexType.ResolveTypes "+Name+" _baseTypeName "+_baseTypeName+" IsSUDSType "+IsSUDSType);
                String baseTypeNS = null;
                String baseTypeAssemName = null;
                if (IsArray())
                {
                    ResolveArray();
                    return;
                }
 
                if (IsSUDSType)
                {
                    // BaseType == null;
                    if (_sudsType == SUDSType.None)
                    {
                        if (_parser._bWrappedProxy)
                            _sudsType = SUDSType.ClientProxy;
                        else
                            _sudsType = SUDSType.MarshalByRef;
                    }
                }
 
                if (_baseTypeName != null)
                {
                    Util.Log("URTComplexType.ResolveTypes 1 ");
                    UrtType urtType = parser.IsURTExportedType(_baseTypeXmlNS, out baseTypeNS, out baseTypeAssemName);
                    if (urtType == UrtType.UrtSystem || baseTypeNS.StartsWith("System", StringComparison.Ordinal))
                    {
                        _baseType = new SystemType(_baseTypeName, _baseTypeXmlNS, baseTypeNS, baseTypeAssemName);
                    }
                    else
                    {
                        URTNamespace ns = parser.LookupNamespace(_baseTypeXmlNS);
                        if (ns == null)
                        {
                            throw new SUDSParserException(
                                                         String.Format(CultureInfo.CurrentCulture, CoreChannel.GetResourceString("Remoting_Suds_CantResolveSchemaNS"),
                                                                       _baseTypeXmlNS, _baseTypeName));
                        }
                        _baseType = ns.LookupComplexType(_baseTypeName);
                        if (_baseType == null)
                        {
                            _baseType = new SystemType(_baseTypeName, _baseTypeXmlNS, baseTypeNS, baseTypeAssemName);
 
                            /*
                            throw new SUDSParserException(
                                                         String.Format(CoreChannel.GetResourceString("Remoting_Suds_CantResolveTypeInNS"),
                                                                       _baseTypeName, _baseTypeXmlNS));
                                                                       */
                        }
                    }
                }
                // Top of inheritance hiearchy for a Wrapped proxy is RemotingClientProxy
                if (IsSUDSType)
                {
                    if (_parser._bWrappedProxy)
                    {
 
                        if (_baseTypeName == null || _baseType is SystemType)
                        {
                            _baseTypeName = "RemotingClientProxy";
                            //<
                            _baseTypeXmlNS = SoapServices.CodeXmlNamespaceForClrTypeNamespace("System.Runtime.Remoting","System.Runtime.Remoting");
                            baseTypeNS = "System.Runtime.Remoting.Services";
                            baseTypeAssemName = "System.Runtime.Remoting";
                            _baseType = new SystemType(_baseTypeName, _baseTypeXmlNS, baseTypeNS, baseTypeAssemName);
                        }
                    }
                    else if (_baseTypeName == null)
                    {                       
                        _baseTypeName = "MarshalByRefObject";
                        //<
                        _baseTypeXmlNS = SoapServices.CodeXmlNamespaceForClrTypeNamespace("System", null);
                        baseTypeNS = "System";
                        baseTypeAssemName = null;
                        _baseType = new SystemType(_baseTypeName, _baseTypeXmlNS, baseTypeNS, baseTypeAssemName);                        
                    }                   
                }
                else if (_baseType == null)
                {
                    Util.Log("URTComplexType.ResolveTypes 5 ");                                         
                    _baseType = new SystemType("Object", SoapServices.CodeXmlNamespaceForClrTypeNamespace("System", null), "System", null);
                }
                for (int i=0;i<_implIFaceNames.Count;i=i+2)
                {
                    String implIFaceName = (String) _implIFaceNames[i];
                    String implIFaceXmlNS = (String) _implIFaceNames[i+1];
                    String implIFaceNS, implIFaceAssemName;
                    BaseInterface iFace;
 
 
                    UrtType iType = parser.IsURTExportedType(implIFaceXmlNS, out implIFaceNS,
                                                             out implIFaceAssemName);
 
                    if (iType == UrtType.UrtSystem)// && implIFaceNS.StartsWith("System", StringComparison.Ordinal))
                    {
                        iFace = new SystemInterface(implIFaceName, implIFaceXmlNS, implIFaceNS, parser, implIFaceAssemName);
                    }
                    else
                    {
                        URTNamespace ns = parser.LookupNamespace(implIFaceXmlNS);
                        if (ns == null)
                        {
                            throw new SUDSParserException(
                                                         String.Format(CultureInfo.CurrentCulture, CoreChannel.GetResourceString("Remoting_Suds_CantResolveSchemaNS"),
                                                                       implIFaceXmlNS, implIFaceName));
                        }
                        iFace = ns.LookupInterface(implIFaceName);
                        if (iFace == null)
                        {
                            throw new SUDSParserException(
                                                         String.Format(CultureInfo.CurrentCulture, CoreChannel.GetResourceString("Remoting_Suds_CantResolveTypeInNS"),
                                                                       implIFaceName, implIFaceXmlNS));
                        }
                    }
                    _implIFaces.Add(iFace);
                }
                for (int i=0;i<_methods.Count;i++)
                    ((URTMethod) _methods[i]).ResolveTypes(parser);
            }
            internal void ResolveMethods()
            {
                Util.Log("URTComplexType.ResolveMethods "+Name);                
                for (int i=0;i<_methods.Count;i++)
                {
                    URTMethod method = (URTMethod) _methods[i];
                    /*
                    if (method.MethodFlags == 0)
                        method.MethodFlags = _baseType.GetMethodFlags(method);
                        */
                }
 
                return;
            }
            internal override MethodFlags GetMethodFlags(URTMethod method)
            {
                /*
                Debug.Assert(method.MethodFlags == 0, "Method has already been considered");
 
                MethodFlags methodFlags = _baseType.GetMethodFlags(method);
                for (int i=0;i<_methods.Count;i++)
                {
                    URTMethod thisMethod = (URTMethod) _methods[i];
                    if (thisMethod.Equals(method))
                        thisMethod.MethodFlags = method.MethodFlags;
                }
                */
 
                return(method.MethodFlags);
            }
 
            internal void PrintCSC(TextWriter textWriter, String indentation, String curNS, StringBuilder sb)
            {
                Util.Log("URTComplexType.PrintCSC enter name "+Name+" curNS "+curNS+" sudsUse "+((Enum)_sudsUse).ToString()+" bNestedType "+bNestedType+" bNestedTypePrint "+bNestedTypePrint);
                // Print only if the type is not an emittable field type
                if (IsEmittableFieldType == true)
                    return;
 
                if (bNestedType && !bNestedTypePrint)
                    return;             
 
                // Handle delegate case
                sb.Length = 0;
                sb.Append(indentation);
                if (_baseTypeName != null)
                {
                    String baseName = _baseType.GetName(curNS);
                    if ((baseName == "System.Delegate") || (baseName == "System.MulticastDelegate"))
                    {
                        sb.Append("public delegate ");
                        URTMethod invokeMethod = GetMethod("Invoke");
                        if (invokeMethod == null)
                        {
                            throw new SUDSParserException(
                                                         CoreChannel.GetResourceString("Remoting_Suds_DelegateWithoutInvoke"));
                        }
                        String typeString = invokeMethod.GetTypeString(curNS, true);
                        sb.Append(WsdlParser.IsValidCSAttr(typeString));
                        sb.Append(' ');
 
                        String printName = Name;
                        int index = printName.IndexOf('.');
                        if (index > 0)
                        {
                            printName = printName.Substring(index+1);
                        }
                        sb.Append(WsdlParser.IsValidCS(printName));
                        sb.Append('(');
                        invokeMethod.PrintSignature(sb, curNS);
                        sb.Append(");");
                        textWriter.WriteLine(sb);
                        return;
                    }
                }
 
                bool bURTType = IsURTType;
 
 
                sb.Length = 0;
                sb.Append("\n"); 
                sb.Append(indentation);
                sb.Append("[");
                if (_sudsType != SUDSType.ClientProxy)
                    sb.Append("Serializable, ");
                sb.Append("SoapType(");
 
                if (_parser._xsdVersion == XsdVersion.V1999)
                {
                    sb.Append("SoapOptions=SoapOption.Option1|SoapOption.AlwaysIncludeTypes|SoapOption.XsdString|SoapOption.EmbedAll,");
                }
                else if (_parser._xsdVersion == XsdVersion.V2000)
                {
                    sb.Append("SoapOptions=SoapOption.Option2|SoapOption.AlwaysIncludeTypes|SoapOption.XsdString|SoapOption.EmbedAll,");
                }
 
                if (!bURTType)
                {
                    sb.Append("XmlElementName=");
                    sb.Append(WsdlParser.IsValidUrl(GetClassName()));
                    sb.Append(", XmlNamespace=");
                    sb.Append(WsdlParser.IsValidUrl(Namespace));
                    sb.Append(", XmlTypeName=");
                    if (WireType != null)
                        sb.Append(WsdlParser.IsValidUrl(WireType));
                    else
                        sb.Append(WsdlParser.IsValidUrl(GetClassName()));
                    sb.Append(", XmlTypeNamespace=");
                    sb.Append(WsdlParser.IsValidUrl(Namespace));
                }
                else
                {
                    // Need namespace for clr type because proxy dll might have a different name than server dll
                    sb.Append("XmlNamespace=");
                    sb.Append(WsdlParser.IsValidUrl(UrlNS));
                    sb.Append(", XmlTypeNamespace=");
                    sb.Append(WsdlParser.IsValidUrl(UrlNS)); 
                    if (WireType != null)
                    {
                        sb.Append(", XmlTypeName=");
                        sb.Append(WsdlParser.IsValidUrl(WireType));
                    }
                }
 
                sb.Append(")]");
                sb.Append("[ComVisible(true)]");
                textWriter.WriteLine(sb);
 
                sb.Length = 0;
                sb.Append(indentation);
 
                if (_sudsUse == SudsUse.Struct)
                    sb.Append("public struct ");
                else
                    sb.Append("public class ");
                if (_bNestedType)
                    sb.Append(WsdlParser.IsValidCS(NestedTypeName));
                else
                    sb.Append(WsdlParser.IsValidCS(GetClassName()));
 
                if (_baseTypeName != null || _sudsUse == SudsUse.ISerializable || _implIFaces.Count > 0)
                    sb.Append(" : ");
                bool bBaseIsURTType = true;
                String baseString = null;
 
                bool binherit = false;
                bool fClientProxy;
                if (_baseTypeName == "RemotingClientProxy")
                    fClientProxy = true;
                else
                    fClientProxy = false;
 
                if (fClientProxy)
                {
                    sb.Append("System.Runtime.Remoting.Services.RemotingClientProxy");
                    binherit = true;
                }
                else if (_baseTypeName != null)
                {
                    bBaseIsURTType = _baseType.IsURTType;
                    baseString = _baseType.GetName(curNS);
                    if (baseString == "System.__ComObject")
                    {
                        /*textWriter.Write(indentation);
                        textWriter.WriteLine("[guid(\"cc3bf020-1881-4e44-88d8-39b1052b1b11\")]");
                        textWriter.Write(indentation);
                        textWriter.WriteLine("[comimport]"); */
                        sb.Append("System.MarshalByRefObject");
                        binherit = true;
                    }
                    else
                    {
                        sb.Append(WsdlParser.IsValidCSAttr(baseString));
                        binherit = true;
                    }
                }
                else
                {
                    // no base name
                    if (_sudsUse == SudsUse.ISerializable)
                    {
                        sb.Append("System.Runtime.Serialization.ISerializable");
                        binherit = true;
                    }
                }
 
                if (_implIFaces.Count > 0)
                {
                    for (int i=0;i<_implIFaces.Count;i++)
                    {
                        if (binherit)
                            sb.Append(", ");
                        sb.Append(WsdlParser.IsValidCS(((BaseInterface) _implIFaces[i]).GetName(curNS)));
                        binherit = true;
                    }
                }
 
 
                textWriter.WriteLine(sb);
 
                textWriter.Write(indentation);
                textWriter.WriteLine('{');
 
                String newIndentation = indentation + "    ";
                int newIndentationLength = newIndentation.Length;
                //bool fClientProxy = _connectURL != null;
 
                Util.Log("URTComplexType.PrintCSC _sudsType "+((Enum)_sudsType).ToString());
 
                if (fClientProxy)
                {
                    PrintClientProxy(textWriter, indentation, curNS, sb);
                }
 
                if (_methods.Count > 0)
                {
                    //textWriter.Write(newIndentation);
                    //textWriter.WriteLine("// Class Methods");
                    String bodyPrefix = null;
 
                    if (_parser._bWrappedProxy)
                    {
                        sb.Length = 0;
                        sb.Append("((");
                        sb.Append(WsdlParser.IsValidCS(GetClassName()));
                        sb.Append(") _tp).");
                        bodyPrefix = sb.ToString();
                    }
 
                    for (int i=0;i<_methods.Count;i++)
                    {
                        Util.Log("URTComplexType.PrintCSC Invoke methods class methods PrintCSC class "+Name+" methodName "+((URTMethod) _methods[i]).Name);
                        ((URTMethod) _methods[i]).PrintCSC(textWriter, newIndentation,
                                                           " ", curNS, MethodPrintEnum.PrintBody, bURTType,
                                                           bodyPrefix, sb); 
                    }
                    textWriter.WriteLine();
                }
 
 
                /*
                if (_implIFaces.Count > 0)
                {
                    ArrayList printedIFaces = new ArrayList(_implIFaces.Count);
                    for (int i=0;i<_implIFaces.Count;i++)
                        ((BaseInterface) _implIFaces[i]).PrintClassMethods(textWriter, newIndentation, curNS, printedIFaces, fClientProxy, sb);
                    textWriter.WriteLine();
                }
                */
 
                // Standard class
                if (_fields.Count > 0)
                {
                    textWriter.Write(newIndentation);
                    textWriter.WriteLine("// Class Fields");
                    for (int i=0;i<_fields.Count;i++)
                    {
                        Util.Log("URTComplexType.PrintCS Invoke _fields PrintCSC");                                                                                                         
                        ((URTField) _fields[i]).PrintCSC(textWriter, newIndentation, curNS, sb);
                    }
                }
 
                // print nested types
                if (_nestedTypes != null && _nestedTypes.Count > 0)
                {
                    foreach (BaseType ctype in _nestedTypes)
                    {
                        ctype.bNestedTypePrint = true;
                        if (ctype is URTSimpleType)
                            ((URTSimpleType)ctype).PrintCSC(textWriter, newIndentation, curNS, sb);
                        else
                            ((URTComplexType)ctype).PrintCSC(textWriter, newIndentation, curNS, sb);
 
                        ctype.bNestedTypePrint = false;
                    }
                }
 
                if (_sudsUse == SudsUse.ISerializable)
                    PrintISerializable(textWriter, indentation, curNS, sb, baseString);
 
                // Close class
                sb.Length = 0;
                sb.Append(indentation);
                sb.Append("}");
                textWriter.WriteLine(sb);
                Util.Log("URTComplexType.PrintCSC Exit name "+Name+" curNS "+curNS);
                return;
            }
 
            private void PrintClientProxy(TextWriter textWriter, String indentation, String curNS, StringBuilder sb)
            {
                Util.Log("URTComplexType.PrintCSC PrintClientProxy ");
                String indent1 = indentation + "    ";
                String indent2 = indent1 + "    ";
                sb.Length = 0;
                sb.Append(indent1);
                sb.Append("// Constructor");
                textWriter.WriteLine(sb);
 
                sb.Length = 0;
                sb.Append(indent1);
                sb.Append("public ");
                sb.Append(WsdlParser.IsValidCS(GetClassName()));
                sb.Append("()");
                textWriter.WriteLine(sb);
 
                sb.Length = 0;
                sb.Append(indent1);
                sb.Append('{');
                textWriter.WriteLine(sb);
 
                if (_connectURLs != null)
                {
                    for (int i=0; i<_connectURLs.Count; i++)
                    {
                        sb.Length = 0;
                        sb.Append(indent2);
                        if (i == 0)
                        {
                            sb.Append("base.ConfigureProxy(this.GetType(), ");
                            sb.Append(WsdlParser.IsValidUrl((string)_connectURLs[i]));
                            sb.Append(");");
                        }
                        else
                        {
                            // Only the first location is used, the rest are commented out in the proxy
                            sb.Append("//base.ConfigureProxy(this.GetType(), ");
                            sb.Append(WsdlParser.IsValidUrl((string)_connectURLs[i]));
                            sb.Append(");");
                        }
                        textWriter.WriteLine(sb);
                    }
                }
 
 
 
                //Preload classes
                foreach (URTNamespace ns in _parser._URTNamespaces)
                {
                    foreach (URTComplexType cs in ns._URTComplexTypes)
                    {
                        if ((cs._sudsType != SUDSType.ClientProxy) && !cs.IsArray())
                        {
                            sb.Length = 0;
                            sb.Append(indent2);
                            sb.Append("System.Runtime.Remoting.SoapServices.PreLoad(typeof(");
                            sb.Append(WsdlParser.IsValidCS(ns.EncodedNS));
                            if (ns.EncodedNS != null && ns.EncodedNS.Length > 0)
                                sb.Append(".");
                            sb.Append(WsdlParser.IsValidCS(cs.Name));
                            sb.Append("));");
                            textWriter.WriteLine(sb);
                        }
                    }
                }
 
                foreach (URTNamespace ns in _parser._URTNamespaces)
                {
                    foreach (URTSimpleType ss in ns._URTSimpleTypes)
                    {
                        if (ss.IsEnum)
                        {
                            sb.Length = 0;
                            sb.Append(indent2);
                            sb.Append("System.Runtime.Remoting.SoapServices.PreLoad(typeof(");
                            sb.Append(WsdlParser.IsValidCS(ns.EncodedNS));
                            if (ns.EncodedNS != null && ns.EncodedNS.Length > 0)
                                sb.Append(".");
                            sb.Append(WsdlParser.IsValidCS(ss.Name));
                            sb.Append("));");
                            textWriter.WriteLine(sb);
                        }
                    }
                }
 
                sb.Length = 0;
                sb.Append(indent1);
                sb.Append('}');
                textWriter.WriteLine(sb);
                
                // Base class for Client Proxy
                // Write Property to retrieve Transparent Proxy
 
                textWriter.WriteLine();
 
                sb.Length = 0;
                sb.Append(indent1);
                sb.Append("public Object RemotingReference");
                textWriter.WriteLine(sb);
 
                sb.Length = 0;
                sb.Append(indent1);
                sb.Append("{");
                textWriter.WriteLine(sb);
 
                sb.Length = 0;
                sb.Append(indent2);
                sb.Append("get{return(_tp);}");
                textWriter.WriteLine(sb);
 
                sb.Length = 0;
                sb.Append(indent1);
                sb.Append("}");
                textWriter.WriteLine(sb);               
 
                textWriter.WriteLine();
            }
 
            private void PrintISerializable(TextWriter textWriter, String indentation, String curNS, StringBuilder sb, String baseString)
            {
                Util.Log("URTComplexType.PrintCSC PrintISerializable ");
                String indent1 = indentation + "    ";
                String indent2 = indent1 + "    ";
 
                if (baseString == null || baseString.StartsWith("System.", StringComparison.Ordinal))
                {
                    // Don't generate if base class already contains field
                    sb.Length = 0;
                    sb.Append(indent1);
                    sb.Append("public System.Runtime.Serialization.SerializationInfo info;");
                    textWriter.WriteLine(sb);
 
                    sb.Length = 0;
                    sb.Append(indent1);
                    sb.Append("public System.Runtime.Serialization.StreamingContext context; \n");
                    textWriter.WriteLine(sb);
                }
 
                sb.Length = 0;
                sb.Append(indent1);
 
                if (_baseTypeName == null)
                    sb.Append("public ");
                else
                    sb.Append("protected ");
 
                if (_bNestedType)
                    sb.Append(WsdlParser.IsValidCS(NestedTypeName));
                else
                    sb.Append(WsdlParser.IsValidCS(GetClassName()));
 
                sb.Append("(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context)");
 
                if (_baseTypeName != null)
                    sb.Append(" : base(info, context)");
                textWriter.WriteLine(sb);
 
                sb.Length = 0;
                sb.Append(indent1);
                sb.Append("{");
                textWriter.WriteLine(sb);
 
                if (baseString == null || baseString.StartsWith("System.", StringComparison.Ordinal))
                {
                    // Don't generate if base class already contains field
                    sb.Length = 0;
                    sb.Append(indent2);
                    sb.Append("this.info = info;");
                    textWriter.WriteLine(sb);
 
                    sb.Length = 0;
                    sb.Append(indent2);
                    sb.Append("this.context = context;");
                    textWriter.WriteLine(sb);
                }
 
 
                sb.Length = 0;
                sb.Append(indent1);
                sb.Append("}");
                textWriter.WriteLine(sb);
 
                if (_baseTypeName == null)
                {
                    sb.Length = 0;
                    sb.Append(indent1);
                    sb.Append("public void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context)");
                    textWriter.WriteLine(sb);
 
                    sb.Length = 0;
                    sb.Append(indent1);
                    sb.Append("{");
                    textWriter.WriteLine(sb);
 
                    sb.Length = 0;
                    sb.Append(indent1);
                    sb.Append("}");
                    textWriter.WriteLine(sb);
                }
 
 
            }
 
            internal void AddArray(String arrayType, URTNamespace arrayNS)
            {
                Util.Log("URTComplexType.ResolveArray Entry "+this.GetHashCode()+" "+_arrayType+" ns "+_arrayNS);
                _arrayType = arrayType;
 
                /*
                int index = arrayType.IndexOf('+');
                if (index > 0)
                {
                    // Nested Type
                    String outerTypeName = arrayType.Substring(0, index);
                    String nestedTypeName = arrayType.Substring(index+1);
                    _arrayType = outerTypeName+"."+nestedTypeName;
                }
                */
                _arrayNS = arrayNS;
                Util.Log("URTComplexType.AddArray "+arrayType+" ns "+(arrayNS == null?"null":arrayNS.Namespace)+" finalName "+_arrayType);
            }
 
            internal void ResolveArray()
            {
                Util.Log("URTComplexType.ResolveArray Entry "+this.GetHashCode()+" "+_arrayType+" ns "+_arrayNS);
 
                if (_clrarray != null)
                    return;
 
                String actualElementType = null;
                String wireElementType = _arrayType;
                int index = _arrayType.IndexOf("[");
                if (index < 0)
                {
                    throw new SUDSParserException(
                                                 String.Format(CultureInfo.CurrentCulture, CoreChannel.GetResourceString("Remoting_Suds_WsdlInvalidArraySyntax"),
                                                               _arrayType));
                }
 
                wireElementType = _arrayType.Substring(0, index);
 
                switch (_arrayNS.UrtType)
                {
                case UrtType.Xsd:
                    actualElementType = _parser.MapSchemaTypesToCSharpTypes(wireElementType);
                    break;
                case UrtType.UrtSystem:
                case UrtType.UrtUser:
                    actualElementType = wireElementType;
                    break;
                case UrtType.Interop:
                    actualElementType = wireElementType;
                    break;
                default:
                    Debug.Assert(false, "!UrtType.None");
                    break;
                }
 
                _clrarray = actualElementType+FilterDimensions(_arrayType.Substring(index));
                Util.Log("URTComplexType.ResolveArray Exit "+_clrarray+" "+_arrayNS+" elementname "+actualElementType);
            }
 
            // Need to remove dimensions in an array (some wsdl's generate fixed arrays with dimensions)
            private String FilterDimensions(String value)
            {
                Char[] outChar = new Char[value.Length];
                for (int i=0; i<value.Length; i++)
                {
                    if (Char.IsDigit(value[i]))
                        outChar[i] = ' ';
                    else
                        outChar[i] = value[i];
                }
                return new String(outChar);
            }
 
 
            private String _baseTypeName;
            private String _baseTypeXmlNS;
            private BaseType _baseType;
            private ArrayList _connectURLs;
            private bool _bStruct;
            private SchemaBlockType _blockType;
            private bool _bSUDSType;
            private bool _bAnonymous;
            private String _wireType;
            private ArrayList _inherit; // proxy hierarchy 
            private String _fieldString;
            private ArrayList _implIFaceNames;
            private ArrayList _implIFaces;
            private ArrayList _fields;
            private ArrayList _methods;
            private SUDSType _sudsType;
            private SudsUse _sudsUse;
            private bool _bValueType;
            private WsdlParser _parser;
            private String _arrayType;
            private URTNamespace _arrayNS;
            private String _clrarray;
            private bool _bprint = true;
            private bool _bNameMethodConflict = false;
 
        }
 
        // Represents an XML element declaration
        internal class ElementDecl
        {
            // Constructor
            internal ElementDecl(String elmName, String elmNS, String typeName, String typeNS,
                                 bool bPrimitive){
                Util.Log("ElementDecl.ElementDecl elmName "+elmName+" elmNS "+elmNS+" typeName "+typeName+" typeNS "+typeNS+" bPrimitive "+bPrimitive);
                _elmName = elmName;
                _elmNS = elmNS;
                _typeName = typeName;
                _typeNS = typeNS;
                _bPrimitive = bPrimitive;
            }
 
            // Field accessors
            internal String Name{
                get{ return(_elmName);}
            }
            internal String Namespace{
                get{ return(_elmNS);}
            }
            internal String TypeName{
                get{ return(_typeName);}
            }
            internal String TypeNS{
                get{ return(_typeNS);}
            }
 
            internal bool Resolve(WsdlParser parser){
                Util.Log("ElementDecl.Resolve "+TypeName+" "+TypeNS);
                // Return immediately for element declaration of primitive types
                if (_bPrimitive)
                    return true;
 
                // Lookup the type from the element declaration
                URTNamespace typeNS = parser.LookupNamespace(TypeNS);
                if (typeNS == null)
                {
                    throw new SUDSParserException(
                                                 String.Format(CultureInfo.CurrentCulture, CoreChannel.GetResourceString("Remoting_Suds_CantResolveSchemaNS"),
                                                               TypeNS, TypeName));
                }
                BaseType type = typeNS.LookupType(TypeName);
                if (type == null)
                {
                    // Because there might be multiple bindings and some not soap, there can be failures in the non soap bindings.
                    return false; 
                    /*
                    throw new SUDSParserException(
                                                 String.Format(CoreChannel.GetResourceString("Remoting_Suds_CantResolveTypeInNS"),
                                                               TypeName, TypeNS));
                                                               */
                }
 
                type.ElementName = Name;
                type.ElementNS = Namespace;
 
                return true;
            }
 
            // Fields
            private String _elmName;
            private String _elmNS;
            private String _typeName;
            private String _typeNS;
            private bool _bPrimitive;
        }
 
        // Represents a namespace
        internal class URTNamespace
        {
            // Constructor
            internal URTNamespace(String name, WsdlParser parser)
            {
                Util.Log("URTNamespace.URTNamespace Enter name "+name);
                _name = name;
                _parser = parser;
                _nsType = parser.IsURTExportedType(name, out _namespace, out _assemName);
                if (_nsType == UrtType.Interop)
                {
                    _encodedNS = EncodeInterop(_namespace, parser);
                }
                else
                    _encodedNS = _namespace;
                _elmDecls = new ArrayList();
                _URTComplexTypes = new ArrayList();
                _numURTComplexTypes = 0;
                _URTSimpleTypes = new ArrayList();
                _numURTSimpleTypes = 0;
                _URTInterfaces = new ArrayList();
                _anonymousSeqNum = 0;
                parser.AddNamespace(this);
                Util.Log("URTNamespace.URTNamespace Exit name "+this.GetHashCode()+" "+name+" _namespace "+_namespace+" _assemName "+_assemName+" _encodedNS "+_encodedNS);
            }
 
            internal static String EncodeInterop(String name, WsdlParser parser)
            {
                String _encodedNS = name;
                if ((parser.ProxyNamespace != null) && parser.ProxyNamespace.Length > 0)
                {
                    String countStr = "";
                    if (parser.ProxyNamespaceCount > 0)
                        countStr = (parser.ProxyNamespaceCount).ToString(CultureInfo.InvariantCulture);
                    parser.ProxyNamespaceCount++;
                    _encodedNS = parser.ProxyNamespace+countStr;
                }
                else
                {
                    int index = name.IndexOf(":");
                    if (index > 0)
                        _encodedNS = _encodedNS.Substring(index+1);
                    if (_encodedNS.StartsWith("//", StringComparison.Ordinal))
                        _encodedNS = _encodedNS.Substring(2);
                    _encodedNS = _encodedNS.Replace('/', '_');
                }
                Util.Log("URTNamespace.EncodeInterop  encoded "+_encodedNS);
                return _encodedNS;
            }
 
 
            // Get the next anonymous type name
            internal String GetNextAnonymousName(){
                ++_anonymousSeqNum;
                Util.Log("URTNamespace.GetNextAnonymousName AnonymousType"+_anonymousSeqNum+" ComplexType "+_name);
                return("AnonymousType" + _anonymousSeqNum);
            }
 
            // Add a new element declaration to the namespace
            internal void AddElementDecl(ElementDecl elmDecl){
                Util.Log("URTNamespace.AddElementDecl ");
                _elmDecls.Add(elmDecl);
            }
 
            // Add a new type into the namespace
            internal void AddComplexType(URTComplexType type){
                Util.Log("URTNamespace.AddComplexType "+this.GetHashCode()+" "+type.Name+" "+type.GetHashCode()+" ns "+_name);
                // Assert that simple and complex types share the same namespace
                Debug.Assert(LookupSimpleType(type.Name) == null,
                             "Complex type has the same name as a simple type");
                _URTComplexTypes.Add(type);
                ++_numURTComplexTypes;
            }
 
            // Add a new type into the namespace
            internal void AddSimpleType(URTSimpleType type){
                Util.Log("URTNamespace.AddSimpleType "+type.Name);              
                // Assert that simple and complex types share the same namespace
                Debug.Assert(LookupComplexType(type.Name) == null,
                             "Simple type has the same name as a complex type");
                _URTSimpleTypes.Add(type);
                ++_numURTSimpleTypes;
            }
 
            // Adds a new interface into the namespace
            internal void AddInterface(URTInterface iface){
                Util.Log("URTNamespace.AddInterface "+iface.Name);              
                _URTInterfaces.Add(iface);
            }
 
            // Returns the namespace
            internal String Namespace{
                get{ return(_namespace);}
            }
            
            internal bool IsSystem
            {
                get
                { 
                    if (_namespace != null && _namespace.StartsWith("System", StringComparison.Ordinal))
                        return true;
                    else
                        return false;
                }
            }
            
            // Returns Encoded namespace
            internal String EncodedNS{
                get{ return(_encodedNS);}
                set{ _encodedNS = value;}
            }
 
            internal bool bReferenced{
                get{ return(_bReferenced);}
                set{ _bReferenced = value;}
            }
            
            // Returns the full name
            internal String Name{
                get{ return(_name);}
            }
 
            // Returns Assembly name
            internal String AssemName{
                get{ return(_assemName);}
            }
 
            internal UrtType UrtType{
                get{ return _nsType;}
            }
 
            // Returns true if this represents a URTNamespace
            internal bool IsURTNamespace{
                get{ return((Object) _namespace == (Object) _encodedNS);}
            }
 
            // Returns true if the namespace has no types defined
            internal bool IsEmpty{
                get{
                    bool isEmpty = true;
                    if (ComplexTypeOnlyArrayorEmpty() &&
                        (_URTInterfaces.Count == 0) &&
                        (_numURTSimpleTypes == 0))
                        isEmpty = true;
                    else
                        isEmpty = false;
                    return isEmpty;
                }
            }
 
            internal bool ComplexTypeOnlyArrayorEmpty()
            {
                bool bempty = true;
                for (int i=0;i<_URTComplexTypes.Count;i++)
                {
                    URTComplexType type = (URTComplexType) _URTComplexTypes[i];
                    if (type != null && !type.IsArray())
                    {
                        bempty = false;
                        break;
                    }
                }
                return bempty;
            }
 
            // Looks up a complex type
            internal URTComplexType LookupComplexType(String typeName){
                URTComplexType ctype = null;
                for (int i=0;i<_URTComplexTypes.Count;i++)
                {
                    URTComplexType type = (URTComplexType) _URTComplexTypes[i];
                    //if (type != null && type.SearchName == typeName)
                    //Util.Log("URTNamespace.LookupComplexType "+this.GetHashCode()+" "+typeName+" "+type.SearchName);
                    if ((type != null) && WsdlParser.MatchingStrings(type.SearchName, typeName))
                    {
                        //Util.Log("URTNamespace.LookupComplexType found");                    
                        ctype = type;
                        break;
                    }
                }
 
                Util.Log("URTNamespace.LookupComplexType "+typeName+" ns "+this.GetHashCode()+" "+_name+" return "+((ctype != null) ? ctype.Name:"null"));               
                return(ctype);
            }
 
            // Looks up a complex type
            internal URTComplexType LookupComplexTypeEqual(String typeName){
                URTComplexType ctype = null;
                for (int i=0;i<_URTComplexTypes.Count;i++)
                {
                    URTComplexType type = (URTComplexType) _URTComplexTypes[i];
                    if (type != null && type.SearchName == typeName)
                    {
                        ctype = type;
                        break;
                    }
                }
 
                Util.Log("URTNamespace.LookupComplexTypeEqual "+typeName+" ns "+this.GetHashCode()+" "+_name+" return "+((ctype != null) ? ctype.Name:"null"));               
                return(ctype);
            }
 
 
            // Looks up a simple type
            internal URTSimpleType LookupSimpleType(String typeName){
                Util.Log("URTNamespace.LookupSimpleType "+typeName+" ns "+_name);                                
                for (int i=0;i<_URTSimpleTypes.Count;i++)
                {
                    URTSimpleType type = (URTSimpleType) _URTSimpleTypes[i];
                    if ((type != null) && WsdlParser.MatchingStrings(type.Name, typeName))
                        return(type);
                }
 
                return(null);
            }
 
            // Looks up a complex or simple type
            internal BaseType LookupType(String typeName){
                BaseType type = LookupComplexType(typeName);
                if (type == null)
                    type = LookupSimpleType(typeName);
 
                return(type);
            }
 
            // Removes the given type from the namespace
            internal void RemoveComplexType(URTComplexType type){
                Util.Log("URTNamespace.RemoveComplexType "+type.Name+" complex Type "+_name);
                for (int i=0;i<_URTComplexTypes.Count;i++)
                {
                    Util.Log("URTNamespace.RemoveComplexType 1 "+type.Name+" complexTypes "+((_URTComplexTypes[i] != null) ? ((URTComplexType)_URTComplexTypes[i]).Name : "Null"));                 
                    if (_URTComplexTypes[i] == type)
                    {
                        Util.Log("URTNamespace.RemoveComplexType 2 match "+type.Name+" complexTypes "+((_URTComplexTypes[i] != null) ? ((URTComplexType)_URTComplexTypes[i]).Name : "Null"));                                       
                        _URTComplexTypes[i] = null;
                        --_numURTComplexTypes;
                        return;
                    }
                }
 
                throw new SUDSParserException(
                                             CoreChannel.GetResourceString("Remoting_Suds_TriedToRemoveNonexistentType"));
            }
 
            // Removes the given type from the namespace
            internal void RemoveSimpleType(URTSimpleType type){
                Util.Log("URTNamespace.RemoveSimpleType "+type.Name+" SimpleType "+_name);              
                for (int i=0;i<_URTSimpleTypes.Count;i++)
                {
                    if (_URTSimpleTypes[i] == type)
                    {
                        _URTSimpleTypes[i] = null;
                        --_numURTSimpleTypes;
                        return;
                    }
                }
 
                throw new SUDSParserException(
                                             CoreChannel.GetResourceString("Remoting_Suds_TriedToRemoveNonexistentType"));
            }
 
            // Looks up an interface
            internal URTInterface LookupInterface(String iFaceName){
                Util.Log("URTNamespace.LookupInterface "+iFaceName);
                for (int i=0;i<_URTInterfaces.Count;i++)
                {
                    URTInterface iFace = (URTInterface) _URTInterfaces[i];
                    if (WsdlParser.MatchingStrings(iFace.Name, iFaceName))
                        return(iFace);
                }
 
                return(null);
            }
 
            // Resolve element references
            internal void ResolveElements(WsdlParser parser){
                Util.Log("URTNamespace.ResolveElements "+Name);
 
                for (int i=0;i<_elmDecls.Count;i++)
                {
                    ((ElementDecl) _elmDecls[i]).Resolve(parser);
                }
            }
 
            // Resolves internal references
            internal void ResolveTypes(WsdlParser parser){
                Util.Log("URTNamespace.ResolveTypes "+Name); 
 
                /*
                // Process nested types 
                Hashtable typeTable = new Hashtable(10);
                for (int i=0;i<_URTComplexTypes.Count;i++)
                {
                    // fill up hashtable with types
                    URTComplexType ctype = (URTComplexType)_URTComplexTypes[i];
 
                    if (ctype.bNestedType)
                    {
                        Util.Log("URTNamespace.ResolveTypes nested type outer type "+ctype.OuterTypeName+" nested type "+ctype.NestedTypeName+" fullNestedTypeName "+ctype.Name);
                        // type is a nested class 
                        URTComplexType outerType = (URTComplexType)typeTable[ctype.OuterTypeName];
                        if (outerType == null)
                        {
                            // place all the URTComplex types in the table, the nested type appears before the outer type in Wsdl
                            for (int j=0;j<_URTComplexTypes.Count;j++)
                            {
                                URTComplexType ctype2 = (URTComplexType)_URTComplexTypes[j];
                                Util.Log("URTNamespace.ResolveTypes miss find all types "+ctype2.Name);
                                typeTable[ctype2.Name] = ctype2;
                            }
                        }
                        outerType = (URTComplexType)typeTable[ctype.OuterTypeName];
                        if (outerType == null)
                        {
                            throw new SUDSParserException(
                                                 String.Format(CoreChannel.GetResourceString("Remoting_Suds_CantResolveNestedType"),
                                                               ctype.Name, ctype.UrlNS));
                        }
                        outerType._nestedTypes.Add(ctype);
 
                    }
                    else
                    {
 
                        Util.Log("URTNamespace.ResolveTypes nested place in table "+ctype.Name);
                        typeTable[ctype.Name] = ctype;
                    }
                }
                */
 
 
                for (int i=0;i<_URTComplexTypes.Count;i++)
                {
                    if (_URTComplexTypes[i] != null)
                        ((URTComplexType)_URTComplexTypes[i]).ResolveTypes(parser);
                }
 
                for (int i=0;i<_URTInterfaces.Count;i++)
                    ((URTInterface)_URTInterfaces[i]).ResolveTypes(parser);
            }
 
            // Resolves method types
            internal void ResolveMethods(){
                Util.Log("URTNamespace.ResolveMethods "+Name);              
                for (int i=0;i<_URTComplexTypes.Count;i++)
                {
                    if (_URTComplexTypes[i] != null)
                        ((URTComplexType)_URTComplexTypes[i]).ResolveMethods();
                }
            }
 
            // Prints all the types in the namespace
            internal void PrintCSC(WriterStream writerStream)
            {
                Util.Log("URTNamespace.PrintCSC Entry "+Name);               
                Debug.Assert(!IsEmpty, "Empty namespace " + Name + " being printed");
                TextWriter textWriter = writerStream.OutputStream;
                // Check to see if there is anything to print for this namespace
                bool bprint = false;
                if (_numURTComplexTypes > 0)
                {
                    for (int i=0;i<_URTComplexTypes.Count;i++)
                    {
                        URTComplexType type = (URTComplexType) _URTComplexTypes[i];
                        if (type != null && type.IsPrint)
                            bprint = true;
                    }
                }
 
                if (_numURTSimpleTypes > 0)
                {
                    for (int i=0;i<_URTSimpleTypes.Count;i++)
                    {
                        URTSimpleType type = (URTSimpleType) _URTSimpleTypes[i];
                        if (type != null)
                            bprint = true;
                    }
                }
 
                if (_URTInterfaces.Count > 0)
                    bprint = true;
 
 
                if (!bprint)
                    return;
                // End of check to see if there is anything to print
 
 
                String indentation = String.Empty;
 
                Stream stream = ((StreamWriter)textWriter).BaseStream;
                if (!writerStream.GetWrittenTo())
                {
                    // Only print when new output file is used
                    textWriter.WriteLine("using System;");
                    textWriter.WriteLine("using System.Runtime.Remoting.Messaging;");
                    textWriter.WriteLine("using System.Runtime.Remoting.Metadata;");
                    textWriter.WriteLine("using System.Runtime.Remoting.Metadata.W3cXsd2001;");
                    textWriter.WriteLine("using System.Runtime.InteropServices;");
                    writerStream.SetWrittenTo();
                }
 
                if ((Namespace != null) &&
                    (Namespace.Length != 0))
                {
                    textWriter.Write("namespace ");
                    textWriter.Write(WsdlParser.IsValidCS(EncodedNS));
                    textWriter.WriteLine(" {");
                    indentation = "    ";
                }
 
 
                StringBuilder sb = new StringBuilder(256);
                if (_numURTComplexTypes > 0)
                {
                    for (int i=0;i<_URTComplexTypes.Count;i++)
                    {
                        URTComplexType type = (URTComplexType) _URTComplexTypes[i];
                        if (type != null && type.IsPrint)
                        {
                            Util.Log("URTNamespace.PrintCSC Invoke Complex type PrintCSC");                                                                                                             
                            type.PrintCSC(textWriter, indentation, _encodedNS, sb);
                        }
                    }
                }
 
                if (_numURTSimpleTypes > 0)
                {
                    for (int i=0;i<_URTSimpleTypes.Count;i++)
                    {
                        URTSimpleType type = (URTSimpleType) _URTSimpleTypes[i];
                        if (type != null)
                        {
                            Util.Log("URTNamespace.PrintCSC Invoke Simple type PrintCSC");                                                                                                                                          
                            type.PrintCSC(textWriter, indentation, _encodedNS, sb);
                        }
                    }
                }
 
                for (int i=0;i<_URTInterfaces.Count;i++)
                {
                    Util.Log("URTNamespace.PrintCSC Invoke Interfaces PrintCSC");                                                                                                                                   
                    ((URTInterface)_URTInterfaces[i]).PrintCSC(textWriter, indentation, _encodedNS, sb);
                }
 
                if ((Namespace != null) &&
                    (Namespace.Length != 0))
                    textWriter.WriteLine('}');
 
                return;
            }
 
            // Fields
            private String _name;
            private UrtType _nsType;
            private WsdlParser _parser;
            private String _namespace;
            private String _encodedNS;
            private String _assemName;
            private int _anonymousSeqNum;
            private ArrayList _elmDecls;
            internal ArrayList _URTComplexTypes;
            private int _numURTComplexTypes;
            internal ArrayList _URTSimpleTypes;
            private int _numURTSimpleTypes;
            private ArrayList _URTInterfaces;
            private bool _bReferenced = false;            
        }
 
        internal interface IDump{
            void Dump();
        }
 
        internal interface INamespaces
        {
            void UsedNamespace(Hashtable namespaces);
        }
 
        internal class WsdlMessage : IDump, INamespaces
        {
            internal String name;
            internal String nameNs;
            internal ArrayList parts = new ArrayList(10);
 
            public void UsedNamespace(Hashtable namespaces)
            {
                Util.Log("WsdlMessage.UsedNamespace "+name+" "+nameNs);
                /*
                if (nameNs != null)
                    namespaces[nameNs] = 1;
                    */
                for (int i=0; i<parts.Count; i++)
                    ((INamespaces)parts[i]).UsedNamespace(namespaces);
            }
 
            public void Dump(){
                Util.Log("WsdlMessage.Dump");
                Util.Log("   name "+name);
                Util.Log("   ns "+nameNs);
                for (int i=0; i<parts.Count; i++)
                    ((IDump)parts[i]).Dump();
            }
 
 
        }
 
        internal class WsdlMessagePart : IDump, INamespaces
        {
            internal String name;
            internal String nameNs;
            internal String element;
            internal String elementNs;
            internal String typeName;
            internal String typeNameNs;
 
 
            public void UsedNamespace(Hashtable namespaces)
            {
                Util.Log("WsdlMessagePart.UsedNamespace "+name+" "+nameNs);
                if (nameNs != null)
                    namespaces[nameNs] = 1;
                if (elementNs != null)
                    namespaces[elementNs] = 1;
 
            }
 
            public void Dump(){
                Util.Log("WsdlMessagePart.Dump");
                Util.Log("   name "+name);
                Util.Log("   element "+element);
                Util.Log("   elementNs "+elementNs);
                Util.Log("   typeName "+typeName);
                Util.Log("   typeNameNs "+typeNameNs);                              
            }
        }
 
        internal class WsdlPortType : IDump, INamespaces
        {
            internal String name;
            //internal String nameNs = null;
            internal ArrayList operations = new ArrayList(10);
            internal Hashtable sections = new Hashtable(10);
 
            public void UsedNamespace(Hashtable namespaces)
            {
                //Util.Log("WsdlPortType.UsedNamespace "+name+" "+nameNs);
                /*
                if (nameNs != null)
                    namespaces[nameNs] = 1;
                    */
                foreach (INamespaces item in operations)
                item.UsedNamespace(namespaces);
 
            }
            public void Dump()          {
                Util.Log("WsdlPortType.Dump");
                Util.Log("   name "+name);
                foreach (DictionaryEntry d in sections)
                Util.Log("   sections key "+d.Key+" value "+((WsdlPortTypeOperation)d.Value).name);
                foreach (IDump item in operations)
                item.Dump();
            }
        }
 
        internal class WsdlPortTypeOperation : IDump, INamespaces
        {
            internal String name;
            internal String nameNs;
            internal String parameterOrder;
            internal ArrayList contents = new ArrayList(3);
 
            public void UsedNamespace(Hashtable namespaces) 
            {
                /*
                if (nameNs != null)
                    namespaces[nameNs] = 1;
                    */
 
                foreach (INamespaces item in contents)
                item.UsedNamespace(namespaces);
            }
 
            public void Dump()          {
                Util.Log("WsdlPortTypeOperation.Dump");
                Util.Log("   name "+name+" parameterOrder "+parameterOrder);
                foreach (IDump item in contents)
                item.Dump();
            }
        }
 
 
        internal class WsdlPortTypeOperationContent : IDump, INamespaces
        {
            internal String element;
            internal String name;
            internal String nameNs;
            internal String message;
            internal String messageNs;
            public void UsedNamespace(Hashtable namespaces)
            {
                Util.Log("WsdlPortTypeOperationContent.UsedNamespace "+name+" "+nameNs);
                /*
                if (nameNs != null)
                    namespaces[nameNs] = 1;
                if (messageNs != null)
                    namespaces[messageNs] = 1;
                    */
            }
 
            public void Dump()          {
                Util.Log("WsdlPortTypeOperationContent.Dump");
                Util.Log("   element "+element);                
                Util.Log("   name "+name);
                Util.Log("   message "+message);                
                Util.Log("   messageNs "+messageNs);                
            }
        }
 
        internal class WsdlBinding : IDump, INamespaces
        {
            internal URTNamespace parsingNamespace;
            internal String name;
            //internal String nameNs = null;
            internal String type;
            internal String typeNs;
            internal ArrayList suds = new ArrayList(10);
            internal WsdlBindingSoapBinding soapBinding;
            internal ArrayList operations = new ArrayList(10);
 
            public void UsedNamespace(Hashtable namespaces)
            {
                //Util.Log("WsdlBinding.UsedNamespace "+name+" "+nameNs);
                /*
                if (nameNs != null)
                    namespaces[nameNs] = 1;
                if (typeNs != null)
                    namespaces[typeNs] = 1;
                    */
 
                if (soapBinding != null)
                    soapBinding.UsedNamespace(namespaces);
 
                foreach (INamespaces item in suds)
                item.UsedNamespace(namespaces);
 
                foreach (INamespaces item in operations)
                item.UsedNamespace(namespaces);
            }
 
            public void Dump(){
                Util.Log("WsdlBinding.Dump");
                Util.Log("   name "+name);
                Util.Log("   type "+type);
                Util.Log("   typeNs "+typeNs);
                Util.Log("   parsingNamespace.ns "+parsingNamespace.Namespace);
                Util.Log("   parsingNamespace.EncodedNS "+parsingNamespace.EncodedNS);              
 
                if (soapBinding != null)
                    soapBinding.Dump();
 
                foreach(IDump item in suds)
                item.Dump();
 
                foreach (IDump item in operations)
                item.Dump();
            }
        }
 
        internal class WsdlBindingOperation : IDump, INamespaces
        {
            internal String name;
            internal String nameNs;
            internal String methodAttributes;
            internal WsdlBindingSoapOperation soapOperation;
            internal ArrayList sections = new ArrayList(10);
 
            public void UsedNamespace(Hashtable namespaces)          
            {
                Util.Log("WsdlBIndingOperation.UsedNamespace "+name+" "+nameNs);
 
                /*
                if (nameNs != null)
                    namespaces[nameNs] = 1;
                    */
 
                soapOperation.UsedNamespace(namespaces);
                foreach (INamespaces item in sections)
                item.UsedNamespace(namespaces);
            }
 
            public void Dump()          {
                Util.Log("WsdlBindingOperation.Dump");
                Util.Log("   name "+name);
                Util.Log("   methodAttributes "+methodAttributes);
                soapOperation.Dump();
                foreach (IDump item in sections)
                item.Dump();
            }
        }
 
        internal class WsdlBindingOperationSection : IDump, INamespaces
        {
            internal String name;
            internal String elementName;
            internal ArrayList extensions = new ArrayList(10);
 
            public void UsedNamespace(Hashtable namespaces)          
            {
                Util.Log("WsdlBIndingOperationSection.UsedNamespace "+name);
                foreach (INamespaces item in extensions)
                item.UsedNamespace(namespaces);
            }
 
            public void Dump()          {
                Util.Log("WsdlBindingOperationSection.Dump");
                Util.Log("   name "+name);
                Util.Log("   elementName "+elementName);                
                foreach (IDump item in extensions)
                item.Dump();
            }
        }
 
 
        internal class WsdlBindingSoapBinding : IDump, INamespaces
        {
            internal String style;
            internal String transport;
 
            public void UsedNamespace(Hashtable namespaces)          
            {
                Util.Log("WsdlBindingSoapBinding.UsedNamespace ");
            }
 
            public void Dump()          {
                Util.Log("WsdlBindingSoapBinding.Dump");
                Util.Log("   style "+style);
                Util.Log("   transport "+transport);
            }
 
 
        }
 
        internal class WsdlBindingSoapBody : IDump, INamespaces
        {
            internal String parts;
            internal String use;
            internal String encodingStyle;
            internal String namespaceUri;
 
            public void UsedNamespace(Hashtable namespaces)          
            {
                Util.Log("WsdlBIndingSoapBody.UsedNamespace "+parts);
            }
 
            public void Dump()          {
                Util.Log("WsdlBindingSoapBody.Dump");
                Util.Log("   parts "+parts);
                Util.Log("   use "+use);
                Util.Log("   encodingStyle "+encodingStyle);
                Util.Log("   namespaceUri "+namespaceUri);              
            }
        }
 
        internal class WsdlBindingSoapHeader : IDump, INamespaces
        {
            internal String message;
            internal String messageNs;
            internal String part;
            internal String use;
            internal String encodingStyle;
            internal String namespaceUri;
 
            public void UsedNamespace(Hashtable namespaces)          
            {
                Util.Log("WsdlBindingSoapHeader.UsedNamespace "+message+" "+messageNs);
                /*
                if (nameNs != null)
                    namespaces[nameNs] = 1; 
                    */
            }
 
            public void Dump()          {
                Util.Log("WsdlBindingSoapHeader.Dump");
                Util.Log("   message "+message);
                Util.Log("   part "+part);
                Util.Log("   use "+use);
                Util.Log("   encodingStyle "+encodingStyle);
                Util.Log("   namespaceUri "+namespaceUri);              
            }
        }
 
        internal class WsdlBindingSoapOperation : IDump, INamespaces
        {
            internal String soapAction;
            internal String style;
 
            public void UsedNamespace(Hashtable namespaces)          
            {
                Util.Log("WsdlBindingSoapOperation.UsedNamespace ");
            }
 
            public void Dump(){
                Util.Log("WsdlBindingSoapOperation.Dump");
                Util.Log("   soapAction "+soapAction);
                Util.Log("   style "+style);
            }
        }
 
        internal class WsdlBindingSoapFault : IDump, INamespaces
        {
            internal String name;
            internal String use;
            internal String encodingStyle;
            internal String namespaceUri;
 
            public void UsedNamespace(Hashtable namespaces)          
            {
                Util.Log("WsdlBindingSoapFault.UsedNamespace "+name+" "+namespaceUri);
                /*
                if (nameNs != null)
                    namespaces[nameNs] = 1; 
                    */
            }
 
            public void Dump()          {
                Util.Log("WsdlBindingSoapFault.Dump");
                Util.Log("   name "+name);
                Util.Log("   use "+use);
                Util.Log("   encodingStyle "+encodingStyle);
                Util.Log("   namespaceUri "+namespaceUri);              
            }
        }
 
        internal enum SudsUse
        {
            Class = 0,
            ISerializable = 1,
            Struct = 2,
            Interface = 3,
            MarshalByRef = 4,
            Delegate = 5,
            ServicedComponent = 6,
        }
 
        internal class WsdlBindingSuds : IDump, INamespaces
        {
            internal String elementName;
            internal String typeName;
            internal String ns;
            internal String extendsTypeName;
            internal String extendsNs;          
            internal SudsUse sudsUse;
            internal ArrayList implements = new ArrayList(10);
            internal ArrayList nestedTypes = new ArrayList(10);
 
            public void UsedNamespace(Hashtable namespaces)          
            {
                Util.Log("WsdlBindingSuds.UsedNamespace elementName "+elementName+" typeName "+typeName+" ns "+ns+" extendsTypeName "+extendsTypeName+" extendsNs "+extendsNs+" sudsUse "+((Enum)sudsUse).ToString());
                if (ns != null)
                    namespaces[ns] = 1;
 
                if (extendsNs != null)
                    namespaces[extendsNs] = 1;
 
                foreach (INamespaces item in implements)
                item.UsedNamespace(namespaces);                    
            }
 
 
            public void Dump()          {
                Util.Log("WsdlBindingSuds.Dump");
                Util.Log("   elementName "+elementName);
                Util.Log("   typeName "+typeName);
                Util.Log("   ns "+ns);
                Util.Log("   extendsTypeName "+extendsTypeName);
                Util.Log("   extendsNs "+extendsNs);                
                Util.Log("   sudsUse "+((Enum)sudsUse).ToString());
                foreach (IDump item in implements)
                item.Dump();                    
                foreach (IDump item in nestedTypes)
                item.Dump();                    
            }
        }
 
        internal class WsdlBindingSudsImplements : IDump, INamespaces
        {
            internal String typeName;
            internal String ns;
 
            public void UsedNamespace(Hashtable namespaces)          
            {
                Util.Log("WsdlBindingSudsImplements.UsedNamespace typeName "+typeName+" ns "+ns);
                if (ns != null)
                    namespaces[ns] = 1;
            }
 
            public void Dump()  
            {
                Util.Log("WsdlBindingSudsImplements.Dump");             
                Util.Log("   typeName "+typeName);
                Util.Log("   ns "+ns);
            }
        }
 
        internal class WsdlBindingSudsNestedType : IDump
        {
            internal String name;
            internal String typeName;
            internal String ns;
 
            public void Dump()   
            {
                Util.Log("WsdlBindingSudsNestedType.Dump");             
                Util.Log("   name "+name);
                Util.Log("   typeName "+typeName);
                Util.Log("   ns "+ns);
            }
        }
 
        internal class WsdlService : IDump, INamespaces
        {
            internal String name;
            //internal String nameNs = null;
            internal Hashtable ports = new Hashtable(10);
 
            public void UsedNamespace(Hashtable namespaces)          
            {
                //Util.Log("WsdlService.UsedNamespace "+name+" "+nameNs);
                /*
                if (nameNs != null)
                    namespaces[nameNs] = 1; 
                    */
                foreach (DictionaryEntry  d in ports)
                ((INamespaces)d.Value).UsedNamespace(namespaces);
            }
 
            public void Dump()          {
                Util.Log("WsdlService.Dump");
                Util.Log("   name "+name);
                foreach (DictionaryEntry  d in ports)
                ((IDump)d.Value).Dump();
            }
        }
 
        internal class WsdlServicePort : IDump, INamespaces
        {
            internal String name;
            internal String nameNs;
            internal String binding;
            internal String bindingNs;
            internal ArrayList locations;
 
            public void UsedNamespace(Hashtable namespaces)          
            {
                /*
                if (nameNs != null)
                    namespaces[nameNs] = 1; 
 
                if (bindingNs != null)
                    namespaces[bindingNs] = 1; 
                    */
            }
 
            public void Dump()          {
                Util.Log("WsdlServicePort.Dump");
                Util.Log("   name "+name);
                Util.Log("   nameNs "+nameNs);
                Util.Log("   binding "+binding);
                Util.Log("   bindingNs"+bindingNs);
                if (locations != null)
                {
                    foreach (String item in locations)
                    Util.Log("   location "+item);
                }
            }
        }
 
 
 
        internal class WsdlMethodInfo : IDump
        {
            internal String soapAction;
            internal String methodName;
            internal String methodNameNs;
            internal String methodAttributes;
            internal String[] paramNamesOrder;
            internal String inputMethodName;
            internal String inputMethodNameNs;
            internal String outputMethodName;
            internal String outputMethodNameNs;
            internal String[] inputNames;
            internal String[] inputNamesNs;
            internal String[] inputElements;
            internal String[] inputElementsNs;
            internal String[] inputTypes;
            internal String[] inputTypesNs;
            internal String[] outputNames;
            internal String[] outputNamesNs;
            internal String[] outputElements;
            internal String[] outputElementsNs;
            internal String[] outputTypes;
            internal String[] outputTypesNs;
            internal String propertyName;
            internal bool bProperty = false;
            internal bool bGet = false;
            internal bool bSet = false;
            internal String propertyType;
            internal String propertyNs;
            internal String soapActionGet;
            internal String soapActionSet;
 
            public void Dump(){
                Util.Log("WsdlMethodInfo.Dump");
                Util.Log("   soapAction "+soapAction);
                Util.Log("   methodName "+methodName);
                Util.Log("   ns "+methodNameNs);
 
                if (paramNamesOrder != null)
                {
                    foreach(String pname in paramNamesOrder)
                    Util.Log("   paramNamesOrder   name "+pname);
 
                }
                if (inputNames != null)
                {
                    for (int i=0; i<inputNames.Length; i++)
                        Util.Log("   inputparams   name "+inputNames[i]+" element "+inputElements[i]+" elementNs "+inputElementsNs[i]+" type "+inputTypes[i]+" typeNs "+inputTypesNs[i]);
                }
 
                if (outputNames != null)
                {
                    for (int i=0; i<outputNames.Length; i++)
                        Util.Log("   outputparams   name "+outputNames[i]+" element "+outputElements[i]+" elementNs "+outputElementsNs[i]+" type "+outputTypes[i]+" typeNs "+outputTypesNs[i]);
                }
 
                if (bProperty)
                {
                    Util.Log("   Property   name "+propertyName+" bGet "+bGet+" bSet "+bSet+" type "+propertyType+" ns "+propertyNs);
                    Util.Log("   action get "+soapActionGet+" set "+soapActionSet);
 
                }
            }
        }
    }
}