File: metadata\wsdlwriter.cs
Project: ndp\clr\src\managedlibraries\remoting\System.Runtime.Remoting.csproj (System.Runtime.Remoting)
// ==++==
// 
//   Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// ==--==
//============================================================
//
// File:    WsdlWriter.cs
//<EMAIL>
// Author:  Peter de Jong (Microsoft)
//</EMAIL>
// Purpose: Defines WsdlWriter 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.Messaging;
    using System.Runtime.Remoting.Metadata; 
    using System.Runtime.Serialization;
    using System.Runtime.Remoting.Channels; // This is so we can get the resource strings.
    using System.Globalization;
 
    // This class generates SUDS documents
    internal class WsdlGenerator
    {
        // Constructor
        internal WsdlGenerator(Type[] types, TextWriter output)
        {
            Util.Log("WsdlGenerator.WsdlGenerator 1");
            _textWriter = output;
            _queue = new Queue();
            _name = null;
            _namespaces = new ArrayList();
            _dynamicAssembly = null;
            _serviceEndpoint = null;
            for (int i=0;i<types.Length;i++)
            {
                if (types[i] != null)
                {
                    if (types[i].BaseType != null)
                    {
                        Util.Log("WsdlGenerator.WsdlGenerator ProcessTypeAttributes 1 "+types[i]);
                        ProcessTypeAttributes(types[i]);
                        _queue.Enqueue(types[i]);
                    }
                }
            }
        }
 
        // Constructor
        internal WsdlGenerator(Type[] types, SdlType sdlType, TextWriter output)
        {
            Util.Log("WsdlGenerator.WsdlGenerator 2");
            _textWriter = output;
            _queue = new Queue();
            _name = null;
            _namespaces = new ArrayList();
            _dynamicAssembly = null;
            _serviceEndpoint = null;
            for (int i=0;i<types.Length;i++)
            {
                if (types[i] != null)
                {
                    if (types[i].BaseType != null)
                    {
                        Util.Log("WsdlGenerator.WsdlGenerator ProcessTypeAttributes 2 "+types[i].BaseType);
                        ProcessTypeAttributes(types[i]);
                        _queue.Enqueue(types[i]);
                    }
                }
            }
        }
 
        // Constructor
        internal WsdlGenerator(Type[] types, TextWriter output, Assembly assembly, String url)
        : this(types, output)
        {
            Util.Log("WsdlGenerator.WsdlGenerator 3 "+url);         
            _dynamicAssembly = assembly;
            _serviceEndpoint = url;
        }
 
        // Constructor
        internal WsdlGenerator(Type[] types, SdlType sdlType, TextWriter output, Assembly assembly, String url)
        : this(types, output)
        {
            Util.Log("WsdlGenerator.WsdlGenerator 4 "+url);         
            _dynamicAssembly = assembly;
            _serviceEndpoint = url;
        }
 
        internal WsdlGenerator(ServiceType[] serviceTypes, SdlType sdlType, TextWriter output)
        {
            Util.Log("WsdlGenerator.WsdlGenerator 5 ");
            _textWriter = output;
            _queue = new Queue();
            _name = null;
            _namespaces = new ArrayList();
            _dynamicAssembly = null;
            _serviceEndpoint = null;
 
            for (int i=0; i<serviceTypes.Length; i++)
            {
                if (serviceTypes[i] != null)
                {
                    if (serviceTypes[i].ObjectType.BaseType != null)
                    {
                        Util.Log("WsdlGenerator.WsdlGenerator ProcessTypeAttributes 3 objectType "+serviceTypes[i].ObjectType+" basetype "+serviceTypes[i].ObjectType.BaseType);
                        ProcessTypeAttributes(serviceTypes[i].ObjectType);
                        _queue.Enqueue(serviceTypes[i].ObjectType);
                    }
                }
 
                // Associate serviceEndpoint with type. A type can have multiple serviceEndpoints
                if (serviceTypes[i].Url != null)
                {
                    if (_typeToServiceEndpoint == null)
                        _typeToServiceEndpoint = new Hashtable(10);
                    if (_typeToServiceEndpoint.ContainsKey(serviceTypes[i].ObjectType.Name))
                    {
                        ArrayList serviceEndpoints = (ArrayList)_typeToServiceEndpoint[serviceTypes[i].ObjectType.Name];
                        serviceEndpoints.Add(serviceTypes[i].Url);
                    }
                    else
                    {
                        ArrayList serviceEndpoints = new ArrayList(10);
                        serviceEndpoints.Add(serviceTypes[i].Url);
                        _typeToServiceEndpoint[serviceTypes[i].ObjectType.Name] = serviceEndpoints;
                    }
 
                }
            }
        }
 
        internal static void QualifyName(StringBuilder sb, String ns, String name)
        {
            if (!(ns == null || ns.Length == 0))
            {
                sb.Append(ns);
                sb.Append('.');
            }
            sb.Append(name);
        }
 
 
        internal static String RefName(Type type)
        {
            String refName = type.Name;
 
            if (!(type.IsPublic || type.IsNotPublic))
            {
                Util.Log("WsdlGenerator.WsdlGenerator RefName nested "+type);
                // nested name
                refName = type.FullName;
                int index = refName.LastIndexOf('.');
                if (index > 0)
                {
                    // nested type, type.Name returns full type rather then simple type
                    refName = refName.Substring(index+1);
                }
                refName = refName.Replace('+', '.');
            }
 
            return refName;
        }
 
        internal void ProcessTypeAttributes(Type type)
        {
            // Check to see if the xsd and xsi schema types should be 1999 instead of 2000. This is a temporary fix for an interop problem
            SoapTypeAttribute att = InternalRemotingServices.GetCachedSoapAttribute(type) as SoapTypeAttribute;
            if (att != null)
            {
                SoapOption soapOption = att.SoapOptions;
                if ((soapOption &= SoapOption.Option1) == SoapOption.Option1)
                    _xsdVersion = XsdVersion.V1999;
                else if ((soapOption &= SoapOption.Option2) == SoapOption.Option2)
                    _xsdVersion = XsdVersion.V2000;
                else
                    _xsdVersion = XsdVersion.V2001;
            }
            Util.Log("WsdlGenerator.ProcessTypeAttributes "+type+" SoapOptions "+((Enum)att.SoapOptions).ToString()+" _xsdVersion "+((Enum)_xsdVersion).ToString());         
 
        }
 
 
        // Generates SUDS
        internal void Generate()
        {
            Util.Log("WsdlGenerator.Generate");         
            // Generate the trasitive closure of the types reachable from
            // the supplied types
            while (_queue.Count > 0)
            {
                // Dequeue from not yet seen queue
                Type type = (Type) _queue.Dequeue();
                ProcessType(type);
            }
 
            // At this point we have the complete list of types
            // to be processed. Resolve cross references between
            // them
            Resolve();
 
            // At this stage, we are ready to print the schemas
            PrintWsdl();
 
            // Flush cached buffers
            _textWriter.Flush();
 
            return;
        }
 
        internal void ProcessType(Type type)
        {
            // Check if the type was encountered earlier
            String ns;
            Assembly assem;
            bool bInteropType = GetNSAndAssembly(type, out ns, out assem);
            Util.Log("WsdlGenerator.ProcessType Dequeue "+type+" ns "+ns+" assem "+assem);                         
            XMLNamespace xns = LookupNamespace(ns, assem);
            if (xns != null)
            {
                String searchName = WsdlGenerator.RefName(type);
 
                if (xns.LookupSchemaType(searchName) != null)
                {
                    return;
                }
            }
            else
            {
                xns = AddNamespace(ns, assem, bInteropType);
            }
            _typeToInteropNS[type] = xns;
            
            if (!type.IsArray)
            {
                // Check if type needs to be represented as a SimpleSchemaType
                SimpleSchemaType ssType = SimpleSchemaType.GetSimpleSchemaType(type, xns, false);
                Util.Log("WsdlGenerator.ProcessType simpleType "+ssType);
 
                if (ssType != null)
                {
                    // Add to namespace as a SimpleSchemaType
                    xns.AddSimpleSchemaType(ssType);
                }
                else
                {
                    // Check for the first MarshalByRef type
                    bool bUnique = false;
                    String connectURL = null;
                    Hashtable connectTypeToServiceEndpoint = null;
                    if (_name == null && s_marshalByRefType.IsAssignableFrom(type))
                    {
                        Util.Log("WsdlGenerator.ProcessType need new type "+type+" typename "+type.Name);          
                        _name = type.Name;
                        _targetNS = xns.Namespace;
                        _targetNSPrefix = xns.Prefix;
                        connectURL = _serviceEndpoint;
                        connectTypeToServiceEndpoint = _typeToServiceEndpoint;
                        bUnique = true;
                    }
 
                    RealSchemaType rsType = new RealSchemaType(type, xns, connectURL, connectTypeToServiceEndpoint, bUnique, this);
                    // Add to namespace as a RealSchemaType
                    xns.AddRealSchemaType(rsType);
                    // Enqueue types reachable from this type
                    EnqueueReachableTypes(rsType);
                }
            }
        }
 
        // Adds types reachable from the given type
        private void EnqueueReachableTypes(RealSchemaType rsType)
        {
            Util.Log("WsdlGenerator.EnqueueReachableTypes "+rsType.Name+" "+rsType.XNS.Name);           
            // Get the XML namespace object
            XMLNamespace xns = rsType.XNS;
 
            // Process base type
            if (rsType.Type.BaseType != null)
            {
                if (rsType.Type.BaseType != s_valueType || rsType.Type.BaseType != s_objectType)
                    AddType(rsType.Type.BaseType, GetNamespace(rsType.Type.BaseType));
            }
 
            // Check if this is a suds type
            bool bSUDSType = rsType.Type.IsInterface ||
                             s_marshalByRefType.IsAssignableFrom(rsType.Type) ||
                             s_delegateType.IsAssignableFrom(rsType.Type);
            if (bSUDSType)
            {
                Util.Log("WsdlGenerator.EnqueueReachableTypes suds type "+rsType.Name+" "+rsType.XNS.Name);           
                // Process fields
                FieldInfo[] fields = rsType.GetInstanceFields();
                for (int i=0;i<fields.Length;i++)
                {
                    if (fields[i].FieldType == null)
                        continue;
                    AddType(fields[i].FieldType, xns);
                }
 
                // Process implemented interfaces
                Type[] interfaces = rsType.GetIntroducedInterfaces();
                if (interfaces.Length > 0)
                {
                    for (int i=0;i<interfaces.Length;i++)
                    {
                        Util.Log("WsdlGenerator.EnqueueReachableTypes Interfaces "+interfaces[i].Name+" "+xns.Name);                        
                        AddType(interfaces[i], xns);
                    }
                }
 
                ProcessMethods(rsType);
 
            }
            else
            {
                // Process fields
                FieldInfo[] fields = rsType.GetInstanceFields();
                for (int i=0;i<fields.Length;i++)
                {
                    if (fields[i].FieldType == null)
                        continue;
                    AddType(fields[i].FieldType, xns);
                }
            }
 
            return;
        }
 
        private void ProcessMethods(RealSchemaType rsType)
        {
            Util.Log("WsdlGenerator.ProcessMethods "+rsType);                       
            XMLNamespace xns = rsType.XNS;
            MethodInfo[] methods = rsType.GetIntroducedMethods();
            if (methods.Length > 0)
            {
                String methodNSString = null;
                XMLNamespace methodXNS = null;  
 
                if (xns.IsInteropType)
                {
                    methodNSString = xns.Name;
                    methodXNS = xns;
                }
                else
                {
                    StringBuilder sb = new StringBuilder();
                    WsdlGenerator.QualifyName(sb, xns.Name, rsType.Name);
                    methodNSString = sb.ToString();
                    methodXNS = AddNamespace(methodNSString, xns.Assem);
                    xns.DependsOnSchemaNS(methodXNS, false);
                }
 
                for (int i=0;i<methods.Length;i++)
                {
                    MethodInfo method = methods[i];
                    Util.Log("WsdlGenerator.ProcessMethods methods "+method.Name+" "+methodXNS.Name);
                    AddType(method.ReturnType, methodXNS);
                    ParameterInfo[] parameters = method.GetParameters();
                    for (int j=0;j<parameters.Length;j++)
                        AddType(parameters[j].ParameterType, methodXNS); 
                }
            }
        }
 
 
        // Adds the given type if it has not been encountered before
        private void AddType(Type type, XMLNamespace xns)
        {
            Util.Log("WsdlGenerator.AddType "+type+" ns "+xns.Namespace);                      
            //  System.Array says that it has element type, but returns null
            //         when asked for the element type.<
 
 
 
 
            // Need to get underlying element type
            // For arrays of arrays, want element, not embedded array
            Type elementType = type.GetElementType();
            Type nextelementType = elementType;
            while(nextelementType != null)
            {
                nextelementType = elementType.GetElementType();
                if (nextelementType != null)
                    elementType = nextelementType;
                
            }
            Util.Log("WsdlGenerator.AddType elementType "+type+" elementType "+elementType);                      
 
            if (elementType != null)
                EnqueueType(elementType, xns);
 
 
            if (!type.IsArray && !type.IsByRef)
                EnqueueType(type, xns);
 
            if (!(type.IsPublic || type.IsNotPublic))
            {
                // nested type, enqueue parent
                String refTypeName = type.FullName;
                int index = refTypeName.IndexOf("+");
                if (index > 0)
                {
                    String parentName = refTypeName.Substring(0, index);
                    Assembly assembly = type.Module.Assembly;
                    Util.Log("WsdlGenerator.AddType parentName "+parentName+" assembly "+assembly);
                    Type parentType = assembly.GetType(parentName, true);
                    Util.Log("WsdlGenerator.AddType parentType "+parentType);
                    if (parentType == null)
                    {
                        //Error nested type
                    }
                    EnqueueType(parentType, xns);
                }
            }
        }
 
        private void EnqueueType(Type type, XMLNamespace xns)
        {
            Util.Log("WsdlGenerator.EnqueueType "+type+" ns "+xns.Namespace);                      
            if (!type.IsPrimitive || type == s_charType) //char is not a xsd type
            {
                String ns;
                Assembly assem;
                XMLNamespace dependsOnNS = null;
 
                bool bInteropType = GetNSAndAssembly(type, out ns, out assem);
 
                // Lookup the namespace
                dependsOnNS = LookupNamespace(ns, assem);
                // Creat a new namespace if neccessary
                if (dependsOnNS == null)
                    dependsOnNS = AddNamespace(ns, assem, bInteropType);
 
                // The supplied namespace depends directly on the namespace of the type
                String typeString = SudsConverter.MapClrTypeToXsdType(type); //see if this is a xsd type
                if (type.IsInterface || typeString != null || type == s_voidType)
                {
                    // Interfaces aren't in schema section
                    // Any xsd type
                    xns.DependsOnSchemaNS(dependsOnNS, false); 
                }
                else
                    xns.DependsOnSchemaNS(dependsOnNS, true);
 
 
 
                // Enqueue the type if does not belong to system namespace
                if (!type.FullName.StartsWith("System."))
                {
                    Util.Log("WsdlGenerator.EnqueueType place on queue "+type+" ns "+xns.Namespace);                      
                    _queue.Enqueue(type);
                }
            }
        }
 
        private static bool GetNSAndAssembly(Type type, out String ns, out Assembly assem)
        {
            Util.Log("WsdlGenerator.GetNSAndAssembly enter "+type);
 
            String xmlNamespace = null;
            String xmlElement = null;
            bool bInterop = false;
            SoapServices.GetXmlElementForInteropType(type, out xmlElement, out xmlNamespace);
            if (xmlNamespace != null)
            {
                ns = xmlNamespace;
                assem = type.Module.Assembly;
                bInterop = true;
            }
            else
            {
                // Return the namespace and assembly in which the type is defined
                ns = type.Namespace;
                assem = type.Module.Assembly;
                bInterop = false;
            }
 
            Util.Log("WsdlGenerator.GetNSAndAssembly exit ns "+ns+" assem "+assem+" bInterop "+bInterop);
            return bInterop;
        }
 
        private XMLNamespace LookupNamespace(String name, Assembly assem)
        {
            Util.Log("WsdlGenerator.LookupNamespace "+name);                        
            for (int i=0;i<_namespaces.Count;i++)
            {
                XMLNamespace xns = (XMLNamespace) _namespaces[i];
                if (name == xns.Name)
                    return(xns);
            }
 
            return(null);
        }
 
        private XMLNamespace AddNamespace(String name, Assembly assem)
        {
            return AddNamespace(name, assem, false);
        }
 
        private XMLNamespace AddNamespace(String name, Assembly assem, bool bInteropType)
        {
            Util.Log("WsdlGenerator.AddNamespace "+name);                       
            Debug.Assert(LookupNamespace(name, assem) == null, "Duplicate Type found");
 
            XMLNamespace xns = new XMLNamespace(name, assem,
                                                _serviceEndpoint,
                                                _typeToServiceEndpoint,
                                                "ns" + _namespaces.Count,
                                                bInteropType, this);
            _namespaces.Add(xns);
 
            return(xns);
        }
 
        private XMLNamespace GetNamespace(Type type)
        {
            Util.Log("WsdlGenerator.GetNamespace "+type);
            String ns = null;
            Assembly assem = null;
            bool bInteropType = GetNSAndAssembly(type, out ns, out assem);
 
            XMLNamespace xns = LookupNamespace(ns, assem);
            if (xns == null)
            {
                xns = AddNamespace(ns, assem, bInteropType);
            }
            return xns;
        }
 
 
        private void Resolve()
        {
            Util.Log("WsdlGenerator.Resolve ");                     
            for (int i=0;i<_namespaces.Count;i++)
                ((XMLNamespace) _namespaces[i]).Resolve();
 
            return;
        }
 
        private void PrintWsdl()
        {
            if (_targetNS == null || _targetNS.Length == 0)
            {
                // No marshalbyRef object so use another target
                // Find a namespace
                if (_namespaces.Count > 0)
                    _targetNS =  ((XMLNamespace)_namespaces[0]).Namespace;
                else
                    _targetNS = "http://schemas.xmlsoap.org/wsdl/";
            }
 
            String indent = "";
            String indent1 = IndentP(indent);
            String indent2 = IndentP(indent1);
            String indent3 = IndentP(indent2);
            String indent4 = IndentP(indent3);
 
            StringBuilder sb = new StringBuilder(256);          
            Util.Log("WsdlGenerator.PrintWsdl");
            _textWriter.WriteLine("<?xml version='1.0' encoding='UTF-8'?>");
            sb.Length = 0;
            sb.Append("<definitions ");
            if (_name != null)
            {
                sb.Append("name='");
                sb.Append(_name);
                sb.Append("' ");
            }
            sb.Append("targetNamespace='");
            sb.Append(_targetNS);
            sb.Append("'");
            _textWriter.WriteLine(sb);              
 
            PrintWsdlNamespaces(_textWriter, sb, indent3);
    	    // See if there are any schema information to print.
    
    	    bool bPrintTypeSection = false;
                for (int i=0;i<_namespaces.Count;i++)
                {
                   if (((XMLNamespace) _namespaces[i]).CheckForSchemaContent())
    	       {	
    		   bPrintTypeSection = true;
    		   break;
    	       }
                }
    
    
    	    if (bPrintTypeSection)
    	    {
                PrintTypesBeginWsdl(_textWriter, sb, indent1);
    
                for (int i=0;i<_namespaces.Count;i++)
                {
           		    if (((XMLNamespace) _namespaces[i]).CheckForSchemaContent())
        		    {
                        Util.Log("WsdlGenerator.PrintWsdl call PrintWsdlNamespaces "+((XMLNamespace) _namespaces[i]).Namespace);                            
                        ((XMLNamespace) _namespaces[i]).PrintSchemaWsdl(_textWriter, sb, indent2);
                    }
                }
    
                PrintTypesEndWsdl(_textWriter, sb, indent1);
            }
            
            ArrayList refNames = new ArrayList(25);
 
            for (int i=0;i<_namespaces.Count;i++)
                ((XMLNamespace) _namespaces[i]).PrintMessageWsdl(_textWriter, sb, indent1, refNames);
 
            PrintServiceWsdl(_textWriter, sb, indent1, refNames);
 
            _textWriter.WriteLine("</definitions>");
 
            return;
        }
 
 
        private void PrintWsdlNamespaces(TextWriter textWriter, StringBuilder sb, String indent)
        {
            Util.Log("WsdlGenerator.PrintWsdlNamespaces");          
            sb.Length = 0;
            sb.Append(indent);
            sb.Append("xmlns='http://schemas.xmlsoap.org/wsdl/'");
            textWriter.WriteLine(sb);
 
            sb.Length = 0;
            sb.Append(indent);
            sb.Append("xmlns:tns='");
            sb.Append(_targetNS);
            sb.Append("'");
            textWriter.WriteLine(sb);
 
            sb.Length = 0;
            sb.Append(indent);          
            sb.Append("xmlns:xsd='");
            sb.Append(SudsConverter.GetXsdVersion(_xsdVersion));
            sb.Append("'");
            textWriter.WriteLine(sb);
 
            sb.Length = 0;
            sb.Append(indent);          
            sb.Append("xmlns:xsi='");
            sb.Append(SudsConverter.GetXsiVersion(_xsdVersion));
            sb.Append("'");
            textWriter.WriteLine(sb);
 
            sb.Length = 0;
            sb.Append(indent);          
            sb.Append("xmlns:suds='http://www.w3.org/2000/wsdl/suds'");
            textWriter.WriteLine(sb);
 
            sb.Length = 0;
            sb.Append(indent);          
            sb.Append("xmlns:wsdl='http://schemas.xmlsoap.org/wsdl/'");
            textWriter.WriteLine(sb);
 
            sb.Length = 0;
            sb.Append(indent);          
            sb.Append("xmlns:soapenc='http://schemas.xmlsoap.org/soap/encoding/'");
            textWriter.WriteLine(sb);
 
 
            Hashtable usedNames = new Hashtable(10);
            for (int i=0;i<_namespaces.Count;i++)
                ((XMLNamespace) _namespaces[i]).PrintDependsOnWsdl(_textWriter, sb, indent, usedNames);
 
            // This should be last because it closes off the definitions element
            sb.Length = 0;
            sb.Append(indent);                      
            sb.Append("xmlns:soap='http://schemas.xmlsoap.org/wsdl/soap/'>");
            textWriter.WriteLine(sb);
 
 
        }
 
        private void PrintTypesBeginWsdl(TextWriter textWriter, StringBuilder sb, String indent)
        {
            Util.Log("WsdlGenerator.PrintTypesBeginWsdl");          
            sb.Length = 0;
            sb.Append(indent);
            sb.Append("<types>");
            textWriter.WriteLine(sb);
        }
 
        private void PrintTypesEndWsdl(TextWriter textWriter, StringBuilder sb, String indent)
        {
            Util.Log("WsdlGenerator.PrintTypesEndWsdl");            
            sb.Length = 0;
            sb.Append(indent);          
            sb.Append("</types>");
            textWriter.WriteLine(sb);           
        }
 
        internal void PrintServiceWsdl(TextWriter textWriter, StringBuilder sb, String indent, ArrayList refNames)
        {
            Util.Log("WsdlGenerator.PrintServiceWsdl");         
            String indent1 = IndentP(indent);               
            String indent2 = IndentP(indent1);
            String indent3 = IndentP(indent2);                                                      
            sb.Length = 0;
            sb.Append("\n");
            sb.Append(indent);
            sb.Append("<service name='");
            sb.Append(_name);
            sb.Append("Service'");
            sb.Append(">");
            textWriter.WriteLine(sb);
 
            for (int i=0; i<refNames.Count; i++)
            {
                if (((_typeToServiceEndpoint != null) && (_typeToServiceEndpoint.ContainsKey(refNames[i]))) ||
                    (_serviceEndpoint != null))
                {
            
                    sb.Length = 0;
                    sb.Append(indent1);
                    sb.Append("<port name='");
                    sb.Append(refNames[i]);
                    sb.Append("Port'");
                    sb.Append(" ");
                    sb.Append("binding='tns:");
                    sb.Append(refNames[i]);
                    sb.Append("Binding");
                    sb.Append("'>");
                    textWriter.WriteLine(sb);               
    
                    if ((_typeToServiceEndpoint != null) && (_typeToServiceEndpoint.ContainsKey(refNames[i])))
                    {
                        foreach (String url in (ArrayList)_typeToServiceEndpoint[refNames[i]])
                        {
                            sb.Length = 0;
                            sb.Append(indent2);
                            sb.Append("<soap:address location='");
                            sb.Append(UrlEncode(url));
                            sb.Append("'/>");
                            textWriter.WriteLine(sb);
                        }
    
                    }
                    else if (_serviceEndpoint != null)
                    {
                        sb.Length = 0;
                        sb.Append(indent2);
                        sb.Append("<soap:address location='");
                        sb.Append(_serviceEndpoint);
                        sb.Append("'/>");
                        textWriter.WriteLine(sb);
                    }
    
                    sb.Length = 0;
                    sb.Append(indent1);
                    sb.Append("</port>");
                    textWriter.WriteLine(sb);
                }
            }
            sb.Length = 0;
            sb.Append(indent);
            sb.Append("</service>");
            textWriter.WriteLine(sb);               
        }
 
        private String UrlEncode(String url)
        {
            if (url == null || url.Length == 0)
                return url;
 
            int index = url.IndexOf("&amp;");
            if (index > -1)
            {
                // Assume it's encoded
                return url;
            }
 
            index = url.IndexOf('&');
            if (index > -1)
            {
                return url.Replace("&", "&amp;");
            }
 
            return url;
        }
 
 
        // Private fields
        private TextWriter _textWriter;
        internal Queue _queue;
        private String _name;
        private String _targetNS;
        private String _targetNSPrefix;
        private ArrayList _namespaces;
        private Assembly _dynamicAssembly;
        private String _serviceEndpoint; //service endpoint for all types
        private XsdVersion _xsdVersion; // Temporary, specifies what xsd and xsi schema to put out
        internal Hashtable _typeToServiceEndpoint; //service endpoint for each type
        internal Hashtable _typeToInteropNS = new Hashtable(); // If interop type, then XMLNamespace the type is in.
 
        private static Type s_marshalByRefType = typeof(System.MarshalByRefObject);
        private static Type s_contextBoundType = typeof(System.ContextBoundObject);
        private static Type s_delegateType = typeof(System.Delegate);
        private static Type s_valueType = typeof(System.ValueType);
        private static Type s_objectType = typeof(System.Object);
        private static Type s_charType = typeof(System.Char);
        private static Type s_voidType = typeof(void);
 
        private static Type s_remotingClientProxyType = typeof(System.Runtime.Remoting.Services.RemotingClientProxy);
        private static SchemaBlockType blockDefault = SchemaBlockType.SEQUENCE;
 
        /***************************************************************
         **
         ** Private classes used by SUDS generator
         **
         ***************************************************************/
        private interface IAbstractElement
        {
            void Print(TextWriter textWriter, StringBuilder sb, String indent);
        }
 
        private class EnumElement : IAbstractElement
        {
            internal EnumElement(String value)
            {
                Util.Log("EnumElement.EnumElement "+value);
                _value = value;
            }
 
            public void Print(TextWriter textWriter, StringBuilder sb, String indent)
            {
                Util.Log("EnumElement.Print");
                sb.Length = 0;
                sb.Append(indent);
                sb.Append("<enumeration value='");
                sb.Append(_value);
                sb.Append("'/>");
                textWriter.WriteLine(sb);
                return;
            }
 
            // Fields
            private String _value;
        }
 
        /*
        private class ComplexContent : IAbstractElement
        {
            internal ComplexContent()
            {
            }
 
            internal void Add(Restriction restriction)
            {
                _restriction = restriction;
            }
 
            public void Print(TextWriter textWriter, StringBuilder sb, String indent)
            {
                Util.Log("EnumElement.Print");
                sb.Length = 0;
                sb.Append(indent);
                sb.Append("<enumeration value='");
                sb.Append(_value);
                sb.Append("'/>");
                textWriter.WriteLine(sb);
                return;
            }
 
            Restriction _restriction;
        }
        */
 
 
        private class Restriction : Particle
        {
            internal enum RestrictionType 
            {
                None = 0,
                Array = 1,
                Enum = 2
            }
 
            internal Restriction()
            {
                Util.Log("Restriction.Restriction ");
            }
 
            internal Restriction(String baseName, XMLNamespace baseNS)
            {
                Util.Log("Restriction.Restriction "+baseName+" "+baseNS.Namespace);
                _baseName = baseName;
                _baseNS = baseNS;
            }
 
            internal void AddArray(SchemaAttribute attribute)
            {
                Util.Log("Restriction.AddArray ");
                _rtype = RestrictionType.Array;
                _attribute = attribute;
            }
 
            public override String Name()
            {
                return _baseName;
            }
 
            public override void Print(TextWriter textWriter, StringBuilder sb, String indent)
            {
                Util.Log("Restriction.Print "+_baseName);
                String indent1 = IndentP(indent);
                sb.Length = 0;
                sb.Append(indent);
                if (_rtype == RestrictionType.Array)
                    sb.Append("<restriction base='soapenc:Array'>");
                else if (_rtype == RestrictionType.Enum)
                {
                    sb.Append("<restriction base='xsd:string'>");
                }
                else
                {
                    sb.Append("<restriction base='");
                    sb.Append(_baseNS.Prefix);
                    sb.Append(':');
                    sb.Append(_baseName);
                    sb.Append("'>");
                }
                textWriter.WriteLine(sb);
                foreach (IAbstractElement elem in _abstractElms)
                  elem.Print(textWriter, sb, IndentP(indent1));
 
                if (_attribute != null)
                    _attribute.Print(textWriter, sb, IndentP(indent1));
                sb.Length = 0;
                sb.Append(indent);
                sb.Append("</restriction>");
                textWriter.WriteLine(sb);
            }
 
            String _baseName;
            XMLNamespace _baseNS;
            internal RestrictionType _rtype;
            SchemaAttribute _attribute;
            internal ArrayList _abstractElms = new ArrayList();
        }
 
        private class SchemaAttribute : IAbstractElement
        {
            internal SchemaAttribute()
            {
                Util.Log("SchemaAttribute ");
            }
 
            internal void AddArray(String wireQname)
            {
                Util.Log("SchemaAttribute wireQname "+wireQname);
                _wireQname = wireQname;
            }
 
            public void Print(TextWriter textWriter, StringBuilder sb, String indent)
            {
                sb.Length = 0;
                sb.Append(indent);
                sb.Append("<attribute ref='soapenc:arrayType'");
                sb.Append(" wsdl:arrayType ='");
                sb.Append(_wireQname);
                sb.Append("'/>");
                textWriter.WriteLine(sb);
                return;
            }
 
            // Fields
            private String _wireQname;
 
        }
 
        private abstract class Particle : IAbstractElement
        {
            protected Particle(){}
            public abstract String Name();
            public abstract void Print(TextWriter textWriter, StringBuilder sb, String indent);
        }
 
        private class SchemaElement : Particle
        {
            internal SchemaElement(String name, Type type, bool bEmbedded, XMLNamespace xns)
            : base(){
                Util.Log("SchemaElement.SchemaElement Particle "+name+" type "+type+" bEmbedded "+bEmbedded);
                _name = name;
                _typeString = null;
                _schemaType = SimpleSchemaType.GetSimpleSchemaType(type, xns, true);                
                _typeString = RealSchemaType.TypeName(type, bEmbedded, xns);
            }
 
            public override String Name()
            {
                return _name;
            }
 
            public override void Print(TextWriter textWriter, StringBuilder sb, String indent){
                Util.Log("SchemaElement.Print "+_name+" _schemaType "+_schemaType+" _typeString "+_typeString );
                String indent1 = IndentP(indent);
                sb.Length = 0;
                sb.Append(indent);
                sb.Append("<element name='");
                sb.Append(_name);
                if (_schemaType != null && !(_schemaType is SimpleSchemaType && ((SimpleSchemaType)_schemaType).Type.IsEnum))
                {
                    sb.Append("'>");
                    textWriter.WriteLine(sb);
                    _schemaType.PrintSchemaType(textWriter, sb, IndentP(indent1), true);
 
                    sb.Length = 0;
                    sb.Append(indent);
                    sb.Append("</element>");
                }
                else
                {
                    if (_typeString != null)
                    {
                        sb.Append("' type='");
                        sb.Append(_typeString);
                        sb.Append('\'');
                    }
                    sb.Append("/>");
                }
                textWriter.WriteLine(sb);
 
                return;
            }
 
            // Fields
            private String _name;
            private String _typeString;
            private SchemaType _schemaType;
        }
 
        private abstract class SchemaType
        {
            internal abstract void PrintSchemaType(TextWriter textWriter, StringBuilder sb, String indent, bool bAnonymous);
        }
 
        private class SimpleSchemaType : SchemaType
        {
            private SimpleSchemaType(Type type, XMLNamespace xns)
            {
                Util.Log("SimpleSchemaType.SimpleSchemaType "+type+" xns "+((xns != null) ? xns.Name : "Null"));
                _type = type;
                _xns = xns;
                _abstractElms = new ArrayList();
 
                _fullRefName = WsdlGenerator.RefName(type);
            }
 
            internal Type Type
            {
                get{ return(_type);}
            }
 
            internal String FullRefName
            {
                get{ return _fullRefName;}
            }
 
            internal String BaseName{
                get{ return(_baseName);}
            }
 
            internal override void PrintSchemaType(TextWriter textWriter, StringBuilder sb, String indent, bool bAnonymous){
                Util.Log("SimpleSchemaType.PrintSchemaType _type.Name "+_type.Name);
                sb.Length = 0;
                sb.Append(indent);
                if (bAnonymous == false)
                {
                    sb.Append("<simpleType name='");
                    sb.Append(FullRefName);
                    sb.Append("'");
                    if (BaseName != null)
                    {
                        sb.Append(" base='");
                        sb.Append(BaseName);
                        sb.Append("'");
                    }
 
                    if (_restriction._rtype == Restriction.RestrictionType.Enum)
                    {
                        sb.Append(" suds:enumType='");
                        sb.Append(_restriction.Name());
                        sb.Append("'");
                    }
                }
                else
                {
                    if (BaseName != null)
                    {
                        sb.Append("<simpleType base='");
                        sb.Append(BaseName);
                        sb.Append("'");
                    }
                    else
                        sb.Append("<simpleType");
                }
 
                bool bEmpty = (_abstractElms.Count == 0 && _restriction == null);
                if (bEmpty)
                    sb.Append("/>");
                else
                    sb.Append(">");
                textWriter.WriteLine(sb);
                if (bEmpty)
                    return;
 
                if (_abstractElms.Count > 0)
                {
                    for (int i=0;i<_abstractElms.Count; i++)
                        ((IAbstractElement) _abstractElms[i]).Print(textWriter, sb, IndentP(indent));
                }
 
                if (_restriction != null)
                    _restriction.Print(textWriter, sb, IndentP(indent));
 
                textWriter.Write(indent);
                textWriter.WriteLine("</simpleType>");
 
                return;
            }
 
 
            internal static SimpleSchemaType GetSimpleSchemaType(Type type, XMLNamespace xns, bool fInline)
            {
                Util.Log("SimpleSchemaType.GetSimpleSchemaType "+type+" xns "+xns.Name);                
 
                SimpleSchemaType ssType = null;
                if (type.IsEnum)
                {
                    ssType = new SimpleSchemaType(type, xns);
                    String baseName = RealSchemaType.TypeName(Enum.GetUnderlyingType(type), true, xns);
                    ssType._restriction = new Restriction(baseName, xns);
                    String[] values = Enum.GetNames(type);
                    for (int i=0;i<values.Length;i++)
                        ssType._restriction._abstractElms.Add(new EnumElement(values[i]));
                    ssType._restriction._rtype = Restriction.RestrictionType.Enum;
                }
                else
                {
                }
                return(ssType);
            }
 
 
            private Type _type;
            internal String _baseName = null; //get rid of warning, not used for now
            private XMLNamespace _xns;
            internal Restriction _restriction;
            private String _fullRefName;
            private ArrayList _abstractElms = new ArrayList();
        }
 
 
        private abstract class ComplexSchemaType : SchemaType
        {
            internal ComplexSchemaType(String name, bool bSealed)
            {
                _name = name;
                _fullRefName = _name;
                _blockType = SchemaBlockType.ALL;
                _baseName = null;
                _elementName = name;
                _bSealed = bSealed;
                _particles = new ArrayList();
                _abstractElms = new ArrayList();
            }
 
            internal ComplexSchemaType(String name, SchemaBlockType blockType, bool bSealed)
            {
                _name = name;
                _fullRefName = _name;
                _blockType = blockType;
                _baseName = null;
                _elementName = name;
                _bSealed = bSealed;
                _particles = new ArrayList();
                _abstractElms = new ArrayList();
            }
 
            internal ComplexSchemaType(Type type)
            {
                Util.Log("ComplexSchemaType.ComplexSchemaType "+type);              
                _blockType = SchemaBlockType.ALL;
                _type = type;
                Init();
            }
 
            private void Init()
            {
                _name = _type.Name;
                _bSealed = _type.IsSealed;
                _baseName = null;
                _elementName = _name;
                _particles = new ArrayList();
                _abstractElms = new ArrayList();
                _fullRefName = WsdlGenerator.RefName(_type);
            }
 
            internal String Name{
                get{ return(_name);}
            }
 
            internal String FullRefName
            {
                get{ return(_fullRefName);}
            }
 
            protected String BaseName{
                get{ return(_baseName);}
                set{ _baseName = value;}
            }
 
            internal String ElementName{
                get{ return(_elementName);}
                set{ _elementName = value;}
            }
 
 
            protected bool IsSealed{
                get{ return(_bSealed);}
            }
 
            protected bool IsEmpty{
                get{
                    return((_abstractElms.Count == 0) &&
                           (_particles.Count == 0));
                }
            }
 
            internal void AddParticle(Particle particle){
                Util.Log("ComplexSchemaType.AddParticle "+particle.Name());                
                _particles.Add(particle);
            }
 
            protected void PrintBody(TextWriter textWriter, StringBuilder sb, String indent){
                Util.Log("ComplexSchemaType.PrintBody "+_name);             
                int particleCount = _particles.Count;
                String indent1 = IndentP(indent);
                String indent2 = IndentP(indent1);
                if (particleCount > 0)
                {
                    bool bPrintBlockElms = /*(particleCount > 1) && */(WsdlGenerator.blockDefault != _blockType);
                    if (bPrintBlockElms)
                    {
                        sb.Length = 0;
                        sb.Append(indent1);
                        sb.Append(schemaBlockBegin[(int) _blockType]);
                        textWriter.WriteLine(sb);
                    }
 
                    for (int i=0;i<particleCount; i++)
                        ((Particle) _particles[i]).Print(textWriter, sb, IndentP(indent2));
 
                    if (bPrintBlockElms)
                    {
                        sb.Length = 0;
                        sb.Append(indent1);
                        sb.Append(schemaBlockEnd[(int) _blockType]);
                        textWriter.WriteLine(sb);
                    }
                }
 
                int abstractElmCount = _abstractElms.Count;
                for (int i=0;i<abstractElmCount; i++)
                    ((IAbstractElement) _abstractElms[i]).Print(textWriter, sb, IndentP(indent));
 
                return;
            }
 
            private String _name;
            private Type _type;
            private String _fullRefName;
            private String _baseName;
            private String _elementName;
            private bool _bSealed;
            private SchemaBlockType _blockType;
            private ArrayList _particles;
            private ArrayList _abstractElms;
 
            static private String[] schemaBlockBegin = { "<all>", "<sequence>", "<choice>", "<complexContent>"};
            static private String[] schemaBlockEnd = { "</all>", "</sequence>", "</choice>", "</complexContent>"};
        }
 
        private class PhonySchemaType : ComplexSchemaType
        {
            internal PhonySchemaType(String name) : base(name, true)
            {
                Util.Log("PhonySchemaType.PhonySchemaType "+name);              
                _numOverloadedTypes = 0;
            }
 
            internal int OverloadedType(){
                Util.Log("PhonySchemaType.OverLoadedTypeType");             
                return(++_numOverloadedTypes);
            }
 
            internal override void PrintSchemaType(TextWriter textWriter, StringBuilder sb, String indent, bool bAnonymous){
                Util.Log("PhonySchemaType.PrintSchemaType"); 
                Debug.Assert(bAnonymous == true, "PhonySchemaType should always be printed as anonymous types");
 
                // Wsdl Phony is not printed, instead the message section contains the parameters.
                return;
            }
            private int _numOverloadedTypes;
            internal ArrayList _inParamTypes;
            internal ArrayList _inParamNames;
            internal ArrayList _outParamTypes;
            internal ArrayList _outParamNames;
            internal ArrayList _paramNamesOrder;
            internal String _returnType;
            internal String _returnName;
        }
 
        private class ArraySchemaType : ComplexSchemaType
        {
            internal ArraySchemaType(Type type, String name, SchemaBlockType blockType, bool bSealed)
            : base(name, blockType, bSealed)
            {
                Util.Log("ArraySchemaType.ArrayComplexSchemaType");  
                _type = type;
            }
 
            internal Type Type
            {
                get { return _type;}
            }
 
 
            internal override void PrintSchemaType(TextWriter textWriter, StringBuilder sb, String indent, bool bAnonymous)
            {
                Util.Log("ArrayType.PrintSchemaType");   
                String indent1 = IndentP(indent);
                sb.Length = 0;
                sb.Append(indent); 
                sb.Append("<complexType name='");
                sb.Append(FullRefName);
                sb.Append("\'>");
                textWriter.WriteLine(sb);
                PrintBody(textWriter, sb, indent1);
                sb.Length = 0;
                sb.Append(indent); 
                sb.Append("</complexType>");
                textWriter.WriteLine(sb);
 
                return;
            }
 
            private Type _type;
        }
 
        private class RealSchemaType : ComplexSchemaType
        {
            internal RealSchemaType(Type type, XMLNamespace xns, String serviceEndpoint, Hashtable typeToServiceEndpoint, bool bUnique, WsdlGenerator WsdlGenerator)
            : base(type)
            {
                Util.Log("RealSchemaType.RealSchemaType "+type+" xns "+xns.Name+" serviceEndpoint "+serviceEndpoint+" bUnique "+bUnique);               
                _type = type;
                _serviceEndpoint = serviceEndpoint;
                _typeToServiceEndpoint = typeToServiceEndpoint;
                _bUnique = bUnique;
                _WsdlGenerator = WsdlGenerator;
                _bStruct = type.IsValueType;
                _xns = xns;
                _implIFaces = null;
                _iFaces = null;
                _methods = null;
                _fields = null;
                _methodTypes = null;
 
                _nestedTypes = type.GetNestedTypes();
                if (_nestedTypes != null)
                {
                    foreach (Type ntype in _nestedTypes)
                    {
                        Util.Log("RealSchemaType.RealSchemaType nested classes"+ntype);
                        _WsdlGenerator.AddType(ntype, xns);
                    }
                }
            }
 
            internal Type Type{
                get{ return(_type);}
            }
 
            internal XMLNamespace XNS{
                get{ return(_xns);}
            }
 
            internal bool IsUnique{
                get{ return(_bUnique);}
            }
 
            internal bool IsSUDSType{
                /*
                get{ return((_fields == null) &&
                            ((_iFaces.Length > 0) || (_methods.Length > 0) ||
                             (_type.IsInterface) || (s_delegateType.IsAssignableFrom(_type))));}
                             */
                get{ return((_iFaces != null && _iFaces.Length > 0) || 
                            (_methods != null && _methods.Length > 0) ||
                             (_type != null && _type.IsInterface) || 
                            (s_delegateType != null && s_delegateType.IsAssignableFrom(_type)));}
            }
 
            internal Type[] GetIntroducedInterfaces(){
                Util.Log("RealSchemaType.GetIntroducedInterfaces");
                Debug.Assert(_iFaces == null, "variable set");
                _iFaces = GetIntroducedInterfaces(_type);
                return(_iFaces);
            }
 
            internal MethodInfo[] GetIntroducedMethods(){
                Util.Log("RealSchemaType.GetIntroducedMethods");                
                Debug.Assert(_methods == null, "variable set");
                _methods = GetIntroducedMethods(_type, ref _methodAttributes);
                _methodTypes = new String[2*_methods.Length];
                return(_methods);
            }
 
            internal FieldInfo[] GetInstanceFields(){
                Util.Log("RealSchemaType.GetInstanceFields");               
                Debug.Assert(_fields == null, "variable set");
                //Debug.Assert(!WsdlGenerator.s_marshalByRefType.IsAssignableFrom(_type), "Invalid Type");
                _fields = GetInstanceFields(_type);
                return(_fields);
            }
 
            private bool IsNotSystemDefinedRoot(Type type, Type baseType)
            {
                if (!type.IsInterface &&
                    !type.IsValueType &&
                    baseType != null &&
                    baseType.BaseType != null &&
                    baseType != WsdlGenerator.s_marshalByRefType &&
                    baseType != WsdlGenerator.s_valueType &&
                    baseType != WsdlGenerator.s_objectType &&
                    baseType != WsdlGenerator.s_contextBoundType &&
                    baseType != WsdlGenerator.s_remotingClientProxyType &&
                    baseType.FullName != "System.EnterpriseServices.ServicedComponent" &&
                    baseType.FullName != "System.__ComObject")
                    return true;
                else 
                    return false;
            }
 
            internal void Resolve(StringBuilder sb){
                Util.Log("RealSchemaType.Resolve "+_type);             
                sb.Length = 0;
 
                // Check if this is a suds type
                bool bSUDSType = IsSUDSType;
 
 
                // Resolve base type eliminating system defined roots of the class heirarchy
 
                Type baseType = _type.BaseType;
                if (IsNotSystemDefinedRoot(_type, baseType))
                {                    
                    Util.Log("RealSchemaType.Resolve Not System Defined root "+baseType);                                                     
                    XMLNamespace xns = _WsdlGenerator.GetNamespace(baseType);
                    Debug.Assert(xns != null, "Namespace should have been found");
                    sb.Append(xns.Prefix);
                    sb.Append(':');
                    sb.Append(baseType.Name);
                    BaseName = sb.ToString();
                    if (bSUDSType)
                        _xns.DependsOnSUDSNS(xns);
                    Type ltype= _type; 
                    Type lbaseType = ltype.BaseType;
                    while(lbaseType != null && IsNotSystemDefinedRoot(ltype, lbaseType))
                    {
                        if (_typeToServiceEndpoint != null && !_typeToServiceEndpoint.ContainsKey(lbaseType.Name) && _typeToServiceEndpoint.ContainsKey(ltype.Name))
                        {
                            // type contains endpoints, but baseType doesn't, so assign the type's endpoints to the baseType.
                            // This is needed when a child has endpoints but the parent doesn't. A cast to the parent won't 
                            // find the object's endpoint
                            _typeToServiceEndpoint[lbaseType.Name] = _typeToServiceEndpoint[ltype.Name];
                        }
                        ltype = lbaseType;
                        lbaseType = ltype.BaseType;
                    }
 
                    Util.Log("RealSchemaType.Resolve Not System Defined root BaseName "+BaseName);                                 
                }
 
                // The element definition of this type depends on itself
                _xns.DependsOnSchemaNS(_xns, false);
 
                if (bSUDSType)
                {
                    Util.Log("RealSchemaType.Resolve AddRealSUDSType  "+_type);                                                     
                    _xns.AddRealSUDSType(this);
 
                    // Resolve interfaces introduced by this type
                    if (_iFaces.Length > 0)
                    {
                        _implIFaces = new String[_iFaces.Length];
                        for (int i=0;i<_iFaces.Length;i++)
                        {
                            String ns;
                            Assembly assem;
                            Util.Log("RealSchemaType.Resolve iFace  "+_iFaces[i].Name);                                                                                     
                            bool bInteropType = WsdlGenerator.GetNSAndAssembly(_iFaces[i], out ns, out assem);
                            XMLNamespace xns = _xns.LookupSchemaNamespace(ns, assem);
                            Debug.Assert(xns != null, "SchemaType should have been found");
                            sb.Length = 0;
                            sb.Append(xns.Prefix);
                            sb.Append(':');
                            sb.Append(_iFaces[i].Name);
                            _implIFaces[i] = sb.ToString();
                            _xns.DependsOnSUDSNS(xns);
                        }
                    }
 
                    // Resolve methods introduced by this type
                    if (_methods.Length > 0)
                    {
                        String useNS = null;
                        if (_xns.IsInteropType)
                            useNS = _xns.Name;
                        else
                        {
                            sb.Length = 0;
                            WsdlGenerator.QualifyName(sb, _xns.Name, Name);
                            useNS = sb.ToString();
                        }
                        XMLNamespace methodXNS = _xns.LookupSchemaNamespace(useNS, _xns.Assem);
                        Debug.Assert(methodXNS != null, "Namespace is null");
                        _xns.DependsOnSUDSNS(methodXNS);
                        _phony = new PhonySchemaType[_methods.Length];
                        for (int i=0;i<_methods.Length;i++)
                        {
                            // Process the request
                            MethodInfo method = _methods[i];
                            String methodRequestName = method.Name;
 
                            ParameterInfo[] parameters = method.GetParameters();
                            PhonySchemaType methodRequest = new PhonySchemaType(methodRequestName);
 
                            // Wsdl 
                            Util.Log("RealSchemaType.Resolve Wsdl  "+methodRequestName);
                            methodRequest._inParamTypes = new ArrayList(10); 
                            methodRequest._inParamNames = new ArrayList(10); 
                            methodRequest._outParamTypes = new ArrayList(10);
                            methodRequest._outParamNames = new ArrayList(10);
                            methodRequest._paramNamesOrder = new ArrayList(10);
 
                            int paramNameCnt = 0;
                            foreach (ParameterInfo param in parameters){
                                bool bmarshalIn = false;
                                bool bmarshalOut = false;
                                methodRequest._paramNamesOrder.Add(param.Name);
                                ParamInOut(param, out bmarshalIn, out bmarshalOut);
 
                                Type type = param.ParameterType;
                                String paramName = param.Name;
                                if (paramName == null || paramName.Length == 0)
                                    paramName = "param"+paramNameCnt++;
 
                                // Find the Wsdl type name
 
                                String stringType = TypeName(type, true, methodXNS);
                                // add to the method parameters
                                if (bmarshalIn)
                                {
                                    methodRequest._inParamNames.Add(paramName);
                                    methodRequest._inParamTypes.Add(stringType);
                                }
 
                                if (bmarshalOut)
                                {
                                    methodRequest._outParamNames.Add(paramName);
                                    methodRequest._outParamTypes.Add(stringType);
                                }
                            }
 
 
                            methodXNS.AddPhonySchemaType(methodRequest);
                            _phony[i] = methodRequest;
                            _methodTypes[2*i] = methodRequest.ElementName;
 
                            if (!RemotingServices.IsOneWay(method))
                            {
                                // Process response (look at custom attributes to get values
 
                                String returnName = null;
                                SoapMethodAttribute soapAttribute = (SoapMethodAttribute)InternalRemotingServices.GetCachedSoapAttribute(method);
                                if (soapAttribute.ReturnXmlElementName != null)
                                    returnName = soapAttribute.ReturnXmlElementName;
                                else
                                    returnName = "return";
 
                                String responseName = null;
                                if (soapAttribute.ResponseXmlElementName != null)
                                    responseName = soapAttribute.ResponseXmlElementName;
                                else
                                    responseName = methodRequestName + "Response";
 
                                PhonySchemaType methodResponse = new PhonySchemaType(responseName);
 
                                //Wsdl type
                                // out paramters alread processed above.
                                // return name stored in methodRequest PhonySchemaType
                                methodRequest._returnName = returnName;
                                Type returnType = method.ReturnType;
 
                                if (!((returnType == null) || (returnType == typeof(void))))
                                {
                                    methodRequest._returnType = TypeName(returnType, true, methodXNS);
                                }
                                methodXNS.AddPhonySchemaType(methodResponse);
                                _methodTypes[2*i+1] = methodResponse.ElementName;
                            }
                        }
                    }
                }
 
                // Resolve fields
                if (_fields != null)
                {
                    for (int i=0;i<_fields.Length;i++)
                    {
                        FieldInfo field = _fields[i];
                        Debug.Assert(!field.IsStatic, "Static field");
                        Type fieldType = field.FieldType;
                        if (fieldType == null)
                            fieldType = typeof(Object);
                        Util.Log("RealSchemaType.Resolve fields  "+field.Name+" type "+fieldType);                                                                                                              
                        AddParticle(new SchemaElement(field.Name, fieldType, false, _xns));
                    }
                }
 
                // Resolve attribute elements                
                return;
            }
 
            private void ParamInOut(ParameterInfo param, out bool bMarshalIn, out bool bMarshalOut)
            {
                bool bIsIn = param.IsIn;    // [In]
                bool bIsOut = param.IsOut;  // [Out]  note: out int a === [Out] ref int b
 
                bool bIsByRef = param.ParameterType.IsByRef; // (ref or normal)      
 
                bMarshalIn = false;
                bMarshalOut = false;
                if (bIsByRef)
                {
                    if (bIsIn == bIsOut)
                    {
                        // "ref int a" or "[In, Out] ref int a"
                        bMarshalIn = true;
                        bMarshalOut = true;
                    }
                    else
                    {
                        // "[In] ref int a" or "out int a"
                        bMarshalIn = bIsIn;     
                        bMarshalOut = bIsOut;  
                    }
                }
                else
                {
                    // "int a" or "[In, Out] a"
                    bMarshalIn = true;     
                    bMarshalOut = bIsOut;
                }
                Util.Log("RealSchemaType.ParamInOut "+param.Name+" ref,in,out "+bIsByRef+","+bIsIn+","+bIsOut+" bMarshalIn,bMarshalOut "+bMarshalIn+","+bMarshalOut);             
            }
 
 
            internal override void PrintSchemaType(TextWriter textWriter, StringBuilder sb, String indent, bool bAnonymous)
            {
                Util.Log("RealSchemaType.PrintSchemaType");             
                if (bAnonymous == false)
                {
                    sb.Length = 0;
                    sb.Append(indent);
                    sb.Append("<element name='");
                    sb.Append(ElementName);
                    sb.Append("' type='");
                    sb.Append(_xns.Prefix);
                    sb.Append(':');
                    sb.Append(FullRefName);
                    sb.Append("'/>");
                    textWriter.WriteLine(sb);
                }
 
                sb.Length = 0;
                sb.Append(indent);
                if (bAnonymous == false)
                {
                    sb.Append("<complexType name='");
                    sb.Append(FullRefName);
                    sb.Append('\'');
                }
                else
                {
                    sb.Append("<complexType ");
                }
                if (BaseName != null)
                {
                    sb.Append(" base='");
                    sb.Append(BaseName);
                    sb.Append('\'');
                }
                if ((IsSealed == true) &&
                    (bAnonymous == false))
                    sb.Append(" final='#all'");
                bool bEmpty = IsEmpty;
                if (bEmpty)
                    sb.Append("/>");
                else
                    sb.Append('>');
                textWriter.WriteLine(sb);
                if (bEmpty)
                    return;
 
                base.PrintBody(textWriter, sb, indent);
 
                textWriter.Write(indent);
                textWriter.WriteLine("</complexType>");
 
                return;
            }
 
 
            internal void PrintMessageWsdl(TextWriter textWriter, StringBuilder sb, String indent, ArrayList refNames)
            {
                Util.Log("RealSchemaType.PrintMessageWsdl "+Name);
 
                String indent1 = IndentP(indent);
                String indent2 = IndentP(indent1);
                String indent3 = IndentP(indent2);
                String ns = null;
                String nsPrefix = null;
                MethodInfo method = null;
                String methodName = null;
                String overloadedName = null;
                bool bIsOneWay = false;
 
                String useNS = null;
                if (_xns.IsInteropType)
                    useNS = _xns.Name;
                else
                {
                    sb.Length = 0;
 
                    WsdlGenerator.QualifyName(sb, _xns.Name, Name);
                    useNS = sb.ToString();
                }
                XMLNamespace methodXns = _xns.LookupSchemaNamespace(useNS, _xns.Assem);
 
                //Debug.Assert(methodXns != null, "Namespace is null");
 
                int methodsLength = 0;
                if (_methods != null)
                    methodsLength = _methods.Length;
 
                if (methodsLength > 0)
                {
                    ns = methodXns.Namespace;
                    nsPrefix = methodXns.Prefix;
                }
 
                refNames.Add(Name);
 
                for (int i=0;i<methodsLength;i++)
                {
                    method = _methods[i];
                    bIsOneWay = RemotingServices.IsOneWay(method);
                    methodName = PrintMethodName(method);
                    sb.Length = 0;
                    WsdlGenerator.QualifyName(sb, Name, _methodTypes[2*i]);
                    overloadedName = sb.ToString();
 
                    // Message element
                    sb.Length = 0;
                    sb.Append("\n");
                    sb.Append(indent);
                    sb.Append("<message name='");
                    sb.Append(overloadedName+"Input");
                    sb.Append("'>");
                    textWriter.WriteLine(sb);
 
                    PhonySchemaType phony = _phony[i];
 
 
                    if (phony._inParamTypes != null)
                    {
                        for (int iparam=0; iparam<phony._inParamTypes.Count; iparam++)
                        {
                            sb.Length = 0;
                            sb.Append(indent1);
                            sb.Append("<part name='");
                            sb.Append(phony._inParamNames[iparam]);
                            sb.Append("' type='");
                            sb.Append(phony._inParamTypes[iparam]);
                            sb.Append("'/>");
                            textWriter.WriteLine(sb);
                        }
 
                        sb.Length = 0;
                        sb.Append(indent);
                        sb.Append("</message>");
                        textWriter.WriteLine(sb);
 
                        if (!bIsOneWay)
                        {
                            sb.Length = 0;
                            sb.Append(indent);
                            sb.Append("<message name='");
                            sb.Append(overloadedName+"Output");
                            sb.Append("'>");
                            textWriter.WriteLine(sb);
 
                            if (phony._returnType != null || phony._outParamTypes != null)
                            {
                                if (phony._returnType != null)
                                {
                                    sb.Length = 0;
                                    sb.Append(indent1);
                                    sb.Append("<part name='");
                                    sb.Append(phony._returnName);
                                    sb.Append("' type='");
                                    sb.Append(phony._returnType);
                                    sb.Append("'/>");
                                    textWriter.WriteLine(sb);
                                }
 
                                if (phony._outParamTypes != null)
                                {
                                    for (int iparam=0; iparam<phony._outParamTypes.Count; iparam++)
                                    {
                                        sb.Length = 0;
                                        sb.Append(indent1);
                                        sb.Append("<part name='");
                                        sb.Append(phony._outParamNames[iparam]);
                                        sb.Append("' type='");
                                        sb.Append(phony._outParamTypes[iparam]);
                                        sb.Append("'/>");
                                        textWriter.WriteLine(sb);
                                    }
                                }
                            }
 
                            sb.Length = 0;
                            sb.Append(indent);
                            sb.Append("</message>");
                            textWriter.WriteLine(sb);
                        }
                    }
                }
 
                // PortType Element
                sb.Length = 0;
                sb.Append("\n");                    
                sb.Append(indent);
                sb.Append("<portType name='");
                sb.Append(Name);
                sb.Append("PortType");
                sb.Append("'>");
                textWriter.WriteLine(sb);
 
                for (int i=0;i<methodsLength;i++)
                {
                    method = _methods[i];
                    PhonySchemaType phony = _phony[i];
 
                    bIsOneWay = RemotingServices.IsOneWay(method);                  
                    methodName = PrintMethodName(method);
                    sb.Length = 0;                    
                    sb.Append("tns:");
                    WsdlGenerator.QualifyName(sb, Name, _methodTypes[2*i]);
                    overloadedName = sb.ToString();
 
                    sb.Length = 0;
                    sb.Append(indent1);
                    sb.Append("<operation name='");
                    sb.Append(methodName);
                    sb.Append("'");
                    if (phony != null && phony._paramNamesOrder.Count > 0)
                    {
 
                        sb.Append(" parameterOrder='");
                        bool bfirst = true;
                        foreach (String param in phony._paramNamesOrder)
                        {
                            if (!bfirst)
                                sb.Append(" ");
                            sb.Append(param);
                            bfirst = false;
                        }
                        sb.Append("'");
                    }
 
                    sb.Append(">");
                    textWriter.WriteLine(sb);
 
                    sb.Length = 0;
                    sb.Append(indent2);
                    sb.Append("<input name='");
                    sb.Append(_methodTypes[2*i]);
                    sb.Append("Request' ");                 
                    sb.Append("message='");
                    sb.Append(overloadedName);
                    sb.Append("Input");
                    sb.Append("'/>");
                    textWriter.WriteLine(sb);
 
                    if (!bIsOneWay)
                    {
                        sb.Length = 0;
                        sb.Append(indent2);
                        sb.Append("<output name='");
                        sb.Append(_methodTypes[2*i]);
                        sb.Append("Response' ");                    
 
                        sb.Append("message='");
                        sb.Append(overloadedName);
                        sb.Append("Output");
                        sb.Append("'/>");
                        textWriter.WriteLine(sb);
                    }
 
                    sb.Length = 0;
                    sb.Append(indent1);
                    sb.Append("</operation>");
                    textWriter.WriteLine(sb);
                }
 
                sb.Length = 0;
                sb.Append(indent);
                sb.Append("</portType>");
                textWriter.WriteLine(sb);
 
 
                // Binding 
                sb.Length = 0;
                sb.Append("\n");                    
                sb.Append(indent);
                sb.Append("<binding name='");
                sb.Append(Name);
                sb.Append("Binding");
                sb.Append("' ");
                sb.Append("type='tns:");                
                sb.Append(Name);
                sb.Append("PortType");
                sb.Append("'>");
                textWriter.WriteLine(sb);
 
                sb.Length = 0;
                sb.Append(indent1);
                sb.Append("<soap:binding style='rpc' transport='http://schemas.xmlsoap.org/soap/http'/>");
                textWriter.WriteLine(sb);
 
                if (_type.IsInterface || IsSUDSType)
                    PrintSuds(_type, _implIFaces, _nestedTypes, textWriter, sb, indent); // Some namespaces have no suds types
 
 
                if (!_xns.IsClassesPrinted)
                {
                    for (int i=0;i<_xns._realSchemaTypes.Count;i++)
                    {
                        RealSchemaType rsType = (RealSchemaType) _xns._realSchemaTypes[i];
                        Type type = rsType._type;
                        Util.Log("RealSchemaType.PrintMessageWsd suds realSchemaType "+type);
                        if (!rsType.Type.IsInterface && !rsType.IsSUDSType)
                        {
                            Util.Log("RealSchemaType.PrintMessageWsd suds realSchemaType 2 "+type.BaseType+" "+typeof(MulticastDelegate).IsAssignableFrom(type));;
 
                            Type[] iFaces = GetIntroducedInterfaces(rsType._type);
                            String[] implIFaces = null;
                            bool bUsedFaces = false;
                            if (iFaces.Length > 0)
                            {
                                implIFaces = new String[iFaces.Length];
                                for (int j=0;i<iFaces.Length;i++)
                                {
                                    String fns;
                                    Assembly fassem;
                                    Util.Log("RealSchemaType.PrintMessageWsdl iFace  "+iFaces[j].Name);
                                    bool bInteropType = WsdlGenerator.GetNSAndAssembly(iFaces[j], out fns, out fassem);
                                    XMLNamespace xns = _xns.LookupSchemaNamespace(fns, fassem);
                                    Debug.Assert(xns != null, "SchemaType should have been found");
                                    sb.Length = 0;
                                    sb.Append(xns.Prefix);
                                    sb.Append(':');
                                    sb.Append(iFaces[j].Name);
                                    implIFaces[j] = sb.ToString();
                                    if (implIFaces[j].Length > 0)
                                        bUsedFaces = true;
                                }
                            }
                            if (!bUsedFaces)
                                implIFaces = null;
 
                            PrintSuds(type, implIFaces, rsType._nestedTypes, textWriter, sb, indent);
                        }
                    }
                    _xns.IsClassesPrinted = true;
                }
 
 
                for (int i=0;i<methodsLength;i++)
                {
                    method = _methods[i];
                    methodName = PrintMethodName(method);
                    bIsOneWay = RemotingServices.IsOneWay(method);                                      
 
                    //binding operation
                    sb.Length = 0;
                    sb.Append(indent1);
                    sb.Append("<operation name='");
                    sb.Append(methodName);
                    sb.Append("'>");
                    textWriter.WriteLine(sb);
 
                    sb.Length = 0;
                    sb.Append(indent2);
                    sb.Append("<soap:operation soapAction='");
                    String soapAction = SoapServices.GetSoapActionFromMethodBase(method);
                    if ((soapAction != null) || (soapAction.Length > 0))
                    {
                        sb.Append(soapAction);
                    }
                    else
                    {
                        sb.Append(ns);
                        sb.Append('#');
                        sb.Append(methodName);
                    }
                    sb.Append("'/>");
                    textWriter.WriteLine(sb);
 
                    if (_methodAttributes != null && (i < _methodAttributes.Length) && _methodAttributes[i] != null)
                    {
                        // Suds for method attributes
                        // Attributes are only for public methods,
                        //  _method contains public and additional qualified interface methods
                        // The public methods are at the beginning of _methods
                        sb.Length = 0;
                        sb.Append(indent2);
                        sb.Append("<suds:method attributes='");
                        sb.Append(_methodAttributes[i]);
                        sb.Append("'/>");
                        textWriter.WriteLine(sb);
                    }
 
                    sb.Length = 0;
                    sb.Append(indent2);
                    sb.Append("<input name='");
                    sb.Append(_methodTypes[2*i]);
                    sb.Append("Request'>");                 
                    textWriter.WriteLine(sb);
 
                    sb.Length = 0;
                    sb.Append(indent3);
                    sb.Append("<soap:body use='encoded' encodingStyle='http://schemas.xmlsoap.org/soap/encoding/' namespace='");
                    String interopNamespace = SoapServices.GetXmlNamespaceForMethodCall(method);
		            if (interopNamespace == null)
			            sb.Append(ns);
		            else
			            sb.Append(interopNamespace);
                    sb.Append("'/>");
                    textWriter.WriteLine(sb);
 
                    sb.Length = 0;
                    sb.Append(indent2);
                    sb.Append("</input>");
                    textWriter.WriteLine(sb);
 
                    if (!bIsOneWay)
                    {
                        sb.Length = 0;
                        sb.Append(indent2);
                        sb.Append("<output name='");
                        sb.Append(_methodTypes[2*i]);
                        sb.Append("Response'>");                                        
                        textWriter.WriteLine(sb);
 
                        sb.Length = 0;
                        sb.Append(indent3);
                        sb.Append("<soap:body use='encoded' encodingStyle='http://schemas.xmlsoap.org/soap/encoding/' namespace='");
                        interopNamespace = SoapServices.GetXmlNamespaceForMethodResponse(method);
			            if (interopNamespace == null)
			                sb.Append(ns);
			            else
			                sb.Append(interopNamespace);
                        sb.Append("'/>");
                        textWriter.WriteLine(sb);
 
                        sb.Length = 0;
                        sb.Append(indent2);
                        sb.Append("</output>");
                        textWriter.WriteLine(sb);
                    }
 
                    sb.Length = 0;
                    sb.Append(indent1);
                    sb.Append("</operation>");
                    textWriter.WriteLine(sb);
                }
 
                sb.Length=0;
                sb.Append(indent);
                sb.Append("</binding>");
                textWriter.WriteLine(sb);                       
            }
 
            private void PrintSuds(Type type, String[] implIFaces, Type[] nestedTypes, TextWriter textWriter, StringBuilder sb, String indent)
            {
                Util.Log("RealSchemaType.PrintSuds  "+type+" implIFaces "+implIFaces+" nestedTypes "+nestedTypes);
                String indent1 = IndentP(indent);
                String indent2 = IndentP(indent1);
                String indent3 = IndentP(indent2);
 
                String sudsEnd = null;
                // Type, interface, extends information
                sb.Length = 0;
                sb.Append(indent1);
                if (type.IsInterface)
                {
                    sb.Append("<suds:interface type='");
                    sudsEnd = "</suds:interface>";
 
 
                }
                else if (type.IsValueType)
                {
                    sb.Append("<suds:struct type='");
                    sudsEnd = "</suds:struct>";
                }
                else
                {
                    sb.Append("<suds:class type='");
                    sudsEnd = "</suds:class>";
                }
                sb.Append(_xns.Prefix);
                sb.Append(':');
                sb.Append(WsdlGenerator.RefName(type));
                sb.Append("'");
 
                Type baseType = type.BaseType;
                if (IsNotSystemDefinedRoot(type, baseType))
                {
                    XMLNamespace xns = _WsdlGenerator.GetNamespace(baseType);
                    sb.Append(" extends='");
                    sb.Append(xns.Prefix);
                    sb.Append(':');
                    sb.Append(baseType.Name);
                    sb.Append("'");
 
                }
 
                if (baseType != null && baseType.FullName == "System.EnterpriseServices.ServicedComponent")
                    sb.Append(" rootType='ServicedComponent'");
                else if (typeof(Delegate).IsAssignableFrom(type) || typeof(MulticastDelegate).IsAssignableFrom(type))
                    sb.Append(" rootType='Delegate'");
                else if (typeof(MarshalByRefObject).IsAssignableFrom(type))
                    sb.Append(" rootType='MarshalByRefObject'");
                else if (typeof(ISerializable).IsAssignableFrom(type))
                    sb.Append(" rootType='ISerializable'");
 
                if (implIFaces == null && nestedTypes == null)
                    sb.Append("/>");
                else
                    sb.Append(">");
 
                textWriter.WriteLine(sb);
 
                String extendAttribute = null;
                if (type.IsInterface)
                    extendAttribute = "<suds:extends type='";
                else
                    extendAttribute = "<suds:implements type='";
 
 
                if (implIFaces != null)
                {
                    for (int j=0;j<implIFaces.Length;j++)
                    {
                        if (!(implIFaces[j] == null || implIFaces[j] == String.Empty))
                        {
                            sb.Length = 0;
                            sb.Append(indent2);                                 
                            sb.Append(extendAttribute);
                            sb.Append(implIFaces[j]);
                            sb.Append("'/>");
                            textWriter.WriteLine(sb);
                        }
                    }
                }
 
                if (nestedTypes != null)
                {
                    for (int j=0;j<nestedTypes.Length;j++)
                    {
                            sb.Length = 0;
                            sb.Append(indent2);                                 
                            sb.Append("<suds:nestedType name='");
                            sb.Append(nestedTypes[j].Name);
                            sb.Append("' type='");
                            sb.Append(_xns.Prefix);
                            sb.Append(':');
                            sb.Append(WsdlGenerator.RefName(nestedTypes[j]));
                            sb.Append("'/>");
                            textWriter.WriteLine(sb);
                    }
                }
 
                if (implIFaces != null || nestedTypes != null)
                {
                    sb.Length = 0;
                    sb.Append(indent1);
                    sb.Append(sudsEnd);
                    textWriter.WriteLine(sb);
                }
            }
 
 
            private static String ProcessArray(Type type, XMLNamespace xns)
            {
                Util.Log("RealSchemaType.ProcessArray Enter "+type);
                String qname = null;
                bool bbinary = false;
                Type elementType = type.GetElementType();
                String elementTypeName = "ArrayOf";
                while (elementType.IsArray)
                {
                    elementTypeName = elementTypeName+"ArrayOf";
                    elementType = elementType.GetElementType();
                }
 
                qname = RealSchemaType.TypeName(elementType, true, xns);
                int index = qname.IndexOf(":");
                String prefix = qname.Substring(0, index);
                String wireName = qname.Substring(index+1);
                Util.Log("RealSchemaType.ProcessArray qname "+qname+" wirename "+wireName);
                int rank =  type.GetArrayRank();
                String rankStr = "";
                if (rank > 1)
                    rankStr = rank.ToString(CultureInfo.InvariantCulture);
                String csname =elementTypeName+wireName.Substring(0,1).ToUpper(CultureInfo.InvariantCulture)+wireName.Substring(1)+rankStr;
                csname = csname.Replace('+','N'); // need to get rid of + in nested classes
                ArraySchemaType ast = xns.LookupArraySchemaType(csname); 
                if (ast == null)
                {
                    ArraySchemaType cstype = new ArraySchemaType(type, csname, SchemaBlockType.ComplexContent, false);
                    Restriction restriction = new Restriction();
                    SchemaAttribute attribute = new SchemaAttribute();
                    if (bbinary)
                        attribute.AddArray(qname);
                    else
                    {
                        String arrayTypeName = type.Name;
                        index = arrayTypeName.IndexOf("[");
                        attribute.AddArray(qname+arrayTypeName.Substring(index));
                    }
 
                    restriction.AddArray(attribute);
                    cstype.AddParticle(restriction);
                    xns.AddArraySchemaType(cstype);
                }
 
                String returnStr = xns.Prefix+":"+csname;
                Util.Log("RealSchemaType.ProcessArray Exit "+returnStr);
                return returnStr;
            }
 
 
 
            internal static String TypeName(Type type, bool bEmbedded, XMLNamespace thisxns)
            {
                Util.Log("RealSchemaType.TypeName entry "+type+" bEmbedded "+bEmbedded+" xns "+thisxns.Name);              
                String typeName = null;
                if (type.IsArray)
                    return ProcessArray(type, thisxns);
 
                String clrTypeName = WsdlGenerator.RefName(type);
                Type clrType = type;
 
                // If ref type the name ends in &
                if (type.IsByRef)
                {
                    clrType = type.GetElementType(); 
                    clrTypeName = WsdlGenerator.RefName(clrType);
                    if (clrType.IsArray)
                        return ProcessArray(clrType, thisxns);
                }
 
                typeName = SudsConverter.MapClrTypeToXsdType(clrType);
 
                if (typeName == null)
                {
                    String ns = type.Namespace;
                    Assembly assem = type.Module.Assembly; 
                    XMLNamespace xns = null;
                    Util.Log("RealSchemaType.TypeName realNS "+ns);
                    xns = (XMLNamespace)thisxns.Generator._typeToInteropNS[type];
 
                    if (xns == null)
                    {
                        xns = thisxns.LookupSchemaNamespace(ns, assem);
                        if (xns == null)
                        {
                            xns = thisxns.Generator.LookupNamespace(ns,assem);
                            if (xns == null)
                            {
                                xns = thisxns.Generator.AddNamespace(ns, assem);
                            }
                            thisxns.DependsOnSchemaNS(xns, false);
                        }
                        Util.Log("RealSchemaType.TypeName depended NS with assem equals "+xns.Name);
                    }
                    StringBuilder sb = new StringBuilder(256);
 
                    sb.Append(xns.Prefix);
                    sb.Append(':');
                    sb.Append(clrTypeName);
                    typeName = sb.ToString();
                }
 
                Util.Log("RealSchemaType.TypeName exit "+typeName);
                return typeName;
            }
            
 
            static private Type[] GetIntroducedInterfaces(Type type)
            {
                ArrayList ifaceA = new ArrayList();
                Type[] typeA = type.GetInterfaces();
                // remove system interfaces.
                foreach (Type itype in typeA)
                {
                    if (!itype.FullName.StartsWith("System."))
                    {
                        ifaceA.Add(itype);
                        Util.Log("RealSchemaType.GetIntroducedInterfaces "+type+" Interfaces "+itype);
                    }
                }
 
                Util.Log("RealSchemaType.GetIntroducedInterfaces "+type+" typeInterface? "+type.IsInterface+" number of interfaces "+typeA.Length);               
 
                Type[] ifaceTypes = new Type[ifaceA.Count];
                for(int i=0; i<ifaceA.Count; i++)
                   ifaceTypes[i] = (Type)ifaceA[i];
                return ifaceTypes;
            }
 
            static private void FindMethodAttributes(Type type, MethodInfo[] infos, ref String[] methodAttributes, BindingFlags bFlags)
            {
                Util.Log("RealSchemaType.FindMethodAttributes Enter "+type);
                Type baseType = type;
                ArrayList inherit = new ArrayList();
                while (true)
                {
                    baseType = baseType.BaseType;
 
                    Util.Log("RealSchemaType.FindMethodAttributes baseType "+baseType);
                    if (baseType != null && !baseType.FullName.StartsWith("System."))
                        inherit.Add(baseType);
                    else
                        break;
                }
 
                StringBuilder sb = new StringBuilder();
                for(int i=0; i<infos.Length; i++)
                {
                    MethodBase info = (MethodBase)infos[i];
                    sb.Length = 0;
                    MethodAttributes ma = info.Attributes;
                    bool bVirtual = info.IsVirtual;
                    bool bNewSlot = ((ma & MethodAttributes.NewSlot) == MethodAttributes.NewSlot);
                    Util.Log("RealSchemaType.FindMethodAttributes "+info.Name+" bVirtual "+bVirtual+" bNewSlot "+bNewSlot+" hidebysig "+info.IsHideBySig);
                    if (info.IsPublic)
                        sb.Append("public");
                    else if (info.IsFamily)
                        sb.Append("protected");
                    else if (info.IsAssembly)
                        sb.Append("internal");
                    
                    // See if method hides inherited methods
                    bool bHides = false;
                    for (int j=0; j<inherit.Count; j++)
                    {
                        baseType = (Type)inherit[j];
                        ParameterInfo[] paramInfos = info.GetParameters();
                        Type[] types = new Type[paramInfos.Length];
                        for (int itype=0; itype<types.Length; itype++)
                        {
                            types[itype] = paramInfos[itype].ParameterType;
                        }
                        MethodInfo baseInfo = baseType.GetMethod(info.Name, types);
                        if (baseInfo != null)
                        {
                            // Hides
                            if (sb.Length > 0)
                                sb.Append(" ");
                            if (bNewSlot || baseInfo.IsFinal)
                                sb.Append("new");
                            else if (baseInfo.IsVirtual && bVirtual)
                                sb.Append("override");
                            else 
                                sb.Append("new");
                            bHides = true;
                            break;
                        }
                    }
                    if (!bHides && bVirtual)
                    {
                        if (sb.Length > 0)
                            sb.Append(" ");
                        sb.Append("virtual");
                    }
 
                    if (sb.Length > 0)
                    {
                        methodAttributes[i] = sb.ToString();
                        Util.Log("RealSchemaType.FindMethodAttributes Exit "+info.Name+" "+methodAttributes[i]);     
                    }
                }
            }
 
            static private MethodInfo[] GetIntroducedMethods(Type type, ref String[] methodAttributes)
            {
                Util.Log("RealSchemaType.GetIntroducedMethods "+type);     
 
 
                // Methods in the class are either the class public methods or interface qualified methods
 
                BindingFlags bFlags = BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public;
                MethodInfo[] methodInfos = type.GetMethods(bFlags); //public methods (including unqualified interface methods)
 
                if (type.IsInterface)
                    return methodInfos;
 
                // Find method attributes for public  methods
                methodAttributes = new String[methodInfos.Length];
                FindMethodAttributes(type, methodInfos, ref methodAttributes, bFlags);
 
                // Get any class methods which are interface qualifed methods.
                // interface qualified methods are not public in the metadata.
                ArrayList additionalInfos = new ArrayList();
                Type[] itypeA = type.GetInterfaces();
                foreach (Type itype in itypeA )
                {
                    InterfaceMapping im = type.GetInterfaceMap(itype);
                    foreach (MethodInfo mi in im.TargetMethods)
                    {
                        if (!mi.IsPublic && type.GetMethod(mi.Name, bFlags | BindingFlags.NonPublic) != null)
                        {
                            additionalInfos.Add(mi);
                        }
                    }
                }
 
                // Combine all the methodinfos into one structure
                MethodInfo[] finalMethodInfos = null;
                if (additionalInfos.Count > 0)
                {
                    finalMethodInfos = new MethodInfo[methodInfos.Length + additionalInfos.Count];
                    for(int i=0; i<methodInfos.Length; i++)
                        finalMethodInfos[i] = methodInfos[i];
                    for(int i=0; i<additionalInfos.Count; i++)
                        finalMethodInfos[methodInfos.Length+i] = (MethodInfo)additionalInfos[i];
                }
                else
                    finalMethodInfos = methodInfos;
 
                return finalMethodInfos;
            }
 
            internal static String PrintMethodName(MethodInfo methodInfo)
            {
                String methodName = methodInfo.Name;
                int lastDot = 0;
                int prevDot = 0;
 
                for (int i=0; i<methodName.Length; i++)
                {
                    if (methodName[i] == '.')
                    {
                        prevDot = lastDot;
                        lastDot = i;
                    }
                }
 
                String iname = methodName;
 
                if (prevDot > 0)
                    iname = methodName.Substring(prevDot+1);
 
                return iname;
            }
 
            static private FieldInfo[] GetInstanceFields(Type type){
                Util.Log("RealSchemaType.GetIntroducedFields "+type);                               
 
                BindingFlags bFlags = BindingFlags.DeclaredOnly | BindingFlags.Instance |
                                      BindingFlags.Public;
 
                if (!s_marshalByRefType.IsAssignableFrom(type))
                    bFlags |= BindingFlags.NonPublic;
 
                FieldInfo[] fields = type.GetFields(bFlags);
                Util.Log("RealSchemaType.GetIntroducedFields length "+fields.Length);                               
                int actualLength = fields.Length;
                if (actualLength == 0)
                    return(emptyFieldSet);
 
                for (int i=0;i<fields.Length;i++)
                {
                    Util.Log("RealSchemaType.GetInstanceFields field "+fields[i].Name+" "+fields[i].FieldType+" type "+type);
                    if (fields[i].IsStatic)
                    {
                        Debug.Assert(false, "Static Field");
                        Util.Log("RealSchemaType.GetInstanceFields field  static "+fields[i].FieldType);
                        --actualLength;
                        fields[i] = fields[actualLength];
                        fields[actualLength] = null;
                    }
                }
 
                if (actualLength < fields.Length)
                {
                    FieldInfo[] ifields = new FieldInfo[actualLength];
                    Array.Copy(fields, ifields, actualLength);
                    Util.Log("RealSchemaType.GetInstanceFields adjust length "+actualLength);
                    return(ifields);
                }
 
                return(fields);
            }
 
            // Instance fields
            private WsdlGenerator _WsdlGenerator;
            private Type _type;
            private String _serviceEndpoint;
            private Hashtable _typeToServiceEndpoint;
            private bool _bUnique;
            private XMLNamespace _xns;
            private bool _bStruct;
            private String[] _implIFaces;
 
            private Type[] _iFaces;
            private MethodInfo[] _methods;
            private String[] _methodAttributes;
            private String[] _methodTypes;
            private FieldInfo[] _fields;
            private PhonySchemaType[] _phony;
            internal Type[] _nestedTypes;
 
            // Static fields
            private static Type[] emptyTypeSet = new Type[0];
            private static MethodInfo[] emptyMethodSet = new MethodInfo[0];
            private static FieldInfo[] emptyFieldSet = new FieldInfo[0];
        }
 
        private class XMLNamespace
        {
            internal XMLNamespace(String name, Assembly assem, String serviceEndpoint, Hashtable typeToServiceEndpoint, String prefix, bool bInteropType, WsdlGenerator generator ){
                Util.Log("XMLNamespace.XMLNamespace Enter "+name+" serviceEndpoint "+serviceEndpoint+" prefix "+prefix+" bInteropType "+bInteropType);
                _name = name;
                _assem = assem;
                _bUnique = false;
                _bInteropType = bInteropType;
                _generator = generator;
                StringBuilder sb = new StringBuilder(256);
                Assembly systemAssembly = typeof(String).Module.Assembly;
 
                // Remove leading . for an empty namespace
 
                if (!_bInteropType)
                {
                    if (assem == systemAssembly)
                    {
                        sb.Append(SoapServices.CodeXmlNamespaceForClrTypeNamespace(name, null));
                    }
                    else if (assem != null)
                    {
                        sb.Append(SoapServices.CodeXmlNamespaceForClrTypeNamespace(name, assem.FullName));
                    }
                }
                else
                {
                    sb.Append(name);
                }
                _namespace = sb.ToString();
                _prefix = prefix;
                _dependsOnSchemaNS = new ArrayList();
                _realSUDSTypes = new ArrayList();
                _dependsOnSUDSNS = new ArrayList();
                _realSchemaTypes = new ArrayList();
                _phonySchemaTypes = new ArrayList();
                _simpleSchemaTypes = new ArrayList();
                _arraySchemaTypes = new ArrayList();
                _xnsImports = new ArrayList();
                _serviceEndpoint = serviceEndpoint;
                _typeToServiceEndpoint = typeToServiceEndpoint;
                Util.Log("XMLNamespace.XMLNamespace exit "+_namespace);
            }
 
            internal String Name{
                get{ return(_name);}
            }
            internal Assembly Assem{
                get{ return(_assem);}
            }
            internal String Prefix{
                get{ return(_prefix);}
            }
            internal String Namespace{
                get{ return(_namespace);}
            }
 
            internal bool IsInteropType{
                get{return(_bInteropType);}
            }
 
            internal WsdlGenerator Generator
            {
                get {return (_generator);}
            }
 
            internal bool IsClassesPrinted
            {
                get {return _bClassesPrinted;}
                set {_bClassesPrinted = value;}
            }
 
 
            //internal XMLNamespace(String name, Assembly assem, String serviceEndpoint, Hashtable typeToServiceEndpoint, String prefix, bool bInteropType, WsdlGenerator generator ){
 
            /*
            internal SchemaType LookupSchemaType(Type type)
            {
                return (SchemaType)_typeToSchemaType[type];
            }
 
            internal Type LookupType(SchemaType stype)
            {
                return (Type)_schemaTypeToType[stype];
            }
            */
	        
            internal Type LookupSchemaType(String name)
            {
                Type returnType = null;
                RealSchemaType rsType = LookupRealSchemaType(name);
                if (rsType != null)
                    returnType = rsType.Type;
 
                SimpleSchemaType ssType = LookupSimpleSchemaType(name);
                if (ssType != null)
                    returnType = ssType.Type;
 
                ArraySchemaType asType = LookupArraySchemaType(name);
                if (asType != null)
                    returnType = asType.Type;
 
                Util.Log("XMLNamespace.LookupSchemaType "+name+" return "+returnType);
                return(returnType);
            }
 
            internal SimpleSchemaType LookupSimpleSchemaType(String name){
                Util.Log("XMLNamespace.LookupSimpleSchemaType "+name);              
                for (int i=0;i<_simpleSchemaTypes.Count;i++)
                {
                    SimpleSchemaType ssType = (SimpleSchemaType) _simpleSchemaTypes[i];
                    if (ssType.FullRefName == name)
                        return(ssType);
                }
 
                return(null);
            }
            
            internal bool CheckForSchemaContent()
	        {
                if (_arraySchemaTypes.Count > 0 ||
                    _simpleSchemaTypes.Count > 0)
		            return true;
 
    		    if (_realSchemaTypes.Count ==  0)
    		        return false;
    
    		    bool bRealSchema = false;
    		    for (int i=0;i<_realSchemaTypes.Count;i++)
    		    {
    		        RealSchemaType rsType = (RealSchemaType) _realSchemaTypes[i];
    		        if (!rsType.Type.IsInterface && !rsType.IsSUDSType)
    		        {
        			    bRealSchema = true;
        	    		break;
    	    	    }
    		    }
    
    		    if (bRealSchema)
    		        return true;
    		    else
    		        return false;
    	    }
            
            internal RealSchemaType LookupRealSchemaType(String name){
                Util.Log("XMLNamespace.LookupRealSchemaType "+name);                                
                Debug.Assert(_phonySchemaTypes.Count == 0, "PhonyTypes present");
                for (int i=0;i<_realSchemaTypes.Count;i++)
                {
                    RealSchemaType rsType = (RealSchemaType) _realSchemaTypes[i];
                    if (rsType.FullRefName == name)
                        return(rsType);
                }
 
                return(null);
            }
 
            internal ArraySchemaType LookupArraySchemaType(String name){
                Util.Log("XMLNamespace.LookupArraySchemaType "+name);                                
                //Debug.Assert(_phonySchemaTypes.Count == 0, "PhonyTypes present");
                for (int i=0;i<_arraySchemaTypes.Count;i++)
                {
                    ArraySchemaType asType = (ArraySchemaType) _arraySchemaTypes[i];
                    if (asType.Name == name)
                        return(asType);
                }
 
                return(null);
            }
 
            internal void AddRealSUDSType(RealSchemaType rsType){
                Util.Log("XMLNamespace.AddRealSUDSType "+rsType.Type);                              
                _realSUDSTypes.Add(rsType);
                //_typeToSchemaType[rsType.Type] = rsType;
                //_schemaTypeToType[rsType] = rsType.Type;
                return;
            }
 
            internal void AddRealSchemaType(RealSchemaType rsType){
                Util.Log("XMLNamespace.AddRealSchemaType "+rsType.Type);                              
                Debug.Assert(LookupRealSchemaType(rsType.Name) == null, "Duplicate Type found");
                _realSchemaTypes.Add(rsType);
                if (rsType.IsUnique)
                    _bUnique = true;
                //_typeToSchemaType[rsType.Type] = rsType;
                //_schemaTypeToType[rsType] = rsType.Type;
                return;
            }
 
            internal void AddArraySchemaType(ArraySchemaType asType){
                Debug.Assert(LookupArraySchemaType(asType.Name) == null, "Duplicate Type found");
                _arraySchemaTypes.Add(asType);
                //_typeToSchemaType[asType.Type] = asType;
                //_schemaTypeToType[asType] = asType.Type;
                return;
            }
            
            internal void AddSimpleSchemaType(SimpleSchemaType ssType){
                Util.Log("XMLNamespace.AddSimpleSchemaType "+ssType.Type);                              
                Debug.Assert(LookupSimpleSchemaType(ssType.Type.Name) == null, "Duplicate Type found");
                _simpleSchemaTypes.Add(ssType);
                //_typeToSchemaType[ssType.Type] = ssType;
                //_schemaTypeToType[ssType] = ssType.Type;
                return;
            }
 
            internal PhonySchemaType LookupPhonySchemaType(String name){
                Util.Log("XMLNamespace.LookupPhonySchemaType "+name);                                               
                for (int i=0;i<_phonySchemaTypes.Count;i++)
                {
                    PhonySchemaType type = (PhonySchemaType) _phonySchemaTypes[i];
                    if (type.Name == name)
                        return(type);
                }
 
                return(null);
            }
 
            internal void AddPhonySchemaType(PhonySchemaType phType){
                Util.Log("XMLNamespace.AddPhonySchemaType "+phType.Name);                                                               
                PhonySchemaType overloadedType = LookupPhonySchemaType(phType.Name);
                if (overloadedType != null)
                    phType.ElementName = phType.Name + overloadedType.OverloadedType();
                _phonySchemaTypes.Add(phType);
 
                return;
            }
 
            internal XMLNamespace LookupSchemaNamespace(String ns, Assembly assem){
                Util.Log("XMLNamespace.LookupSchemaNamespace "+ns);                                                             
                for (int i=0;i<_dependsOnSchemaNS.Count;i++)
                {
                    XMLNamespace xns = (XMLNamespace) _dependsOnSchemaNS[i];
                    if ((xns.Name == ns) && (xns.Assem == assem))
                        return(xns);
                }
 
                return(null);
            }
 
            internal void DependsOnSchemaNS(XMLNamespace xns, bool bImport){
                Util.Log("XMLNamespace.DependsOnSchemaNS "+Namespace+" depends on "+xns.Namespace+" bImport "+bImport);                                                              
                if (LookupSchemaNamespace(xns.Name, xns.Assem) != null)
                    return;
 
                _dependsOnSchemaNS.Add(xns);
                if (bImport && Namespace != xns.Namespace)
                    _xnsImports.Add(xns);
                return;
            }
 
            private XMLNamespace LookupSUDSNamespace(String ns, Assembly assem){
                Util.Log("XMLNamespace.LookupSUDSNamespace "+ns);                                                               
                for (int i=0;i<_dependsOnSUDSNS.Count;i++)
                {
                    XMLNamespace xns = (XMLNamespace) _dependsOnSUDSNS[i];
                    if ((xns.Name == ns) && (xns.Assem == assem))
                        return(xns);
                }
 
                return(null);
            }
 
            internal void DependsOnSUDSNS(XMLNamespace xns){
                Util.Log("XMLNamespace.DependsOnSUDSNS "+xns.Name+" "+xns.Assem);
                if (LookupSUDSNamespace(xns.Name, xns.Assem) != null)
                    return;
 
                _dependsOnSUDSNS.Add(xns);
                return;
            }
 
            internal void Resolve(){
                Util.Log("XMLNamespace.Resolve");                                                               
                StringBuilder sb = new StringBuilder(256);
                for (int i=0;i<_realSchemaTypes.Count;i++)
                    ((RealSchemaType) _realSchemaTypes[i]).Resolve(sb);
 
                return;
            }
 
            internal void PrintDependsOnWsdl(TextWriter textWriter, StringBuilder sb, String indent, Hashtable usedNames)
            {
                Util.Log("XMLNamespace.PrintDependsOn "+_name+" targetNameSpace "+Namespace);                                                                                                   
                if (_dependsOnSchemaNS.Count > 0)
                {
                    for (int i=0;i<_dependsOnSchemaNS.Count;i++)
                    {
                        XMLNamespace xns = (XMLNamespace) _dependsOnSchemaNS[i];
                        if (!usedNames.ContainsKey(xns.Prefix))
                        {
                            usedNames[xns.Prefix] = null;
                            sb.Length = 0;
                            sb.Append(indent);
                            sb.Append("xmlns:");                            
                            sb.Append(xns.Prefix);
                            sb.Append("='");
                            sb.Append(xns.Namespace);
                            sb.Append("'");
                            textWriter.WriteLine(sb);
                        }
                    }
                }
            }            
 
            internal void PrintSchemaWsdl(TextWriter textWriter, StringBuilder sb, String indent){
                Util.Log("XMLNamespace.PrintSchemaWsdl "+Namespace+" _realSchemaTypes.Count "+_realSchemaTypes.Count);                      
                // Print schema types
 
                bool bReal = false; 
 
                /*
                for(int i=0;i<_realSchemaTypes.Count;i++)
                {
                    RealSchemaType rsType = (RealSchemaType) _realSchemaTypes[i];
                    if(!rsType.Type.IsInterface && !rsType.IsSUDSType)
                        bReal = true;
                }
                */
 
                if ((_simpleSchemaTypes.Count > 0) || (_realSchemaTypes.Count > 0) || (_arraySchemaTypes.Count > 0))
                {
                    bReal = true;
                }
 
                // Print schema types
                if (bReal)
                {
                    // schema begin
                    String indent1 = IndentP(indent);
                    String indent2 = IndentP(indent1);
                    String indent3 = IndentP(indent2);
                    String indent4 = IndentP(indent3);                                  
                    sb.Length = 0;
                    sb.Append(indent);
                    sb.Append("<schema ");
                    sb.Append("targetNamespace='");
                    sb.Append(Namespace);
                    sb.Append("'");
                    textWriter.WriteLine(sb);
 
                    sb.Length = 0;
                    sb.Append(indent2);
                    sb.Append("xmlns='");
                    sb.Append(SudsConverter.GetXsdVersion(_generator._xsdVersion));
                    sb.Append("'");
                    textWriter.WriteLine(sb);
 
                    sb.Length = 0;
                    sb.Append(indent2);         
                    sb.Append("elementFormDefault='unqualified' attributeFormDefault='unqualified'>");
                    textWriter.WriteLine(sb);
 
                    // Write import statements
                    foreach (XMLNamespace xns in _xnsImports)
                    {
                        sb.Length = 0;
                        sb.Append(indent1);
                        sb.Append("<import namespace='");
                        sb.Append(xns.Namespace);
                        sb.Append("'/>");
                        textWriter.WriteLine(sb);
                    }
 
 
                    for (int i=0;i<_simpleSchemaTypes.Count;i++)
                    {
                        SimpleSchemaType ssType = (SimpleSchemaType) _simpleSchemaTypes[i];
                        ssType.PrintSchemaType(textWriter, sb, indent1, false);
                    }
 
                    for (int i=0;i<_realSchemaTypes.Count;i++)
                    {
                        RealSchemaType rsType = (RealSchemaType) _realSchemaTypes[i];
                        if (!rsType.Type.IsInterface && !rsType.IsSUDSType)
                            rsType.PrintSchemaType(textWriter, sb, indent1, false);
                    }
 
                    for (int i=0;i<_arraySchemaTypes.Count;i++)
                    {
                        ArraySchemaType asType = (ArraySchemaType) _arraySchemaTypes[i];
                        asType.PrintSchemaType(textWriter, sb, indent1, false);
                    }
 
 
                    /*
                    for(int i=0;i<_phonySchemaTypes.Count;i++)
                    {
                        PhonySchemaType psType = (PhonySchemaType) _phonySchemaTypes[i];
                        psType.PrintSchemaType(textWriter, sb, indent1, true);
                    }
                    */
 
                    sb.Length = 0;
                    sb.Append(indent);
                    sb.Append("</schema>");
                    textWriter.WriteLine(sb);
 
 
                }
            }
 
            internal void PrintMessageWsdl(TextWriter textWriter, StringBuilder sb, String indent, ArrayList refNames)
            {
                Util.Log("XmlNamespace.PrintMessageWsdl");
                for (int i=0;i<_realSUDSTypes.Count;i++)
                    ((RealSchemaType) _realSUDSTypes[i]).PrintMessageWsdl(textWriter, sb, indent, refNames);
                
                if (_realSUDSTypes.Count == 0 && _realSchemaTypes.Count > 0)
                {
                    // If no suds type, we still generate a binding section to print the Suds Extendsions
                    // We only need to do this once, because all the realschema types will be placed into
                    // one binding
                    ((RealSchemaType) _realSchemaTypes[0]).PrintMessageWsdl(textWriter, sb, indent, new ArrayList());
                }
            }
 
            // Fields
            private String _name;
            private Assembly _assem;
            private String _namespace;
            private String _prefix;
 // disable csharp compiler warning #0414: field assigned unused value
#pragma warning disable 0414
           internal bool _bUnique; 
#pragma warning restore 0414
            private ArrayList _dependsOnSUDSNS;
            private ArrayList _realSUDSTypes;
            private ArrayList _dependsOnSchemaNS;
            internal ArrayList _realSchemaTypes;
            private ArrayList _phonySchemaTypes;
            private ArrayList _simpleSchemaTypes;
            private ArrayList _arraySchemaTypes;
            private bool _bInteropType;
            private String _serviceEndpoint;
            private Hashtable _typeToServiceEndpoint;
            private WsdlGenerator _generator;
            private ArrayList _xnsImports;
            private bool _bClassesPrinted = false;
            //private Hashtable _typeToSchemaType = new Hashtable();
            //private Hashtable _schemaTypeToType = new Hashtable();
 
 
        }
 
        internal static String IndentP(String indentStr){
            return indentStr+"    ";
        }
 
    }
}