XmlSchemaImporter.cs :  » 2.6.4-mono-.net-core » System.Xml » System » Xml » Serialization » C# / CSharp Open Source

Home
C# / CSharp Open Source
1.2.6.4 mono .net core
2.2.6.4 mono core
3.Aspect Oriented Frameworks
4.Bloggers
5.Build Systems
6.Business Application
7.Charting Reporting Tools
8.Chat Servers
9.Code Coverage Tools
10.Content Management Systems CMS
11.CRM ERP
12.Database
13.Development
14.Email
15.Forum
16.Game
17.GIS
18.GUI
19.IDEs
20.Installers Generators
21.Inversion of Control Dependency Injection
22.Issue Tracking
23.Logging Tools
24.Message
25.Mobile
26.Network Clients
27.Network Servers
28.Office
29.PDF
30.Persistence Frameworks
31.Portals
32.Profilers
33.Project Management
34.RSS RDF
35.Rule Engines
36.Script
37.Search Engines
38.Sound Audio
39.Source Control
40.SQL Clients
41.Template Engines
42.Testing
43.UML
44.Web Frameworks
45.Web Service
46.Web Testing
47.Wiki Engines
48.Windows Presentation Foundation
49.Workflows
50.XML Parsers
C# / C Sharp
C# / C Sharp by API
C# / CSharp Tutorial
C# / CSharp Open Source » 2.6.4 mono .net core » System.Xml 
System.Xml » System » Xml » Serialization » XmlSchemaImporter.cs
// 
// System.Xml.Serialization.XmlSchemaImporter
//
// Author:
//   Tim Coleman (tim@timcoleman.com)
//   Lluis Sanchez Gual (lluis@ximian.com)
//
// Copyright (C) Tim Coleman, 2002
//

//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
// 
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
// 
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//

using System.Xml;
#if !TARGET_JVM && !MONOTOUCH
using System.CodeDom.Compiler;
#endif
using System.Xml.Schema;
using System.Collections;
#if NET_2_0 && CONFIGURATION_DEP
using System.Configuration;
using System.Xml.Serialization.Configuration;
#endif

namespace System.Xml.Serialization{
  public class XmlSchemaImporter
#if NET_2_0 && !MONOTOUCH
    : SchemaImporter
#endif
  {
    #region Fields

    XmlSchemas schemas;
    CodeIdentifiers typeIdentifiers;
    CodeIdentifiers elemIdentifiers = new CodeIdentifiers ();
    Hashtable mappedTypes = new Hashtable ();
    Hashtable primitiveDerivedMappedTypes = new Hashtable ();
    Hashtable dataMappedTypes = new Hashtable ();
    Queue pendingMaps = new Queue ();
    Hashtable sharedAnonymousTypes = new Hashtable ();
    bool encodedFormat = false;
    XmlReflectionImporter auxXmlRefImporter;
    SoapReflectionImporter auxSoapRefImporter;
    bool anyTypeImported;

#if NET_2_0
    CodeGenerationOptions options;
#endif

    static readonly XmlQualifiedName anyType = new XmlQualifiedName ("anyType",XmlSchema.Namespace);
    static readonly XmlQualifiedName arrayType = new XmlQualifiedName ("Array",XmlSerializer.EncodingNamespace);
    static readonly XmlQualifiedName arrayTypeRefName = new XmlQualifiedName ("arrayType",XmlSerializer.EncodingNamespace);
    
    const string XmlNamespace = "http://www.w3.org/XML/1998/namespace";
    
    XmlSchemaElement anyElement = null;

    class MapFixup
    {
      public XmlTypeMapping Map;
      public XmlSchemaComplexType SchemaType;
      public XmlQualifiedName TypeName;
    }

    #endregion

    #region Constructors

    public XmlSchemaImporter (XmlSchemas schemas)
    {
      this.schemas = schemas;
      typeIdentifiers = new CodeIdentifiers ();

      InitializeExtensions ();
    }

    public XmlSchemaImporter (XmlSchemas schemas, CodeIdentifiers typeIdentifiers)
      : this (schemas)
    {
      this.typeIdentifiers = typeIdentifiers;
    }
    
#if NET_2_0
#if !TARGET_JVM && !MONOTOUCH
    [MonoTODO]
    public XmlSchemaImporter (XmlSchemas schemas, CodeGenerationOptions options, CodeDomProvider codeProvider, ImportContext context)
    {
      this.schemas = schemas;
      this.options = options;
      if (context != null) {
        typeIdentifiers = context.TypeIdentifiers;
        InitSharedData (context);
      }
      else
        typeIdentifiers = new CodeIdentifiers ();

      InitializeExtensions ();
    }
#endif

    public XmlSchemaImporter (XmlSchemas schemas, CodeGenerationOptions options, ImportContext context)
    {
      this.schemas = schemas;
      this.options = options;
      if (context != null) {
        typeIdentifiers = context.TypeIdentifiers;
        InitSharedData (context);
      }
      else
        typeIdentifiers = new CodeIdentifiers ();

      InitializeExtensions ();
    }
    

    public XmlSchemaImporter (XmlSchemas schemas, CodeIdentifiers typeIdentifiers, CodeGenerationOptions options)
    {
      this.typeIdentifiers = typeIdentifiers;
      this.schemas = schemas;
      this.options = options;

      InitializeExtensions ();
    }

    void InitSharedData (ImportContext context)
    {
      if (context.ShareTypes) {
        mappedTypes = context.MappedTypes;
        dataMappedTypes = context.DataMappedTypes;
        sharedAnonymousTypes = context.SharedAnonymousTypes;
      }
    }
#endif
    
    internal bool UseEncodedFormat
    {
      get { return encodedFormat; }
      set { encodedFormat = value; }
    }

    #endregion // Constructors

    #region Methods

    void InitializeExtensions ()
    {
#if NET_2_0 && CONFIGURATION_DEP
      SerializationSectionGroup root = ConfigurationManager.GetSection ("system.xml.serialization") as SerializationSectionGroup;
      if (root == null)
        return;

      foreach (SchemaImporterExtensionElement element in
         root.SchemaImporterExtensions.SchemaImporterExtensions)
        Extensions.Add (element.Name, element.Type);
#endif
    }

    public XmlMembersMapping ImportAnyType (XmlQualifiedName typeName, string elementName)
    {
      if (typeName == XmlQualifiedName.Empty)
      {
        XmlTypeMapMemberAnyElement mapMem = new XmlTypeMapMemberAnyElement ();
        mapMem.Name = typeName.Name;
        mapMem.TypeData = TypeTranslator.GetTypeData(typeof(XmlNode));
        mapMem.ElementInfo.Add (CreateElementInfo (typeName.Namespace, mapMem, typeName.Name, mapMem.TypeData, true, XmlSchemaForm.None));
        
        XmlMemberMapping[] mm = new XmlMemberMapping [1];
        mm[0] = new XmlMemberMapping (typeName.Name, typeName.Namespace, mapMem, encodedFormat);
        return new XmlMembersMapping (mm);
      }
      else
      {
        XmlSchemaComplexType stype = (XmlSchemaComplexType) schemas.Find (typeName, typeof (XmlSchemaComplexType));
        if (stype == null) 
          throw new InvalidOperationException ("Referenced type '" + typeName + "' not found");
        
        if (!CanBeAnyElement (stype))
          throw new InvalidOperationException ("The type '" + typeName + "' is not valid for a collection of any elements");
          
        ClassMap cmap = new ClassMap ();
        CodeIdentifiers classIds = new CodeIdentifiers ();
        bool isMixed = stype.IsMixed;
        ImportSequenceContent (typeName, cmap, ((XmlSchemaSequence) stype.Particle).Items, classIds, false, ref isMixed);
        XmlTypeMapMemberAnyElement mapMem = (XmlTypeMapMemberAnyElement) cmap.AllMembers[0];
        mapMem.Name = typeName.Name;
        
        XmlMemberMapping[] mm = new XmlMemberMapping [1];
        mm[0] = new XmlMemberMapping (typeName.Name, typeName.Namespace, mapMem, encodedFormat);
        return new XmlMembersMapping (mm);
      }
    }

    public XmlTypeMapping ImportDerivedTypeMapping (XmlQualifiedName name, Type baseType)
    {
      return ImportDerivedTypeMapping (name, baseType, true);
    }
    
    public XmlTypeMapping ImportDerivedTypeMapping (XmlQualifiedName name, Type baseType, bool baseTypeCanBeIndirect)
    {
      XmlQualifiedName qname;
      XmlSchemaType stype;
      
      if (encodedFormat)
      {
        qname = name;
        stype = schemas.Find (name, typeof (XmlSchemaComplexType)) as XmlSchemaComplexType;
        if (stype == null) throw new InvalidOperationException ("Schema type '" + name + "' not found or not valid");
      }
      else
      {
        if (!LocateElement (name, out qname, out stype))
          return null;
      }

      XmlTypeMapping map = GetRegisteredTypeMapping (qname, baseType);
      if (map != null)
      {
        // If the type has already been imported, make sure that the map 
        // has the requested base type
        
        SetMapBaseType (map, baseType);
        map.UpdateRoot (name);
        return map;
      }
      
      map = CreateTypeMapping (qname, SchemaTypes.Class, name);
      if (stype != null) {
        map.Documentation = GetDocumentation (stype);
        RegisterMapFixup (map, qname, (XmlSchemaComplexType)stype);
      } else {
        ClassMap cmap = new ClassMap ();
        CodeIdentifiers classIds = new CodeIdentifiers ();
        map.ObjectMap = cmap;
        AddTextMember (qname, cmap, classIds);
      }
      
      BuildPendingMaps ();
      SetMapBaseType (map, baseType);
      
      return map;
    }
    
    void SetMapBaseType (XmlTypeMapping map, Type baseType)
    {
      // This method sets the base type for a given map.
      // If the map already inherits from this type, it does nothing.
      
      // Fiirst of all, check if the map already inherits from baseType
        
      XmlTypeMapping topMap = null;
      while (map != null)
      {
        if (map.TypeData.Type == baseType)
          return;
        topMap = map;
        map = map.BaseMap;
      }
      
      // Does not have the requested base type.
      // Then, get/create a map for that base type.

      XmlTypeMapping baseMap = ReflectType (baseType);
      
      // Add this map as a derived map of the base map

      topMap.BaseMap = baseMap;
      baseMap.DerivedTypes.Add (topMap);
      baseMap.DerivedTypes.AddRange (topMap.DerivedTypes);
      
      // Now add the base type fields to all derived maps

      ClassMap baseClassMap = (ClassMap)baseMap.ObjectMap;
      
      ClassMap cmap = (ClassMap)topMap.ObjectMap;
      foreach (XmlTypeMapMember member in baseClassMap.AllMembers)
        cmap.AddMember (member);
        
      foreach (XmlTypeMapping derivedMap in topMap.DerivedTypes)
      {
        cmap = (ClassMap)derivedMap.ObjectMap;
        foreach (XmlTypeMapMember member in baseClassMap.AllMembers)
          cmap.AddMember (member);
      }
    }

    public XmlMembersMapping ImportMembersMapping (XmlQualifiedName name)
    {
      XmlSchemaElement elem = (XmlSchemaElement) schemas.Find (name, typeof (XmlSchemaElement));
      if (elem == null) throw new InvalidOperationException ("Schema element '" + name + "' not found or not valid");

      XmlSchemaComplexType stype;
      if (elem.SchemaType != null)
      {
        stype = elem.SchemaType as XmlSchemaComplexType;
      }
      else
      {
        if (elem.SchemaTypeName.IsEmpty) return null;
        object type = schemas.Find (elem.SchemaTypeName, typeof (XmlSchemaComplexType));
        if (type == null) {
          if (IsPrimitiveTypeNamespace (elem.SchemaTypeName.Namespace)) return null;
          throw new InvalidOperationException ("Schema type '" + elem.SchemaTypeName + "' not found");
        }
        stype = type as XmlSchemaComplexType;
      }
      
      if (stype == null) 
        throw new InvalidOperationException ("Schema element '" + name + "' not found or not valid");
      
      XmlMemberMapping[] mapping = ImportMembersMappingComposite (stype, name);      
      return new XmlMembersMapping (name.Name, name.Namespace, mapping);
    }
    
    public XmlMembersMapping ImportMembersMapping (XmlQualifiedName[] names)
    {
      XmlMemberMapping[] mapping = new XmlMemberMapping [names.Length];
      for (int n=0; n<names.Length; n++)
      {
        XmlSchemaElement elem = (XmlSchemaElement) schemas.Find (names[n], typeof (XmlSchemaElement));
        if (elem == null) throw new InvalidOperationException ("Schema element '" + names[n] + "' not found");
        
        XmlQualifiedName typeQName = new XmlQualifiedName ("Message", names[n].Namespace);
        XmlTypeMapping tmap;
        TypeData td = GetElementTypeData (typeQName, elem, names[n], out tmap);
        
        mapping[n] = ImportMemberMapping (elem.Name, typeQName.Namespace, elem.IsNillable, td, tmap);
      }
      BuildPendingMaps ();
      return new XmlMembersMapping (mapping);
    }
    
#if NET_2_0
    [MonoTODO]
    public XmlMembersMapping ImportMembersMapping (string name, string ns, SoapSchemaMember[] members)
    {
      throw new NotImplementedException ();
    }
    
    public XmlTypeMapping ImportSchemaType (XmlQualifiedName typeName)
    {
      return ImportSchemaType (typeName, typeof (object));
    }
    
    public XmlTypeMapping ImportSchemaType (XmlQualifiedName typeName, Type baseType)
    {
      return ImportSchemaType (typeName, typeof (object), false);
    }
    
    [MonoTODO ("baseType and baseTypeCanBeIndirect are ignored")]
    public XmlTypeMapping ImportSchemaType (XmlQualifiedName typeName, Type baseType, bool baseTypeCanBeIndirect)
    {
      XmlSchemaType stype =
        (XmlSchemaType) schemas.Find (typeName, typeof (XmlSchemaComplexType)) ??
        (XmlSchemaType) schemas.Find (typeName, typeof (XmlSchemaSimpleType));
      return ImportTypeCommon (typeName, typeName, stype, true);
    }
#endif
    
    internal XmlMembersMapping ImportEncodedMembersMapping (string name, string ns, SoapSchemaMember[] members, bool hasWrapperElement)
    {
      XmlMemberMapping[] mapping = new XmlMemberMapping [members.Length];
      for (int n=0; n<members.Length; n++)
      {
        TypeData td = GetTypeData (members[n].MemberType, null, false); // FIXME: isNullable could be true?
        XmlTypeMapping tmap = GetTypeMapping (td);
        mapping[n] = ImportMemberMapping (members[n].MemberName, members[n].MemberType.Namespace, true, td, tmap);
      }
      BuildPendingMaps ();
      return new XmlMembersMapping (name, ns, hasWrapperElement, false, mapping);
    }
    
    internal XmlMembersMapping ImportEncodedMembersMapping (string name, string ns, SoapSchemaMember member)
    {
      XmlSchemaComplexType stype = schemas.Find (member.MemberType, typeof (XmlSchemaComplexType)) as XmlSchemaComplexType;
      if (stype == null) throw new InvalidOperationException ("Schema type '" + member.MemberType + "' not found or not valid");

      XmlMemberMapping[] mapping = ImportMembersMappingComposite (stype, member.MemberType);      
      return new XmlMembersMapping (name, ns, mapping);
    }
    
    XmlMemberMapping[] ImportMembersMappingComposite (XmlSchemaComplexType stype, XmlQualifiedName refer)
    {
      if (stype.Particle == null) 
        return new XmlMemberMapping [0];

      ClassMap cmap = new ClassMap ();
      
      XmlSchemaSequence seq = stype.Particle as XmlSchemaSequence;
      if (seq == null) throw new InvalidOperationException ("Schema element '" + refer + "' cannot be imported as XmlMembersMapping");

      CodeIdentifiers classIds = new CodeIdentifiers ();
      ImportParticleComplexContent (refer, cmap, seq, classIds, false);
      ImportAttributes (refer, cmap, stype.Attributes, stype.AnyAttribute, classIds);

      BuildPendingMaps ();

      int n = 0;
      XmlMemberMapping[] mapping = new XmlMemberMapping [cmap.AllMembers.Count];
      foreach (XmlTypeMapMember mapMem in cmap.AllMembers)
        mapping[n++] = new XmlMemberMapping (mapMem.Name, refer.Namespace, mapMem, encodedFormat);
        
      return mapping;
    }
    
    XmlMemberMapping ImportMemberMapping (string name, string ns, bool isNullable, TypeData type, XmlTypeMapping emap)
    {
      XmlTypeMapMemberElement mapMem;
      
      if (type.IsListType)
        mapMem = new XmlTypeMapMemberList ();
      else
        mapMem = new XmlTypeMapMemberElement ();
      
      mapMem.Name = name;
      mapMem.TypeData = type;
      mapMem.ElementInfo.Add (CreateElementInfo (ns, mapMem, name, type, isNullable, XmlSchemaForm.None, emap));
      return new XmlMemberMapping (name, ns, mapMem, encodedFormat);
    }
    
    [MonoTODO]
    public XmlMembersMapping ImportMembersMapping (XmlQualifiedName[] names, Type baseType, bool baseTypeCanBeIndirect)
    {
      throw new NotImplementedException ();
    }

    public XmlTypeMapping ImportTypeMapping (XmlQualifiedName name)
    {
      XmlQualifiedName qname;
      XmlSchemaType stype;

      XmlSchemaElement elem = (XmlSchemaElement) schemas.Find (name, typeof (XmlSchemaElement));
      if (!LocateElement (elem, out qname, out stype))
        throw new InvalidOperationException (String.Format ("'{0}' is missing.", name));
      return ImportTypeCommon (name, qname, stype, elem.IsNillable);
    }

    // FIXME: name and qname are confusing. Rename one either
    // (name is in schema itself, qname is for actual processing.
    //  For example simple types have qname as in xsd namespace.)
    private XmlTypeMapping ImportTypeCommon (XmlQualifiedName name, XmlQualifiedName qname, XmlSchemaType stype, bool isNullable)
    {
      if (stype == null) {
        if (qname == anyType) {
          // Importing anyType.
          XmlTypeMapping xmap = GetTypeMapping (TypeTranslator.GetTypeData (typeof (object)));
          // This also means, all complexTypes
          // are imported as well.
          BuildPendingMaps ();
          return xmap;
        } else {
          // Importing a primitive type
          TypeData td = TypeTranslator.GetPrimitiveTypeData (qname.Name);
          return ReflectType (td, name.Namespace);
        }
      }
      
      XmlTypeMapping map = GetRegisteredTypeMapping (qname);
      if (map != null) return map;
      
      if (stype is XmlSchemaSimpleType)
        return ImportClassSimpleType (stype.QualifiedName, (XmlSchemaSimpleType) stype, name);
      
      map = CreateTypeMapping (qname, SchemaTypes.Class, name);
      map.Documentation = GetDocumentation (stype);
      map.IsNullable = isNullable;
      RegisterMapFixup (map, qname, (XmlSchemaComplexType)stype);
      
      BuildPendingMaps ();
      return map;
    }

    bool LocateElement (XmlQualifiedName name, out XmlQualifiedName qname, out XmlSchemaType stype)
    {
      XmlSchemaElement elem = (XmlSchemaElement) schemas.Find (name, typeof (XmlSchemaElement));
      return LocateElement (elem, out qname, out stype);
    }

    bool LocateElement (XmlSchemaElement elem, out XmlQualifiedName qname, out XmlSchemaType stype)
    {
      qname = null;
      stype = null;
      
      if (elem == null) return false;

      // The root element must be an element with complex type

      if (elem.SchemaType != null)
      {
        stype = elem.SchemaType;
        qname = elem.QualifiedName;
      }
      else if (elem.ElementType == XmlSchemaComplexType.AnyType)
      {
        qname = anyType;
        return true;
      }
      else
      {
        if (elem.SchemaTypeName.IsEmpty) return false;
        
        object type = schemas.Find (elem.SchemaTypeName, typeof (XmlSchemaComplexType));
        if (type == null) type = schemas.Find (elem.SchemaTypeName, typeof (XmlSchemaSimpleType));
        if (type == null) {
          if (IsPrimitiveTypeNamespace (elem.SchemaTypeName.Namespace)) {
            qname = elem.SchemaTypeName;
            return true;
          }
          throw new InvalidOperationException ("Schema type '" + elem.SchemaTypeName + "' not found");
        }
        stype = (XmlSchemaType) type;
        qname = stype.QualifiedName;
        
        XmlSchemaType btype = stype.BaseSchemaType as XmlSchemaType;
        if (btype != null && btype.QualifiedName == elem.SchemaTypeName)
          throw new InvalidOperationException ("Cannot import schema for type '" + elem.SchemaTypeName.Name + "' from namespace '" + elem.SchemaTypeName.Namespace + "'. Redefine not supported");
      }

      //if (stype is XmlSchemaSimpleType) return false;
      return true;
    }

    XmlTypeMapping ImportType (XmlQualifiedName name, XmlQualifiedName root, bool throwOnError)
    {
      XmlTypeMapping map = GetRegisteredTypeMapping (name);
      if (map != null) {
        map.UpdateRoot (root);
        return map;
      }

      XmlSchemaType type = (XmlSchemaType) schemas.Find (name, typeof (XmlSchemaComplexType));
      if (type == null) type = (XmlSchemaType) schemas.Find (name, typeof (XmlSchemaSimpleType));
      
      if (type == null) 
      {
        if (throwOnError) {
          if (name.Namespace == XmlSerializer.EncodingNamespace)
            throw new InvalidOperationException ("Referenced type '" + name + "' valid only for encoded SOAP.");
          else
            throw new InvalidOperationException ("Referenced type '" + name + "' not found.");
        } else
          return null;
      }

      return ImportType (name, type, root);
    }

    XmlTypeMapping ImportClass (XmlQualifiedName name)
    {
      XmlTypeMapping map = ImportType (name, null, true);
      if (map.TypeData.SchemaType == SchemaTypes.Class) return map;
      XmlSchemaComplexType stype = schemas.Find (name, typeof (XmlSchemaComplexType)) as XmlSchemaComplexType;
      return CreateClassMap (name, stype, new XmlQualifiedName (map.ElementName, map.Namespace));
    }
    
    XmlTypeMapping ImportType (XmlQualifiedName name, XmlSchemaType stype, XmlQualifiedName root)
    {
      XmlTypeMapping map = GetRegisteredTypeMapping (name);
      if (map != null) {
        XmlSchemaComplexType ct = stype as XmlSchemaComplexType;
        if (map.TypeData.SchemaType != SchemaTypes.Class || ct == null || !CanBeArray (name, ct)) {
          map.UpdateRoot (root);
          return map;
        }
          
        // The map was initially imported as a class, but it turns out that it is an
        // array. It has to be imported now as array.
      }
      
      if (stype is XmlSchemaComplexType)
        return ImportClassComplexType (name, (XmlSchemaComplexType) stype, root);
      else if (stype is XmlSchemaSimpleType)
        return ImportClassSimpleType (name, (XmlSchemaSimpleType) stype, root);

      throw new NotSupportedException ("Schema type not supported: " + stype.GetType ());
    }

    XmlTypeMapping ImportClassComplexType (XmlQualifiedName typeQName, XmlSchemaComplexType stype, XmlQualifiedName root)
    {
      // The need for fixups: If the complex type is an array, then to get the type of the
      // array we need first to get the type of the items of the array.
      // But if one of the item types or its children has a referece to this type array,
      // then we enter in an infinite loop. This does not happen with class types because
      // the class map is registered before parsing the children. We can't do the same
      // with the array type because to register the array map we need the type of the array.

      Type anyType = GetAnyElementType (stype);
      if (anyType != null)
        return GetTypeMapping (TypeTranslator.GetTypeData(anyType));
        
      if (CanBeArray (typeQName, stype))
      {
        TypeData typeData;
        ListMap listMap = BuildArrayMap (typeQName, stype, out typeData);
        if (listMap != null)
        {
          XmlTypeMapping map = CreateArrayTypeMapping (typeQName, typeData);
          map.ObjectMap = listMap;
          return map;
        }

        // After all, it is not an array. Create a class map then.
      }
      else if (CanBeIXmlSerializable (stype))
      {
        return ImportXmlSerializableMapping (typeQName.Namespace);
      }

      // Register the map right now but do not build it,
      // This will avoid loops.

      return CreateClassMap (typeQName, stype, root);
    }
    
    XmlTypeMapping CreateClassMap (XmlQualifiedName typeQName, XmlSchemaComplexType stype, XmlQualifiedName root)
    {
      XmlTypeMapping map = CreateTypeMapping (typeQName, SchemaTypes.Class, root);
      map.Documentation = GetDocumentation (stype);
      RegisterMapFixup (map, typeQName, stype);
      return map;
    }

    void RegisterMapFixup (XmlTypeMapping map, XmlQualifiedName typeQName, XmlSchemaComplexType stype)
    {
      MapFixup fixup = new MapFixup ();
      fixup.Map = map;
      fixup.SchemaType = stype;
      fixup.TypeName = typeQName;
      pendingMaps.Enqueue (fixup);
    }

    void BuildPendingMaps ()
    {
      while (pendingMaps.Count > 0) {
        MapFixup fixup  = (MapFixup) pendingMaps.Dequeue ();
        if (fixup.Map.ObjectMap == null) {
          BuildClassMap (fixup.Map, fixup.TypeName, fixup.SchemaType);
          if (fixup.Map.ObjectMap == null) pendingMaps.Enqueue (fixup);
        }
      }
    }

    void BuildPendingMap (XmlTypeMapping map)
    {
      if (map.ObjectMap != null) return;

      foreach (MapFixup fixup in pendingMaps)
      {
        if (fixup.Map == map) {
          BuildClassMap (fixup.Map, fixup.TypeName, fixup.SchemaType);
          return;
        }
      }
      throw new InvalidOperationException ("Can't complete map of type " + map.XmlType + " : " + map.Namespace);
    }

    void BuildClassMap (XmlTypeMapping map, XmlQualifiedName typeQName, XmlSchemaComplexType stype)
    {
      CodeIdentifiers classIds = new CodeIdentifiers();
      classIds.AddReserved (map.TypeData.TypeName);

      ClassMap cmap = new ClassMap ();
      map.ObjectMap = cmap;
      bool isMixed = stype.IsMixed;

      if (stype.Particle != null)
        ImportParticleComplexContent (typeQName, cmap, stype.Particle, classIds, isMixed);
      else
      {
        if (stype.ContentModel is XmlSchemaSimpleContent) {
          ImportSimpleContent (typeQName, map, (XmlSchemaSimpleContent)stype.ContentModel, classIds, isMixed);
        }
        else if (stype.ContentModel is XmlSchemaComplexContent) {
          ImportComplexContent (typeQName, map, (XmlSchemaComplexContent)stype.ContentModel, classIds, isMixed);
        }
      }

      ImportAttributes (typeQName, cmap, stype.Attributes, stype.AnyAttribute, classIds);
      ImportExtensionTypes (typeQName);

      if (isMixed) AddTextMember (typeQName, cmap, classIds);
      
      AddObjectDerivedMap (map);
    }
    
    void ImportAttributes (XmlQualifiedName typeQName, ClassMap cmap, XmlSchemaObjectCollection atts, XmlSchemaAnyAttribute anyat, CodeIdentifiers classIds)
    {
      atts = CollectAttributeUsesNonOverlap (atts, cmap);

      if (anyat != null)
      {
          XmlTypeMapMemberAnyAttribute member = new XmlTypeMapMemberAnyAttribute ();
        member.Name = classIds.AddUnique ("AnyAttribute", member);
        member.TypeData = TypeTranslator.GetTypeData (typeof(XmlAttribute[]));
        cmap.AddMember (member);
      }
      
      foreach (XmlSchemaObject at in atts)
      {
        if (at is XmlSchemaAttribute)
        {
          string ns;
          XmlSchemaAttribute attr = (XmlSchemaAttribute)at;
          XmlSchemaAttribute refAttr = GetRefAttribute (typeQName, attr, out ns);
          XmlTypeMapMemberAttribute member = new XmlTypeMapMemberAttribute ();
          member.Name = classIds.AddUnique (CodeIdentifier.MakeValid (refAttr.Name), member);
          member.Documentation = GetDocumentation (attr);
          member.AttributeName = refAttr.Name;
          member.Namespace = ns;
          member.Form = refAttr.Form;
          member.TypeData = GetAttributeTypeData (typeQName, attr);
          
          if (refAttr.DefaultValue != null) 
            member.DefaultValue = ImportDefaultValue (member.TypeData, refAttr.DefaultValue);
          else if (member.TypeData.IsValueType)
            member.IsOptionalValueType = (refAttr.ValidatedUse != XmlSchemaUse.Required);
            
          if (member.TypeData.IsComplexType)
            member.MappedType = GetTypeMapping (member.TypeData);
          cmap.AddMember (member);
        }
        else if (at is XmlSchemaAttributeGroupRef)
        {
          XmlSchemaAttributeGroupRef gref = (XmlSchemaAttributeGroupRef)at;
          XmlSchemaAttributeGroup grp = FindRefAttributeGroup (gref.RefName);
          ImportAttributes (typeQName, cmap, grp.Attributes, grp.AnyAttribute, classIds);
        }
      }
    }

    // Attributes might be redefined, so there is an existing attribute for the same name, skip it.
    // FIXME: this is nothing more than just a hack.
    // Basically it should use
    // XmlSchemaComplexType.AttributeUses.
    XmlSchemaObjectCollection CollectAttributeUsesNonOverlap (
      XmlSchemaObjectCollection src, ClassMap map)
    {
      XmlSchemaObjectCollection atts = new XmlSchemaObjectCollection ();
      foreach (XmlSchemaAttribute a in src)
        if (map.GetAttribute (a.QualifiedName.Name, a.QualifiedName.Namespace) == null)
          atts.Add (a);
      return atts;
    }

    ListMap BuildArrayMap (XmlQualifiedName typeQName, XmlSchemaComplexType stype, out TypeData arrayTypeData)
    {
      if (encodedFormat)
      {
        XmlSchemaComplexContent content = stype.ContentModel as XmlSchemaComplexContent;
        XmlSchemaComplexContentRestriction rest = content.Content as XmlSchemaComplexContentRestriction;
        XmlSchemaAttribute arrayTypeAt = FindArrayAttribute (rest.Attributes);
        
        if (arrayTypeAt != null)
        {
          XmlAttribute[] uatts = arrayTypeAt.UnhandledAttributes;
          if (uatts == null || uatts.Length == 0) throw new InvalidOperationException ("arrayType attribute not specified in array declaration: " + typeQName);
          
          XmlAttribute xat = null;
          foreach (XmlAttribute at in uatts)
            if (at.LocalName == "arrayType" && at.NamespaceURI == XmlSerializer.WsdlNamespace)
              { xat = at; break; }
          
          if (xat == null) 
            throw new InvalidOperationException ("arrayType attribute not specified in array declaration: " + typeQName);
  
          string name, ns, dims;
          TypeTranslator.ParseArrayType (xat.Value, out name, out ns, out dims);
          return BuildEncodedArrayMap (name + dims, ns, out arrayTypeData);
        }
        else
        {
          XmlSchemaElement elem = null;
          XmlSchemaSequence seq = rest.Particle as XmlSchemaSequence;
          if (seq != null && seq.Items.Count == 1) 
            elem = seq.Items[0] as XmlSchemaElement;
          else {
            XmlSchemaAll all = rest.Particle as XmlSchemaAll;
            if (all != null && all.Items.Count == 1)
              elem = all.Items[0] as XmlSchemaElement;
          }
          if (elem == null)
            throw new InvalidOperationException ("Unknown array format");
            
          return BuildEncodedArrayMap (elem.SchemaTypeName.Name + "[]", elem.SchemaTypeName.Namespace, out arrayTypeData);
        }
      }
      else
      {
        ClassMap cmap = new ClassMap ();
        CodeIdentifiers classIds = new CodeIdentifiers();
        ImportParticleComplexContent (typeQName, cmap, stype.Particle, classIds, stype.IsMixed);

        XmlTypeMapMemberFlatList list = (cmap.AllMembers.Count == 1) ? cmap.AllMembers[0] as XmlTypeMapMemberFlatList : null;
        if (list != null && list.ChoiceMember == null)
        {
          arrayTypeData = list.TypeData;
          return list.ListMap;
        }
        else
        {
          arrayTypeData = null;
          return null;
        }
      }
    }
    
    ListMap BuildEncodedArrayMap (string type, string ns, out TypeData arrayTypeData)
    {
      ListMap map = new ListMap ();
      
      int i = type.LastIndexOf ("[");
      if (i == -1) throw new InvalidOperationException ("Invalid arrayType value: " + type);
      if (type.IndexOf (",",i) != -1) throw new InvalidOperationException ("Multidimensional arrays are not supported");
      
      string itemType = type.Substring (0,i);
      
      TypeData itemTypeData;
      if (itemType.IndexOf ("[") != -1) 
      {
        ListMap innerListMap = BuildEncodedArrayMap (itemType, ns, out itemTypeData);
        
        int dims = itemType.Split ('[').Length - 1;
        string name = TypeTranslator.GetArrayName (type, dims);
        XmlQualifiedName qname = new XmlQualifiedName (name, ns);
        XmlTypeMapping tmap = CreateArrayTypeMapping (qname, itemTypeData);
        tmap.ObjectMap = innerListMap;
      }
      else
      {
        itemTypeData = GetTypeData (new XmlQualifiedName (itemType, ns), null, false);
      }
      
      arrayTypeData = itemTypeData.ListTypeData;
      
      map.ItemInfo = new XmlTypeMapElementInfoList();
      map.ItemInfo.Add (CreateElementInfo ("", null, "Item", itemTypeData, true, XmlSchemaForm.None));
      return map;
    }
    
    XmlSchemaAttribute FindArrayAttribute (XmlSchemaObjectCollection atts)
    {
      foreach (object ob in atts)
      {
        XmlSchemaAttribute att = ob as XmlSchemaAttribute;
        if (att != null && att.RefName == arrayTypeRefName) return att;
        
        XmlSchemaAttributeGroupRef gref = ob as XmlSchemaAttributeGroupRef;
        if (gref != null)
        {
          XmlSchemaAttributeGroup grp = FindRefAttributeGroup (gref.RefName);
          att = FindArrayAttribute (grp.Attributes);
          if (att != null) return att;
        }
      }
      return null;
    }

    void ImportParticleComplexContent (XmlQualifiedName typeQName, ClassMap cmap, XmlSchemaParticle particle, CodeIdentifiers classIds, bool isMixed)
    {
      ImportParticleContent (typeQName, cmap, particle, classIds, false, ref isMixed);
      if (isMixed) AddTextMember (typeQName, cmap, classIds);
    }
    
    void AddTextMember (XmlQualifiedName typeQName, ClassMap cmap, CodeIdentifiers classIds)
    {
      if (cmap.XmlTextCollector == null)
      {
        XmlTypeMapMemberFlatList member = new XmlTypeMapMemberFlatList ();
        member.Name = classIds.AddUnique ("Text", member);
        member.TypeData = TypeTranslator.GetTypeData (typeof(string[]));
        member.ElementInfo.Add (CreateTextElementInfo (typeQName.Namespace, member, member.TypeData.ListItemTypeData));
        member.IsXmlTextCollector = true;
        member.ListMap = new ListMap ();
        member.ListMap.ItemInfo = member.ElementInfo;
        cmap.AddMember (member);
      }
    }
    
    void ImportParticleContent (XmlQualifiedName typeQName, ClassMap cmap, XmlSchemaParticle particle, CodeIdentifiers classIds, bool multiValue, ref bool isMixed)
    {
      if (particle == null) return;
      
      if (particle is XmlSchemaGroupRef)
        particle = GetRefGroupParticle ((XmlSchemaGroupRef)particle);

      if (particle.MaxOccurs > 1) multiValue = true;
      
      if (particle is XmlSchemaSequence) {
        ImportSequenceContent (typeQName, cmap, ((XmlSchemaSequence)particle).Items, classIds, multiValue, ref isMixed);
      }
      else if (particle is XmlSchemaChoice) {
        if (((XmlSchemaChoice)particle).Items.Count == 1)
          ImportSequenceContent (typeQName, cmap, ((XmlSchemaChoice)particle).Items, classIds, multiValue, ref isMixed);
        else
          ImportChoiceContent (typeQName, cmap, (XmlSchemaChoice)particle, classIds, multiValue);
      }
      else if (particle is XmlSchemaAll) {
        ImportSequenceContent (typeQName, cmap, ((XmlSchemaAll)particle).Items, classIds, multiValue, ref isMixed);
      }
    }

    void ImportSequenceContent (XmlQualifiedName typeQName, ClassMap cmap, XmlSchemaObjectCollection items, CodeIdentifiers classIds, bool multiValue, ref bool isMixed)
    {
      foreach (XmlSchemaObject item in items)
      {
        if (item is XmlSchemaElement)
        {
          string ns;
          XmlSchemaElement elem = (XmlSchemaElement) item;
          XmlTypeMapping emap;
          TypeData typeData = GetElementTypeData (typeQName, elem, null, out emap);
          XmlSchemaElement refElem = GetRefElement (typeQName, elem, out ns);

          if (elem.MaxOccurs == 1 && !multiValue)
          {
            XmlTypeMapMemberElement member = null;
            if (typeData.SchemaType != SchemaTypes.Array)
            {
              member = new XmlTypeMapMemberElement ();
              if (refElem.DefaultValue != null) member.DefaultValue = ImportDefaultValue (typeData, refElem.DefaultValue);
            }
            else if (GetTypeMapping (typeData).IsSimpleType)
            {
              // It is a simple list (space separated list).
              // Since this is not supported, map as a single item value
              member = new XmlTypeMapMemberElement ();
#if NET_2_0
              // In MS.NET those types are mapped to a string
              typeData = TypeTranslator.GetTypeData(typeof(string));
#else
              typeData = typeData.ListItemTypeData;
#endif
            }
            else
              member = new XmlTypeMapMemberList ();

            if (elem.MinOccurs == 0 && typeData.IsValueType)
              member.IsOptionalValueType = true;

            member.Name = classIds.AddUnique(CodeIdentifier.MakeValid(refElem.Name), member);
            member.Documentation = GetDocumentation (elem);
            member.TypeData = typeData;
            member.ElementInfo.Add (CreateElementInfo (ns, member, refElem.Name, typeData, refElem.IsNillable, refElem.Form, emap));
            cmap.AddMember (member);
          }
          else
          {
            XmlTypeMapMemberFlatList member = new XmlTypeMapMemberFlatList ();
            member.ListMap = new ListMap ();
            member.Name = classIds.AddUnique(CodeIdentifier.MakeValid(refElem.Name), member);
            member.Documentation = GetDocumentation (elem);
            member.TypeData = typeData.ListTypeData;
            member.ElementInfo.Add (CreateElementInfo (ns, member, refElem.Name, typeData, refElem.IsNillable, refElem.Form, emap));
            member.ListMap.ItemInfo = member.ElementInfo;
            cmap.AddMember (member);
          }
        }
        else if (item is XmlSchemaAny)
        {
          XmlSchemaAny elem = (XmlSchemaAny) item;
          XmlTypeMapMemberAnyElement member = new XmlTypeMapMemberAnyElement ();
          member.Name = classIds.AddUnique ("Any", member);
          member.Documentation = GetDocumentation (elem);
          
          Type ctype;
          if (elem.MaxOccurs != 1 || multiValue)
            ctype = isMixed ? typeof(XmlNode[]) : typeof(XmlElement[]);
          else
            ctype = isMixed ? typeof(XmlNode) : typeof(XmlElement);

          member.TypeData = TypeTranslator.GetTypeData (ctype);
          XmlTypeMapElementInfo einfo = new XmlTypeMapElementInfo (member, member.TypeData);
          einfo.IsUnnamedAnyElement = true;
          member.ElementInfo.Add (einfo);

          if (isMixed)
          {
            einfo = CreateTextElementInfo (typeQName.Namespace, member, member.TypeData);
            member.ElementInfo.Add (einfo);
            member.IsXmlTextCollector = true;
            isMixed = false;  //Allow only one XmlTextAttribute
          }
          
          cmap.AddMember (member);
        }
        else if (item is XmlSchemaParticle) {
          ImportParticleContent (typeQName, cmap, (XmlSchemaParticle)item, classIds, multiValue, ref isMixed);
        }
      }
    }
    
    object ImportDefaultValue (TypeData typeData, string value)
    {
      if (typeData.SchemaType == SchemaTypes.Enum) {
        XmlTypeMapping map = GetTypeMapping (typeData);
        EnumMap emap = (EnumMap) map.ObjectMap;
        string res = emap.GetEnumName (map.TypeFullName, value);
        if (res == null) throw new InvalidOperationException ("'" + value + "' is not a valid enumeration value");
        return res;
      } else
        return XmlCustomFormatter.FromXmlString (typeData, value);
    }
    
    void ImportChoiceContent (XmlQualifiedName typeQName, ClassMap cmap, XmlSchemaChoice choice, CodeIdentifiers classIds, bool multiValue)
    {
      XmlTypeMapElementInfoList choices = new XmlTypeMapElementInfoList ();
      multiValue = ImportChoices (typeQName, null, choices, choice.Items) || multiValue;
      if (choices.Count == 0) return;

      if (choice.MaxOccurs > 1) multiValue = true;

      XmlTypeMapMemberElement member;
      if (multiValue)
      {
        member = new XmlTypeMapMemberFlatList ();
        member.Name = classIds.AddUnique ("Items", member);
        ListMap listMap = new ListMap ();
        listMap.ItemInfo = choices;
        ((XmlTypeMapMemberFlatList)member).ListMap = listMap;
      }
      else
      {
        member = new XmlTypeMapMemberElement ();
        member.Name = classIds.AddUnique ("Item", member);
      }
      
      // If all choices have the same type, use that type for the member.
      // If not use System.Object.
      // If there are at least two choices with the same type, use a choice
      // identifier attribute

      TypeData typeData = null;
      bool twoEqual = false;
      bool allEqual = true;
      Hashtable types = new Hashtable ();

      for (int n = choices.Count - 1; n >= 0; n--)
      {
        XmlTypeMapElementInfo einfo = (XmlTypeMapElementInfo) choices [n];
        
        // In some complex schemas, we may end up with several options
        // with the same name. It is better to ignore the extra options
        // than to crash. It's the best we can do, and btw it works
        // better than in MS.NET.
        
        if (cmap.GetElement (einfo.ElementName, einfo.Namespace) != null ||
          choices.IndexOfElement (einfo.ElementName, einfo.Namespace) != n)
        {
          choices.RemoveAt (n);
          continue;
        }
          
        if (types.ContainsKey (einfo.TypeData)) twoEqual = true;
        else types.Add (einfo.TypeData, einfo);

        TypeData choiceType = einfo.TypeData;
        if (choiceType.SchemaType == SchemaTypes.Class)
        {
          // When comparing class types, use the most generic class in the
          // inheritance hierarchy

          XmlTypeMapping choiceMap = GetTypeMapping (choiceType);
          BuildPendingMap (choiceMap);
          while (choiceMap.BaseMap != null) {
            choiceMap = choiceMap.BaseMap;
            BuildPendingMap (choiceMap);
            choiceType = choiceMap.TypeData;
          }
        }
        
        if (typeData == null) typeData = choiceType;
        else if (typeData != choiceType) allEqual = false;
      }

      if (!allEqual)
        typeData = TypeTranslator.GetTypeData (typeof(object));

      if (twoEqual)
      {
        // Create the choice member
        XmlTypeMapMemberElement choiceMember = new XmlTypeMapMemberElement ();
        choiceMember.Ignore = true;
        choiceMember.Name = classIds.AddUnique (member.Name + "ElementName", choiceMember);
        member.ChoiceMember = choiceMember.Name;

        // Create the choice enum
        XmlTypeMapping enumMap = CreateTypeMapping (new XmlQualifiedName (member.Name + "ChoiceType", typeQName.Namespace), SchemaTypes.Enum, null);
        enumMap.IncludeInSchema = false;

        CodeIdentifiers codeIdents = new CodeIdentifiers ();
        EnumMap.EnumMapMember[] members = new EnumMap.EnumMapMember [choices.Count];
        for (int n=0; n<choices.Count; n++)
        {
          XmlTypeMapElementInfo it =(XmlTypeMapElementInfo) choices[n];
          bool extraNs = (it.Namespace != null && it.Namespace != "" && it.Namespace != typeQName.Namespace);
          string xmlName = extraNs ? it.Namespace + ":" + it.ElementName : it.ElementName;
          string enumName = codeIdents.AddUnique (CodeIdentifier.MakeValid (it.ElementName), it);
          members [n] = new EnumMap.EnumMapMember (xmlName, enumName);
        }
        enumMap.ObjectMap = new EnumMap (members, false);

        choiceMember.TypeData = multiValue ? enumMap.TypeData.ListTypeData : enumMap.TypeData;
        choiceMember.ElementInfo.Add (CreateElementInfo (typeQName.Namespace, choiceMember, choiceMember.Name, choiceMember.TypeData, false, XmlSchemaForm.None));
        cmap.AddMember (choiceMember);
      }
      
      if (typeData == null)
        return;
  
      if (multiValue)
        typeData = typeData.ListTypeData;

      member.ElementInfo = choices;
      member.Documentation = GetDocumentation (choice);
      member.TypeData = typeData;
      cmap.AddMember (member);
    }

    bool ImportChoices (XmlQualifiedName typeQName, XmlTypeMapMember member, XmlTypeMapElementInfoList choices, XmlSchemaObjectCollection items)
    {
      bool multiValue = false;
      foreach (XmlSchemaObject titem in items)
      {
        XmlSchemaObject item = titem;
        if (item is XmlSchemaGroupRef)
          item = GetRefGroupParticle ((XmlSchemaGroupRef)item);

        if (item is XmlSchemaElement)
        {
          string ns;
          XmlSchemaElement elem = (XmlSchemaElement) item;
          XmlTypeMapping emap;
          TypeData typeData = GetElementTypeData (typeQName, elem, null, out emap);
          XmlSchemaElement refElem = GetRefElement (typeQName, elem, out ns);
          choices.Add (CreateElementInfo (ns, member, refElem.Name, typeData, refElem.IsNillable, refElem.Form, emap));
          if (elem.MaxOccurs > 1) multiValue = true;
        }
        else if (item is XmlSchemaAny)
        {
          XmlTypeMapElementInfo einfo = new XmlTypeMapElementInfo (member, TypeTranslator.GetTypeData(typeof(XmlElement)));
          einfo.IsUnnamedAnyElement = true;
          choices.Add (einfo);
        }
        else if (item is XmlSchemaChoice) {
          multiValue = ImportChoices (typeQName, member, choices, ((XmlSchemaChoice)item).Items) || multiValue;
        }
        else if (item is XmlSchemaSequence) {
          multiValue = ImportChoices (typeQName, member, choices, ((XmlSchemaSequence)item).Items) || multiValue;
        }
      }
      return multiValue;
    }

    void ImportSimpleContent (XmlQualifiedName typeQName, XmlTypeMapping map, XmlSchemaSimpleContent content, CodeIdentifiers classIds, bool isMixed)
    {
      XmlSchemaSimpleContentExtension ext = content.Content as XmlSchemaSimpleContentExtension;
      ClassMap cmap = (ClassMap)map.ObjectMap;
      XmlQualifiedName qname = GetContentBaseType (content.Content);
      TypeData simpleType = null;
      
      if (!IsPrimitiveTypeNamespace (qname.Namespace))
      {
        // Add base map members to this map
  
        XmlTypeMapping baseMap = ImportType (qname, null, true);
        BuildPendingMap (baseMap);
        
        if (baseMap.IsSimpleType) {
          simpleType = baseMap.TypeData;
        } else {
          ClassMap baseClassMap = (ClassMap)baseMap.ObjectMap;
    
          foreach (XmlTypeMapMember member in baseClassMap.AllMembers)
            cmap.AddMember (member);
    
          map.BaseMap = baseMap;
          baseMap.DerivedTypes.Add (map);
        }
      }
      else
        simpleType = FindBuiltInType (qname);
        
      if (simpleType != null) {
        XmlTypeMapMemberElement member = new XmlTypeMapMemberElement ();
        member.Name = classIds.AddUnique("Value", member);
        member.TypeData = simpleType;
        member.ElementInfo.Add (CreateTextElementInfo (typeQName.Namespace, member, member.TypeData));
        member.IsXmlTextCollector = true;
        cmap.AddMember (member);
      }
      
      if (ext != null)
        ImportAttributes (typeQName, cmap, ext.Attributes, ext.AnyAttribute, classIds);
    }

    TypeData FindBuiltInType (XmlQualifiedName qname)
    {
      XmlSchemaComplexType ct = (XmlSchemaComplexType) schemas.Find (qname, typeof(XmlSchemaComplexType));
      if (ct != null)
      {
        XmlSchemaSimpleContent sc = ct.ContentModel as XmlSchemaSimpleContent;
        if (sc == null) throw new InvalidOperationException ("Invalid schema");
        return FindBuiltInType (GetContentBaseType (sc.Content));
      }
      
      XmlSchemaSimpleType st = (XmlSchemaSimpleType) schemas.Find (qname, typeof(XmlSchemaSimpleType));
      if (st != null)
        return FindBuiltInType (qname, st);

      if (IsPrimitiveTypeNamespace (qname.Namespace))
        return TypeTranslator.GetPrimitiveTypeData (qname.Name);

      throw new InvalidOperationException ("Definition of type '" + qname + "' not found");
    }

    TypeData FindBuiltInType (XmlQualifiedName qname, XmlSchemaSimpleType st)
    {
      if (CanBeEnum (st) && qname != null)
        return ImportType (qname, null, true).TypeData;

      if (st.Content is XmlSchemaSimpleTypeRestriction) {
        XmlSchemaSimpleTypeRestriction rest = (XmlSchemaSimpleTypeRestriction) st.Content;
        XmlQualifiedName bn = GetContentBaseType (rest);
        if (bn == XmlQualifiedName.Empty && rest.BaseType != null)
          return FindBuiltInType (qname, rest.BaseType);
        else
          return FindBuiltInType (bn);
      }
      else if (st.Content is XmlSchemaSimpleTypeList) {
        return FindBuiltInType (GetContentBaseType (st.Content)).ListTypeData;
      }
      else if (st.Content is XmlSchemaSimpleTypeUnion) {
        // MS.NET always import simple unions as string
        return FindBuiltInType (new XmlQualifiedName ("string", XmlSchema.Namespace));
      }
      else
        return null;
    }

    XmlQualifiedName GetContentBaseType (XmlSchemaObject ob)
    {
      if (ob is XmlSchemaSimpleContentExtension)
        return ((XmlSchemaSimpleContentExtension)ob).BaseTypeName;
      else if (ob is XmlSchemaSimpleContentRestriction)
        return ((XmlSchemaSimpleContentRestriction)ob).BaseTypeName;
      else if (ob is XmlSchemaSimpleTypeRestriction)
        return ((XmlSchemaSimpleTypeRestriction)ob).BaseTypeName;
      else if (ob is XmlSchemaSimpleTypeList)
        return ((XmlSchemaSimpleTypeList)ob).ItemTypeName;
      else
        return null;
    }

    void ImportComplexContent (XmlQualifiedName typeQName, XmlTypeMapping map, XmlSchemaComplexContent content, CodeIdentifiers classIds, bool isMixed)
    {
      ClassMap cmap = (ClassMap)map.ObjectMap;
      XmlQualifiedName qname;

      XmlSchemaComplexContentExtension ext = content.Content as XmlSchemaComplexContentExtension;
      if (ext != null) qname = ext.BaseTypeName;
      else qname = ((XmlSchemaComplexContentRestriction)content.Content).BaseTypeName;
      
      if (qname == typeQName)
        throw new InvalidOperationException ("Cannot import schema for type '" + typeQName.Name + "' from namespace '" + typeQName.Namespace + "'. Redefine not supported");
      
      // Add base map members to this map

      XmlTypeMapping baseMap = ImportClass (qname);
      BuildPendingMap (baseMap);
      ClassMap baseClassMap = (ClassMap)baseMap.ObjectMap;

      foreach (XmlTypeMapMember member in baseClassMap.AllMembers)
        cmap.AddMember (member);

      if (baseClassMap.XmlTextCollector != null) isMixed = false;
      else if (content.IsMixed) isMixed = true;

      map.BaseMap = baseMap;
      baseMap.DerivedTypes.Add (map);

      if (ext != null) {
        // Add the members of this map
        ImportParticleComplexContent (typeQName, cmap, ext.Particle, classIds, isMixed);
        ImportAttributes (typeQName, cmap, ext.Attributes, ext.AnyAttribute, classIds);
      }
      else {
        if (isMixed) ImportParticleComplexContent (typeQName, cmap, null, classIds, true);
      }
    }
    
    void ImportExtensionTypes (XmlQualifiedName qname)
    {
      foreach (XmlSchema schema in schemas) {
        foreach (XmlSchemaObject sob in schema.Items) 
        {
          XmlSchemaComplexType sct = sob as XmlSchemaComplexType;
          if (sct != null && sct.ContentModel is XmlSchemaComplexContent) {
            XmlQualifiedName exqname;
            XmlSchemaComplexContentExtension ext = sct.ContentModel.Content as XmlSchemaComplexContentExtension;
            if (ext != null) exqname = ext.BaseTypeName;
            else exqname = ((XmlSchemaComplexContentRestriction)sct.ContentModel.Content).BaseTypeName;
            if (exqname == qname)
              ImportType (new XmlQualifiedName (sct.Name, schema.TargetNamespace), sct, null);
          }
        }
      }          
    }

    XmlTypeMapping ImportClassSimpleType (XmlQualifiedName typeQName, XmlSchemaSimpleType stype, XmlQualifiedName root)
    {
      if (CanBeEnum (stype))
      {
        // Create an enum map

        CodeIdentifiers codeIdents = new CodeIdentifiers ();
        XmlTypeMapping enumMap = CreateTypeMapping (typeQName, SchemaTypes.Enum, root);
        enumMap.Documentation = GetDocumentation (stype);
        
        bool isFlags = false;
        if (stype.Content is XmlSchemaSimpleTypeList) {
          stype = ((XmlSchemaSimpleTypeList)stype.Content).ItemType;
          isFlags = true;
        }
        XmlSchemaSimpleTypeRestriction rest = (XmlSchemaSimpleTypeRestriction)stype.Content;

        codeIdents.AddReserved (enumMap.TypeData.TypeName);

        EnumMap.EnumMapMember[] members = new EnumMap.EnumMapMember [rest.Facets.Count];
        for (int n=0; n<rest.Facets.Count; n++)
        {
          XmlSchemaEnumerationFacet enu = (XmlSchemaEnumerationFacet) rest.Facets[n];
          string enumName = codeIdents.AddUnique(CodeIdentifier.MakeValid (enu.Value), enu);
          members [n] = new EnumMap.EnumMapMember (enu.Value, enumName);
          members [n].Documentation = GetDocumentation (enu);
        }
        enumMap.ObjectMap = new EnumMap (members, isFlags);
        enumMap.IsSimpleType = true;
        return enumMap;
      }

      if (stype.Content is XmlSchemaSimpleTypeList)
      {
        XmlSchemaSimpleTypeList slist = (XmlSchemaSimpleTypeList)stype.Content;
        TypeData arrayTypeData = FindBuiltInType (slist.ItemTypeName, stype);

        ListMap listMap = new ListMap ();

        listMap.ItemInfo = new XmlTypeMapElementInfoList ();
        listMap.ItemInfo.Add (CreateElementInfo (typeQName.Namespace, null, "Item", arrayTypeData.ListItemTypeData, false, XmlSchemaForm.None));

        XmlTypeMapping map = CreateArrayTypeMapping (typeQName, arrayTypeData);
        map.ObjectMap = listMap;
        map.IsSimpleType = true;
        return map;
      }

      // It is an extension of a primitive or known type
      
      TypeData typeData = FindBuiltInType (typeQName, stype);
      XmlTypeMapping rmap = GetTypeMapping (typeData);
      
      // The resulting map must be a simple type. It needs to be explicitely set for arrays
      rmap.IsSimpleType = true;
      return rmap;
    }

    bool CanBeEnum (XmlSchemaSimpleType stype)
    {
      if (stype.Content is XmlSchemaSimpleTypeRestriction)
      {
        XmlSchemaSimpleTypeRestriction rest = (XmlSchemaSimpleTypeRestriction)stype.Content;
        if (rest.Facets.Count == 0) return false;
        foreach (object ob in rest.Facets)
          if (!(ob is XmlSchemaEnumerationFacet)) return false;
        return true;
      }
      else if (stype.Content is XmlSchemaSimpleTypeList)
      {
        XmlSchemaSimpleTypeList list = (XmlSchemaSimpleTypeList) stype.Content;
        return (list.ItemType != null && CanBeEnum (list.ItemType));
      }
      return false;
    }

    bool CanBeArray (XmlQualifiedName typeQName, XmlSchemaComplexType stype)
    {
      if (encodedFormat)
      {
        XmlSchemaComplexContent content = stype.ContentModel as XmlSchemaComplexContent;
        if (content == null) return false;
        XmlSchemaComplexContentRestriction rest = content.Content as XmlSchemaComplexContentRestriction;
        if (rest == null) return false;
        return rest.BaseTypeName == arrayType;
      }
      else
      {
        if (stype.Attributes.Count > 0 || stype.AnyAttribute != null) return false;
        else return !stype.IsMixed && CanBeArray (typeQName, stype.Particle, false);
      }
    }

    bool CanBeArray (XmlQualifiedName typeQName, XmlSchemaParticle particle, bool multiValue)
    {
      // To be an array, there can't be a direct child of type typeQName

      if (particle == null) return false;

      multiValue = multiValue || particle.MaxOccurs > 1;

      if (particle is XmlSchemaGroupRef)
        return CanBeArray (typeQName, GetRefGroupParticle ((XmlSchemaGroupRef)particle), multiValue);

      if (particle is XmlSchemaElement)
      {
        XmlSchemaElement elem = (XmlSchemaElement)particle;
        if (!elem.RefName.IsEmpty)
          return CanBeArray (typeQName, FindRefElement (elem), multiValue);
        else
          return multiValue && !typeQName.Equals (((XmlSchemaElement)particle).SchemaTypeName);
      }

      if (particle is XmlSchemaAny)
        return multiValue;

      if (particle is XmlSchemaSequence)
      {
        XmlSchemaSequence seq = particle as XmlSchemaSequence;
        if (seq.Items.Count != 1) return false;
        return CanBeArray (typeQName, (XmlSchemaParticle)seq.Items[0], multiValue);
      }

      if (particle is XmlSchemaChoice)
      {
        // Can be array if all choices have different types
        ArrayList types = new ArrayList ();
        if(!CheckChoiceType (typeQName, particle, types, ref multiValue)) return false;
        return multiValue;
      }

      return false;
    }

    bool CheckChoiceType (XmlQualifiedName typeQName, XmlSchemaParticle particle, ArrayList types, ref bool multiValue)
    {
      XmlQualifiedName type = null;

      multiValue = multiValue || particle.MaxOccurs > 1;

      if (particle is XmlSchemaGroupRef)
        return CheckChoiceType (typeQName, GetRefGroupParticle ((XmlSchemaGroupRef)particle), types, ref multiValue);

      if (particle is XmlSchemaElement) {
        string ns;
        XmlSchemaElement elem = (XmlSchemaElement)particle;
        XmlSchemaElement refElem = GetRefElement (typeQName, elem, out ns);
        if (refElem.SchemaType != null) return true;
        type = refElem.SchemaTypeName;
      }
      else if (particle is XmlSchemaAny) {
        type = anyType;
      }
      else if (particle is XmlSchemaSequence)
      {
        XmlSchemaSequence seq = particle as XmlSchemaSequence;
        foreach (XmlSchemaParticle par in seq.Items)
          if (!CheckChoiceType (typeQName, par, types, ref multiValue)) return false;
        return true;
      }
      else if (particle is XmlSchemaChoice)
      {
        foreach (XmlSchemaParticle choice in ((XmlSchemaChoice)particle).Items)
          if (!CheckChoiceType (typeQName, choice, types, ref multiValue)) return false;
        return true;
      }

      if (typeQName.Equals (type)) return false;

      // For primitive types, compare using CLR types, since several
      // xml types can be mapped to a single CLR type

      string t;
      if (IsPrimitiveTypeNamespace (type.Namespace))
        t = TypeTranslator.GetPrimitiveTypeData (type.Name).FullTypeName + ":" + type.Namespace;

      else
        t = type.Name + ":" + type.Namespace;

      if (types.Contains (t)) return false;
      types.Add (t);
      return true;
    }
    
    bool CanBeAnyElement (XmlSchemaComplexType stype)
    {
      XmlSchemaSequence seq = stype.Particle as XmlSchemaSequence;
      return (seq != null) && (seq.Items.Count == 1) && (seq.Items[0] is XmlSchemaAny);
    }
    
    Type GetAnyElementType (XmlSchemaComplexType stype)
    {
      XmlSchemaSequence seq = stype.Particle as XmlSchemaSequence;
      
      if ((seq == null) || (seq.Items.Count != 1) || !(seq.Items[0] is XmlSchemaAny))
        return null;
      
      if (encodedFormat) 
        return typeof(object);

      XmlSchemaAny any = seq.Items[0] as XmlSchemaAny;
      if (any.MaxOccurs == 1)
      {
        if (stype.IsMixed)
          return typeof(XmlNode);
        else
          return typeof(XmlElement);
      }
      else
      {
        if (stype.IsMixed)
          return typeof(XmlNode[]);
        else
          return typeof(XmlElement[]);
      }
    }

    bool CanBeIXmlSerializable (XmlSchemaComplexType stype)
    {
      XmlSchemaSequence seq = stype.Particle as XmlSchemaSequence;
      if (seq == null) return false;
      if (seq.Items.Count != 2) return false;
      XmlSchemaElement elem = seq.Items[0] as XmlSchemaElement;
      if (elem == null) return false;
      if (elem.RefName != new XmlQualifiedName ("schema",XmlSchema.Namespace)) return false;
      return (seq.Items[1] is XmlSchemaAny);
    }
    
    XmlTypeMapping ImportXmlSerializableMapping (string ns)
    {
      XmlQualifiedName qname = new XmlQualifiedName ("System.Data.DataSet",ns);
      XmlTypeMapping map = GetRegisteredTypeMapping (qname);
      if (map != null) return map;
      
      TypeData typeData = new TypeData ("System.Data.DataSet", "System.Data.DataSet", "System.Data.DataSet", SchemaTypes.XmlSerializable, null);
      map = new XmlTypeMapping ("System.Data.DataSet", "", typeData, "System.Data.DataSet", ns);
      map.IncludeInSchema = true;
      RegisterTypeMapping (qname, typeData, map);
      return map;
    }
    
    XmlTypeMapElementInfo CreateElementInfo (string ns, XmlTypeMapMember member, string name, TypeData typeData, bool isNillable, XmlSchemaForm form)
    {
      if (typeData.IsComplexType)
        return CreateElementInfo (ns, member, name, typeData, isNillable, form, GetTypeMapping (typeData));
      else
        return CreateElementInfo (ns, member, name, typeData, isNillable, form, null);
    }
    
    XmlTypeMapElementInfo CreateElementInfo (string ns, XmlTypeMapMember member, string name, TypeData typeData, bool isNillable, XmlSchemaForm form, XmlTypeMapping emap)
    {
      XmlTypeMapElementInfo einfo = new XmlTypeMapElementInfo (member, typeData);
      einfo.ElementName = name;
      einfo.Namespace = ns;
      einfo.IsNullable = isNillable;
      einfo.Form = form;
      if (typeData.IsComplexType)
        einfo.MappedType = emap;
      return einfo;
    }

    XmlTypeMapElementInfo CreateTextElementInfo (string ns, XmlTypeMapMember member, TypeData typeData)
    {
      XmlTypeMapElementInfo einfo = new XmlTypeMapElementInfo (member, typeData);
      einfo.IsTextElement = true;
      einfo.WrappedElement = false;
      if (typeData.IsComplexType)
        einfo.MappedType = GetTypeMapping (typeData);
      return einfo;
    }

    XmlTypeMapping CreateTypeMapping (XmlQualifiedName typeQName, SchemaTypes schemaType, XmlQualifiedName root)
    {
      string typeName = CodeIdentifier.MakeValid (typeQName.Name);
      typeName = typeIdentifiers.AddUnique (typeName, null);

      TypeData typeData = new TypeData (typeName, typeName, typeName, schemaType, null);

      string rootElem;
      string rootNs;
      if (root != null) {
        rootElem = root.Name;
        rootNs = root.Namespace;
      }
      else {
        rootElem = typeQName.Name;
        rootNs = "";
      }
      
      XmlTypeMapping map = new XmlTypeMapping (rootElem, rootNs, typeData, typeQName.Name, typeQName.Namespace);
      map.IncludeInSchema = true;
      RegisterTypeMapping (typeQName, typeData, map);

      return map;
    }

    XmlTypeMapping CreateArrayTypeMapping (XmlQualifiedName typeQName, TypeData arrayTypeData)
    {
      XmlTypeMapping map;
      if (encodedFormat) map = new XmlTypeMapping ("Array", XmlSerializer.EncodingNamespace, arrayTypeData, "Array", XmlSerializer.EncodingNamespace);
      else map = new XmlTypeMapping (arrayTypeData.XmlType, typeQName.Namespace, arrayTypeData, arrayTypeData.XmlType, typeQName.Namespace);
      
      map.IncludeInSchema = true;
      RegisterTypeMapping (typeQName, arrayTypeData, map);

      return map;
    }

    XmlSchemaElement GetRefElement (XmlQualifiedName typeQName, XmlSchemaElement elem, out string ns)
    {

      if (!elem.RefName.IsEmpty)
      {
        ns = elem.RefName.Namespace;
        return FindRefElement (elem);
      }
      else
      {
        ns = typeQName.Namespace;
        return elem;
      }
    }

    XmlSchemaAttribute GetRefAttribute (XmlQualifiedName typeQName, XmlSchemaAttribute attr, out string ns)
    {
      if (!attr.RefName.IsEmpty)
      {
        ns = attr.RefName.Namespace;
        XmlSchemaAttribute at = FindRefAttribute (attr.RefName);
        if (at == null) throw new InvalidOperationException ("The attribute " + attr.RefName + " is missing");
        return at;
      }
      else
      {
        ns = attr.ParentIsSchema ? typeQName.Namespace : String.Empty;
        return attr;
      }
    }

    TypeData GetElementTypeData (XmlQualifiedName typeQName, XmlSchemaElement elem, XmlQualifiedName root, out XmlTypeMapping map)
    {
      bool sharedAnnType = false;
      map = null;
      
      if (!elem.RefName.IsEmpty) {
        XmlSchemaElement refElem = FindRefElement (elem);
        if (refElem == null) throw new InvalidOperationException ("Global element not found: " + elem.RefName);
        root = elem.RefName;
        elem = refElem;
        sharedAnnType = true;
      }

      TypeData td;
      if (!elem.SchemaTypeName.IsEmpty) {
        td = GetTypeData (elem.SchemaTypeName, root, elem.IsNillable);
        map = GetRegisteredTypeMapping (td);
      }
      else if (elem.SchemaType == null) 
        td = TypeTranslator.GetTypeData (typeof(object));
      else 
        td = GetTypeData (elem.SchemaType, typeQName, elem.Name, sharedAnnType, root);
      
      if (map == null && td.IsComplexType)
        map = GetTypeMapping (td);
        
      return td;
    }

    TypeData GetAttributeTypeData (XmlQualifiedName typeQName, XmlSchemaAttribute attr)
    {
      bool sharedAnnType = false;

      if (!attr.RefName.IsEmpty) {
        XmlSchemaAttribute refAtt = FindRefAttribute (attr.RefName);
        if (refAtt == null) throw new InvalidOperationException ("Global attribute not found: " + attr.RefName);
        attr = refAtt;
        sharedAnnType = true;
      }
      
      if (!attr.SchemaTypeName.IsEmpty) return GetTypeData (attr.SchemaTypeName, null, false);
      if (attr.SchemaType == null) return TypeTranslator.GetTypeData (typeof(string));
      else return GetTypeData (attr.SchemaType, typeQName, attr.Name, sharedAnnType, null);
    }

    TypeData GetTypeData (XmlQualifiedName typeQName, XmlQualifiedName root, bool isNullable)
    {
      if (IsPrimitiveTypeNamespace (typeQName.Namespace)) {
        XmlTypeMapping map = ImportType (typeQName, root, false);
        if (map != null) return map.TypeData;
        else return TypeTranslator.GetPrimitiveTypeData (typeQName.Name, isNullable);
      }
      
      if (encodedFormat && typeQName.Namespace == "")
        return TypeTranslator.GetPrimitiveTypeData (typeQName.Name);

      return ImportType (typeQName, root, true).TypeData;
    }

    TypeData GetTypeData (XmlSchemaType stype, XmlQualifiedName typeQNname, string propertyName, bool sharedAnnType, XmlQualifiedName root)
    {
      string baseName;

      if (sharedAnnType)
      {
        // Anonymous types defined in root elements or attributes can be shared among all elements that
        // reference this root element or attribute
        TypeData std = sharedAnonymousTypes [stype] as TypeData;
        if (std != null) return std;
        baseName = propertyName;
      }
      else
        baseName = typeQNname.Name + typeIdentifiers.MakeRightCase (propertyName);

      baseName = elemIdentifiers.AddUnique (baseName, stype);
      
      XmlQualifiedName newName;
      newName = new XmlQualifiedName (baseName, typeQNname.Namespace);

      XmlTypeMapping map = ImportType (newName, stype, root);
      if (sharedAnnType) sharedAnonymousTypes [stype] = map.TypeData;

      return map.TypeData;
    }

    XmlTypeMapping GetTypeMapping (TypeData typeData)
    {
      if (typeData.Type == typeof(object) && !anyTypeImported)
        ImportAllObjectTypes ();
        
      XmlTypeMapping map = GetRegisteredTypeMapping (typeData);
      if (map != null) return map;
      
      if (typeData.IsListType)
      {
        // Create an array map for the type

        XmlTypeMapping itemMap = GetTypeMapping (typeData.ListItemTypeData);
        
        map = new XmlTypeMapping (typeData.XmlType, itemMap.Namespace, typeData, typeData.XmlType, itemMap.Namespace);
        map.IncludeInSchema = true;

        ListMap listMap = new ListMap ();
        listMap.ItemInfo = new XmlTypeMapElementInfoList();
        listMap.ItemInfo.Add (CreateElementInfo (itemMap.Namespace, null, typeData.ListItemTypeData.XmlType, typeData.ListItemTypeData, false, XmlSchemaForm.None));
        map.ObjectMap = listMap;
        
        RegisterTypeMapping (new XmlQualifiedName(map.ElementName, map.Namespace), typeData, map);
        return map;
      }
      else if (typeData.SchemaType == SchemaTypes.Primitive || typeData.Type == typeof(object) || typeof(XmlNode).IsAssignableFrom(typeData.Type))
      {
        return CreateSystemMap (typeData);
      }
      
      throw new InvalidOperationException ("Map for type " + typeData.TypeName + " not found");
    }
    
    void AddObjectDerivedMap (XmlTypeMapping map)
    {
      TypeData typeData = TypeTranslator.GetTypeData (typeof(object));
      XmlTypeMapping omap = GetRegisteredTypeMapping (typeData);
      if (omap == null)
        omap = CreateSystemMap (typeData);
      omap.DerivedTypes.Add (map);
    }
    
    XmlTypeMapping CreateSystemMap (TypeData typeData)
    {
      XmlTypeMapping map = new XmlTypeMapping (typeData.XmlType, XmlSchema.Namespace, typeData, typeData.XmlType, XmlSchema.Namespace);
      map.IncludeInSchema = false;
      map.ObjectMap = new ClassMap ();
      dataMappedTypes [typeData] = map;
      return map;
    }
    
    void ImportAllObjectTypes ()
    {
      // All complex types are subtypes of anyType, so all of them 
      // must also be imported
      
      anyTypeImported = true;
      foreach (XmlSchema schema in schemas) {
        foreach (XmlSchemaObject sob in schema.Items) 
        {
          XmlSchemaComplexType sct = sob as XmlSchemaComplexType;
          if (sct != null)
            ImportType (new XmlQualifiedName (sct.Name, schema.TargetNamespace), sct, null);
        }
      }          
    }
    
    XmlTypeMapping GetRegisteredTypeMapping (XmlQualifiedName typeQName, Type baseType)
    {
      // Primitive types with a forced base class are stored in a different table.
      // In this way it is possible to have two maps for primitive types: one with
      // the forced base class (returned by ImportDerivedTypeMapping) and one
      // with the regular primitive map.
      
      if (IsPrimitiveTypeNamespace (typeQName.Namespace))
        return (XmlTypeMapping) primitiveDerivedMappedTypes [typeQName];
      else
        return (XmlTypeMapping) mappedTypes [typeQName];
    }
    
    XmlTypeMapping GetRegisteredTypeMapping (XmlQualifiedName typeQName)
    {
      return (XmlTypeMapping) mappedTypes [typeQName];
    }
    
    XmlTypeMapping GetRegisteredTypeMapping (TypeData typeData)
    {
      return (XmlTypeMapping) dataMappedTypes [typeData];
    }
    
    void RegisterTypeMapping (XmlQualifiedName qname, TypeData typeData, XmlTypeMapping map)
    {
      // Primitive types with a forced base class are stored in a different table.
      // In this way it is possible to have two maps for primitive types: one with
      // the forced base class (returned by ImportDerivedTypeMapping) and one
      // with the regular primitive map.
      
      dataMappedTypes [typeData] = map;
      if (IsPrimitiveTypeNamespace (qname.Namespace) && !map.IsSimpleType)
        primitiveDerivedMappedTypes [qname] = map;
      else
        mappedTypes [qname] = map;
    }

    XmlSchemaParticle GetRefGroupParticle (XmlSchemaGroupRef refGroup)
    {
      XmlSchemaGroup grp = (XmlSchemaGroup) schemas.Find (refGroup.RefName, typeof (XmlSchemaGroup));
      return grp.Particle;
    }

    XmlSchemaElement FindRefElement (XmlSchemaElement elem)
    {
      XmlSchemaElement refelem = (XmlSchemaElement) schemas.Find (elem.RefName, typeof(XmlSchemaElement));
      if (refelem != null) return refelem;
      
      if (IsPrimitiveTypeNamespace (elem.RefName.Namespace))
      {
        if (anyElement != null) return anyElement;
        anyElement = new XmlSchemaElement ();
        anyElement.Name = "any";
        anyElement.SchemaTypeName = anyType;
        return anyElement;
      } else
        return null;
    }
    
    XmlSchemaAttribute FindRefAttribute (XmlQualifiedName refName)
    {
      if (refName.Namespace == XmlNamespace)
      {
        XmlSchemaAttribute at = new XmlSchemaAttribute ();
        at.Name = refName.Name;
        at.SchemaTypeName = new XmlQualifiedName ("string",XmlSchema.Namespace);
        return at;
      }
      return (XmlSchemaAttribute) schemas.Find (refName, typeof(XmlSchemaAttribute));
    }
    
    XmlSchemaAttributeGroup FindRefAttributeGroup (XmlQualifiedName refName)
    {
      XmlSchemaAttributeGroup grp = (XmlSchemaAttributeGroup) schemas.Find (refName, typeof(XmlSchemaAttributeGroup));
      foreach (XmlSchemaObject at in grp.Attributes)
      {
        if (at is XmlSchemaAttributeGroupRef && ((XmlSchemaAttributeGroupRef)at).RefName == refName)
          throw new InvalidOperationException ("Cannot import attribute group '" + refName.Name + "' from namespace '" + refName.Namespace + "'. Redefine not supported");
          
      }
      return grp;
    }

    XmlTypeMapping ReflectType (Type type)
    {
      TypeData typeData = TypeTranslator.GetTypeData (type);
      return ReflectType (typeData, (string) null);
    }

    XmlTypeMapping ReflectType (TypeData typeData, string ns)
    {
      if (!encodedFormat)
      {
        if (auxXmlRefImporter == null) auxXmlRefImporter = new XmlReflectionImporter ();
        return auxXmlRefImporter.ImportTypeMapping (typeData, ns);
      }
      else
      {
        if (auxSoapRefImporter == null) auxSoapRefImporter = new SoapReflectionImporter ();
        return auxSoapRefImporter.ImportTypeMapping (typeData, ns);
      }
    }


    string GetDocumentation (XmlSchemaAnnotated elem)
    {
      string res = "";
      XmlSchemaAnnotation anot = elem.Annotation;
      if (anot == null || anot.Items == null) return null;
      
      foreach (object ob in anot.Items)
      {
        XmlSchemaDocumentation doc = ob as XmlSchemaDocumentation;
        if (doc != null && doc.Markup != null && doc.Markup.Length > 0) {
          if (res != string.Empty) res += "\n";
          foreach (XmlNode node in doc.Markup)
            res += node.Value;
        }
      }
      return res;
    }
    
    bool IsPrimitiveTypeNamespace (string ns)
    {
      return (ns == XmlSchema.Namespace) || (encodedFormat && ns == XmlSerializer.EncodingNamespace);
    }

    #endregion // Methods
  }
}
www.java2v.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.