The Labs \ Source Viewer \ SSCLI \ System.Xml.Serialization \ XmlSchemaImporter

  1. //------------------------------------------------------------------------------
  2. // <copyright file="XmlSchemaImporter.cs" company="Microsoft">
  3. //
  4. // Copyright (c) 2006 Microsoft Corporation. All rights reserved.
  5. //
  6. // The use and distribution terms for this software are contained in the file
  7. // named license.txt, which can be found in the root of this distribution.
  8. // By using this software in any fashion, you are agreeing to be bound by the
  9. // terms of this license.
  10. //
  11. // You must not remove this notice, or any other, from this software.
  12. //
  13. // </copyright>
  14. //------------------------------------------------------------------------------
  15. namespace System.Xml.Serialization
  16. {
  17.    
  18.     using System;
  19.     using System.Xml.Schema;
  20.     using System.Collections;
  21.     using System.ComponentModel;
  22.     using System.Reflection;
  23.     using System.Xml.Serialization.Configuration;
  24.     using System.CodeDom;
  25.     using System.CodeDom.Compiler;
  26.     using System.Collections.Specialized;
  27.     using System.Globalization;
  28.     using System.Security.Permissions;
  29.     using System.Xml.Serialization.Advanced;
  30.    
  31.     #if DEBUG
  32.     using System.Diagnostics;
  33.     #endif
  34.    
  35.     /// <include file='doc\XmlSchemaImporter.uex' path='docs/doc[@for="XmlSchemaImporter"]/*' />
  36.     ///<internalonly/>
  37.     /// <devdoc>
  38.     /// <para>[To be supplied.]</para>
  39.     /// </devdoc>
  40.     public class XmlSchemaImporter : SchemaImporter
  41.     {
  42.        
  43.         /// <include file='doc\XmlSchemaImporter.uex' path='docs/doc[@for="XmlSchemaImporter.XmlSchemaImporter"]/*' />
  44.         /// <devdoc>
  45.         /// <para>[To be supplied.]</para>
  46.         /// </devdoc>
  47.         public XmlSchemaImporter(XmlSchemas schemas) : base(schemas, CodeGenerationOptions.GenerateProperties, null, new ImportContext())
  48.         {
  49.         }
  50.        
  51.         /// <include file='doc\XmlSchemaImporter.uex' path='docs/doc[@for="XmlSchemaImporter.XmlSchemaImporter1"]/*' />
  52.         /// <devdoc>
  53.         /// <para>[To be supplied.]</para>
  54.         /// </devdoc>
  55.         public XmlSchemaImporter(XmlSchemas schemas, CodeIdentifiers typeIdentifiers) : base(schemas, CodeGenerationOptions.GenerateProperties, null, new ImportContext(typeIdentifiers, false))
  56.         {
  57.         }
  58.        
  59.         /// <include file='doc\XmlSchemaImporter.uex' path='docs/doc[@for="XmlSchemaImporter.XmlSchemaImporter2"]/*' />
  60.         /// <devdoc>
  61.         /// <para>[To be supplied.]</para>
  62.         /// </devdoc>
  63.         public XmlSchemaImporter(XmlSchemas schemas, CodeIdentifiers typeIdentifiers, CodeGenerationOptions options) : base(schemas, options, null, new ImportContext(typeIdentifiers, false))
  64.         {
  65.         }
  66.        
  67.         /// <include file='doc\XmlSchemaImporter.uex' path='docs/doc[@for="XmlSchemaImporter.XmlSchemaImporter3"]/*' />
  68.         /// <devdoc>
  69.         /// <para>[To be supplied.]</para>
  70.         /// </devdoc>
  71.         public XmlSchemaImporter(XmlSchemas schemas, CodeGenerationOptions options, ImportContext context) : base(schemas, options, null, context)
  72.         {
  73.         }
  74.        
  75.         /// <include file='doc\XmlSchemaImporter.uex' path='docs/doc[@for="XmlSchemaImporter.XmlSchemaImporter4"]/*' />
  76.         /// <devdoc>
  77.         /// <para>[To be supplied.]</para>
  78.         /// </devdoc>
  79.         public XmlSchemaImporter(XmlSchemas schemas, CodeGenerationOptions options, CodeDomProvider codeProvider, ImportContext context) : base(schemas, options, codeProvider, context)
  80.         {
  81.         }
  82.        
  83.         /// <include file='doc\XmlSchemaImporter.uex' path='docs/doc[@for="XmlSchemaImporter.ImportDerivedTypeMapping"]/*' />
  84.         /// <devdoc>
  85.         /// <para>[To be supplied.]</para>
  86.         /// </devdoc>
  87.         public XmlTypeMapping ImportDerivedTypeMapping(XmlQualifiedName name, Type baseType)
  88.         {
  89.             return ImportDerivedTypeMapping(name, baseType, false);
  90.         }
  91.        
  92.         internal bool GenerateOrder {
  93.             get { return (Options & CodeGenerationOptions.GenerateOrder) != 0; }
  94.         }
  95.        
  96.         internal TypeMapping GetDefaultMapping(TypeFlags flags)
  97.         {
  98.             PrimitiveMapping mapping = new PrimitiveMapping();
  99.             mapping.TypeDesc = Scope.GetTypeDesc("string", XmlSchema.Namespace, flags);
  100.             mapping.TypeName = mapping.TypeDesc.DataType.Name;
  101.             mapping.Namespace = XmlSchema.Namespace;
  102.             return mapping;
  103.         }
  104.        
  105.         /// <include file='doc\XmlSchemaImporter.uex' path='docs/doc[@for="XmlSchemaImporter.ImportDerivedTypeMapping1"]/*' />
  106.         /// <devdoc>
  107.         /// <para>[To be supplied.]</para>
  108.         /// </devdoc>
  109.         public XmlTypeMapping ImportDerivedTypeMapping(XmlQualifiedName name, Type baseType, bool baseTypeCanBeIndirect)
  110.         {
  111.             ElementAccessor element = ImportElement(name, typeof(TypeMapping), baseType);
  112.            
  113.             if (element.Mapping is StructMapping) {
  114.                 MakeDerived((StructMapping)element.Mapping, baseType, baseTypeCanBeIndirect);
  115.             }
  116.             else if (baseType != null) {
  117.                 if (element.Mapping is ArrayMapping) {
  118.                     // in the case of the ArrayMapping we can use the top-level StructMapping, because it does not have base base type
  119.                     element.Mapping = ((ArrayMapping)element.Mapping).TopLevelMapping;
  120.                     MakeDerived((StructMapping)element.Mapping, baseType, baseTypeCanBeIndirect);
  121.                 }
  122.                 else {
  123.                     // Element '{0}' from namespace '{1}' is not a complex type and cannot be used as a {2}.
  124.                     throw new InvalidOperationException(Res.GetString(Res.XmlBadBaseElement, name.Name, name.Namespace, baseType.FullName));
  125.                 }
  126.             }
  127.             return new XmlTypeMapping(Scope, element);
  128.         }
  129.        
  130.         /// <include file='doc\XmlSchemaImporter.uex' path='docs/doc[@for="XmlSchemaImporter.ImportSchemaType"]/*' />
  131.         /// <devdoc>
  132.         /// <para>[To be supplied.]</para>
  133.         /// </devdoc>
  134.         public XmlTypeMapping ImportSchemaType(XmlQualifiedName typeName)
  135.         {
  136.             return ImportSchemaType(typeName, null, false);
  137.         }
  138.        
  139.        
  140.         /// <include file='doc\XmlSchemaImporter.uex' path='docs/doc[@for="XmlSchemaImporter.ImportSchemaType1"]/*' />
  141.         /// <devdoc>
  142.         /// <para>[To be supplied.]</para>
  143.         /// </devdoc>
  144.         public XmlTypeMapping ImportSchemaType(XmlQualifiedName typeName, Type baseType)
  145.         {
  146.             return ImportSchemaType(typeName, baseType, false);
  147.         }
  148.        
  149.         /// <include file='doc\XmlSchemaImporter.uex' path='docs/doc[@for="XmlSchemaImporter.ImportSchemaType2"]/*' />
  150.         /// <devdoc>
  151.         /// <para>[To be supplied.]</para>
  152.         /// </devdoc>
  153.         public XmlTypeMapping ImportSchemaType(XmlQualifiedName typeName, Type baseType, bool baseTypeCanBeIndirect)
  154.         {
  155.             TypeMapping typeMapping = ImportType(typeName, typeof(TypeMapping), baseType, TypeFlags.CanBeElementValue, true);
  156.             typeMapping.ReferencedByElement = false;
  157.            
  158.             ElementAccessor accessor = new ElementAccessor();
  159.             accessor.IsTopLevelInSchema = true;
  160.             // false
  161.             accessor.Name = typeName.Name;
  162.             accessor.Namespace = typeName.Namespace;
  163.             accessor.Mapping = typeMapping;
  164.            
  165.             if (typeMapping is SpecialMapping && ((SpecialMapping)typeMapping).NamedAny)
  166.                 accessor.Any = true;
  167.             accessor.IsNullable = typeMapping.TypeDesc.IsNullable;
  168.             accessor.Form = XmlSchemaForm.Qualified;
  169.            
  170.             if (accessor.Mapping is StructMapping) {
  171.                 MakeDerived((StructMapping)accessor.Mapping, baseType, baseTypeCanBeIndirect);
  172.             }
  173.             else if (baseType != null) {
  174.                 if (accessor.Mapping is ArrayMapping) {
  175.                     // in the case of the ArrayMapping we can use the top-level StructMapping, because it does not have base base type
  176.                     accessor.Mapping = ((ArrayMapping)accessor.Mapping).TopLevelMapping;
  177.                     MakeDerived((StructMapping)accessor.Mapping, baseType, baseTypeCanBeIndirect);
  178.                 }
  179.                 else {
  180.                     // Type '{0}' from namespace '{1}' is not a complex type and cannot be used as a {2}.
  181.                     throw new InvalidOperationException(Res.GetString(Res.XmlBadBaseType, typeName.Name, typeName.Namespace, baseType.FullName));
  182.                 }
  183.             }
  184.             return new XmlTypeMapping(Scope, accessor);
  185.         }
  186.        
  187.         /// <include file='doc\XmlSchemaImporter.uex' path='docs/doc[@for="XmlSchemaImporter.ImportTypeMapping"]/*' />
  188.         /// <devdoc>
  189.         /// <para>[To be supplied.]</para>
  190.         /// </devdoc>
  191.         public XmlTypeMapping ImportTypeMapping(XmlQualifiedName name)
  192.         {
  193.             return ImportDerivedTypeMapping(name, null);
  194.         }
  195.        
  196.         /// <include file='doc\XmlSchemaImporter.uex' path='docs/doc[@for="XmlSchemaImporter.ImportMembersMapping"]/*' />
  197.         /// <devdoc>
  198.         /// <para>[To be supplied.]</para>
  199.         /// </devdoc>
  200.         public XmlMembersMapping ImportMembersMapping(XmlQualifiedName name)
  201.         {
  202.             return new XmlMembersMapping(Scope, ImportElement(name, typeof(MembersMapping), null), XmlMappingAccess.Read | XmlMappingAccess.Write);
  203.         }
  204.        
  205.         /// <include file='doc\XmlSchemaImporter.uex' path='docs/doc[@for="XmlSchemaImporter.ImportAnyType"]/*' />
  206.         public XmlMembersMapping ImportAnyType(XmlQualifiedName typeName, string elementName)
  207.         {
  208.             TypeMapping typeMapping = ImportType(typeName, typeof(MembersMapping), null, TypeFlags.CanBeElementValue, true);
  209.             MembersMapping mapping = typeMapping as MembersMapping;
  210.            
  211.             if (mapping == null) {
  212.                 XmlSchemaComplexType type = new XmlSchemaComplexType();
  213.                 XmlSchemaSequence seq = new XmlSchemaSequence();
  214.                 type.Particle = seq;
  215.                 XmlSchemaElement element = new XmlSchemaElement();
  216.                 element.Name = elementName;
  217.                 element.SchemaTypeName = typeName;
  218.                 seq.Items.Add(element);
  219.                 mapping = ImportMembersType(type, typeName.Namespace, elementName);
  220.             }
  221.            
  222.             if (mapping.Members.Length != 1 || !mapping.Members[0].Accessor.Any)
  223.                 return null;
  224.             mapping.Members[0].Name = elementName;
  225.             ElementAccessor accessor = new ElementAccessor();
  226.             accessor.Name = elementName;
  227.             accessor.Namespace = typeName.Namespace;
  228.             accessor.Mapping = mapping;
  229.             accessor.Any = true;
  230.            
  231.             XmlSchemaObject xso = Schemas.SchemaSet.GlobalTypes[typeName];
  232.             if (xso != null) {
  233.                 XmlSchema schema = xso.Parent as XmlSchema;
  234.                 if (schema != null) {
  235.                     accessor.Form = schema.ElementFormDefault == XmlSchemaForm.None ? XmlSchemaForm.Unqualified : schema.ElementFormDefault;
  236.                 }
  237.             }
  238.             XmlMembersMapping members = new XmlMembersMapping(Scope, accessor, XmlMappingAccess.Read | XmlMappingAccess.Write);
  239.             return members;
  240.         }
  241.        
  242.         /// <include file='doc\XmlSchemaImporter.uex' path='docs/doc[@for="XmlSchemaImporter.ImportMembersMapping1"]/*' />
  243.         /// <devdoc>
  244.         /// <para>[To be supplied.]</para>
  245.         /// </devdoc>
  246.         public XmlMembersMapping ImportMembersMapping(XmlQualifiedName[] names)
  247.         {
  248.             return ImportMembersMapping(names, null, false);
  249.         }
  250.        
  251.         /// <include file='doc\XmlSchemaImporter.uex' path='docs/doc[@for="XmlSchemaImporter.ImportMembersMapping2"]/*' />
  252.         /// <devdoc>
  253.         /// <para>[To be supplied.]</para>
  254.         /// </devdoc>
  255.         public XmlMembersMapping ImportMembersMapping(XmlQualifiedName[] names, Type baseType, bool baseTypeCanBeIndirect)
  256.         {
  257.             CodeIdentifiers memberScope = new CodeIdentifiers();
  258.             memberScope.UseCamelCasing = true;
  259.             MemberMapping[] members = new MemberMapping[names.Length];
  260.             for (int i = 0; i < names.Length; i++) {
  261.                 XmlQualifiedName name = names[i];
  262.                 ElementAccessor accessor = ImportElement(name, typeof(TypeMapping), baseType);
  263.                 if (baseType != null && accessor.Mapping is StructMapping)
  264.                     MakeDerived((StructMapping)accessor.Mapping, baseType, baseTypeCanBeIndirect);
  265.                
  266.                 MemberMapping member = new MemberMapping();
  267.                 member.Name = CodeIdentifier.MakeValid(Accessor.UnescapeName(accessor.Name));
  268.                 member.Name = memberScope.AddUnique(member.Name, member);
  269.                 member.TypeDesc = accessor.Mapping.TypeDesc;
  270.                 member.Elements = new ElementAccessor[] {accessor};
  271.                 members[i] = member;
  272.             }
  273.             MembersMapping mapping = new MembersMapping();
  274.             mapping.HasWrapperElement = false;
  275.             mapping.TypeDesc = Scope.GetTypeDesc(typeof(object[]));
  276.             mapping.Members = members;
  277.             ElementAccessor element = new ElementAccessor();
  278.             element.Mapping = mapping;
  279.             return new XmlMembersMapping(Scope, element, XmlMappingAccess.Read | XmlMappingAccess.Write);
  280.         }
  281.        
  282.         public XmlMembersMapping ImportMembersMapping(string name, string ns, SoapSchemaMember[] members)
  283.         {
  284.             XmlSchemaComplexType type = new XmlSchemaComplexType();
  285.             XmlSchemaSequence seq = new XmlSchemaSequence();
  286.             type.Particle = seq;
  287.             foreach (SoapSchemaMember member in members) {
  288.                 XmlSchemaElement element = new XmlSchemaElement();
  289.                 element.Name = member.MemberName;
  290.                 element.SchemaTypeName = member.MemberType;
  291.                 seq.Items.Add(element);
  292.             }
  293.             MembersMapping mapping = ImportMembersType(type, null, name);
  294.            
  295.             ElementAccessor accessor = new ElementAccessor();
  296.             accessor.Name = Accessor.EscapeName(name);
  297.             accessor.Namespace = ns;
  298.             accessor.Mapping = mapping;
  299.             accessor.IsNullable = false;
  300.             accessor.Form = XmlSchemaForm.Qualified;
  301.             return new XmlMembersMapping(Scope, accessor, XmlMappingAccess.Read | XmlMappingAccess.Write);
  302.         }
  303.        
  304.         ElementAccessor ImportElement(XmlQualifiedName name, Type desiredMappingType, Type baseType)
  305.         {
  306.             XmlSchemaElement element = FindElement(name);
  307.             ElementAccessor accessor = (ElementAccessor)ImportedElements[element];
  308.             if (accessor != null)
  309.                 return accessor;
  310.             accessor = ImportElement(element, string.Empty, desiredMappingType, baseType, name.Namespace, true);
  311.             ElementAccessor existing = (ElementAccessor)ImportedElements[element];
  312.             if (existing != null) {
  313.                 return existing;
  314.             }
  315.             ImportedElements.Add(element, accessor);
  316.             return accessor;
  317.         }
  318.        
  319.         ElementAccessor ImportElement(XmlSchemaElement element, string identifier, Type desiredMappingType, Type baseType, string ns, bool topLevelElement)
  320.         {
  321.             if (!element.RefName.IsEmpty) {
  322.                 // we cannot re-use the accessor for the element refs
  323.                 ElementAccessor topAccessor = ImportElement(element.RefName, desiredMappingType, baseType);
  324.                 if (element.IsMultipleOccurrence && topAccessor.Mapping is ArrayMapping) {
  325.                     ElementAccessor refAccessor = topAccessor.Clone();
  326.                     refAccessor.IsTopLevelInSchema = false;
  327.                     refAccessor.Mapping.ReferencedByElement = true;
  328.                     return refAccessor;
  329.                 }
  330.                 return topAccessor;
  331.             }
  332.            
  333.             if (element.Name.Length == 0) {
  334.                 XmlQualifiedName parentType = XmlSchemas.GetParentName(element);
  335.                 throw new InvalidOperationException(Res.GetString(Res.XmlElementHasNoName, parentType.Name, parentType.Namespace));
  336.             }
  337.             string unescapedName = Accessor.UnescapeName(element.Name);
  338.             if (identifier.Length == 0)
  339.                 identifier = CodeIdentifier.MakeValid(unescapedName);
  340.             else
  341.                 identifier += CodeIdentifier.MakePascal(unescapedName);
  342.             TypeMapping mapping = ImportElementType(element, identifier, desiredMappingType, baseType, ns);
  343.             ElementAccessor accessor = new ElementAccessor();
  344.             accessor.IsTopLevelInSchema = element.Parent is XmlSchema;
  345.             accessor.Name = element.Name;
  346.             accessor.Namespace = ns;
  347.             accessor.Mapping = mapping;
  348.             accessor.IsOptional = element.MinOccurs == 0m;
  349.            
  350.             if (element.DefaultValue != null) {
  351.                 accessor.Default = element.DefaultValue;
  352.             }
  353.             else if (element.FixedValue != null) {
  354.                 accessor.Default = element.FixedValue;
  355.                 accessor.IsFixed = true;
  356.             }
  357.            
  358.             if (mapping is SpecialMapping && ((SpecialMapping)mapping).NamedAny)
  359.                 accessor.Any = true;
  360.             accessor.IsNullable = element.IsNillable;
  361.             if (topLevelElement) {
  362.                 accessor.Form = XmlSchemaForm.Qualified;
  363.             }
  364.             else {
  365.                 accessor.Form = ElementForm(ns, element);
  366.             }
  367.             return accessor;
  368.         }
  369.        
  370.         TypeMapping ImportElementType(XmlSchemaElement element, string identifier, Type desiredMappingType, Type baseType, string ns)
  371.         {
  372.             TypeMapping mapping;
  373.             if (!element.SchemaTypeName.IsEmpty) {
  374.                 mapping = ImportType(element.SchemaTypeName, desiredMappingType, baseType, TypeFlags.CanBeElementValue, false);
  375.                 if (!mapping.ReferencedByElement) {
  376.                     object type = FindType(element.SchemaTypeName, TypeFlags.CanBeElementValue);
  377.                     XmlSchemaObject parent = element;
  378.                     while (parent.Parent != null && type != parent) {
  379.                         parent = parent.Parent;
  380.                     }
  381.                     mapping.ReferencedByElement = (type != parent);
  382.                 }
  383.             }
  384.             else if (element.SchemaType != null) {
  385.                 if (element.SchemaType is XmlSchemaComplexType)
  386.                     mapping = ImportType((XmlSchemaComplexType)element.SchemaType, ns, identifier, desiredMappingType, baseType, TypeFlags.CanBeElementValue);
  387.                 else
  388.                     mapping = ImportDataType((XmlSchemaSimpleType)element.SchemaType, ns, identifier, baseType, TypeFlags.CanBeElementValue | TypeFlags.CanBeAttributeValue | TypeFlags.CanBeTextValue, false);
  389.                 mapping.ReferencedByElement = true;
  390.             }
  391.             else if (!element.SubstitutionGroup.IsEmpty)
  392.                 mapping = ImportElementType(FindElement(element.SubstitutionGroup), identifier, desiredMappingType, baseType, ns);
  393.             else {
  394.                 if (desiredMappingType == typeof(MembersMapping)) {
  395.                     mapping = ImportMembersType(new XmlSchemaType(), ns, identifier);
  396.                 }
  397.                 else {
  398.                     mapping = ImportRootMapping();
  399.                 }
  400.             }
  401.             if (!(desiredMappingType.IsAssignableFrom(mapping.GetType())))
  402.                 throw new InvalidOperationException(Res.GetString(Res.XmlElementImportedTwice, element.Name, ns, mapping.GetType().Name, desiredMappingType.Name));
  403.            
  404.             // let the extensions to run
  405.             if (!mapping.TypeDesc.IsMappedType) {
  406.                 RunSchemaExtensions(mapping, element.SchemaTypeName, element.SchemaType, element, TypeFlags.CanBeElementValue);
  407.             }
  408.             return mapping;
  409.         }
  410.        
  411.         void RunSchemaExtensions(TypeMapping mapping, XmlQualifiedName qname, XmlSchemaType type, XmlSchemaObject context, TypeFlags flags)
  412.         {
  413.             string typeName = null;
  414.             SchemaImporterExtension typeOwner = null;
  415.             CodeCompileUnit compileUnit = new CodeCompileUnit();
  416.             CodeNamespace mainNamespace = new CodeNamespace();
  417.             compileUnit.Namespaces.Add(mainNamespace);
  418.            
  419.             if (!qname.IsEmpty) {
  420.                 typeName = FindExtendedType(qname.Name, qname.Namespace, context, compileUnit, mainNamespace, out typeOwner);
  421.             }
  422.             else if (type != null) {
  423.                 typeName = FindExtendedType(type, context, compileUnit, mainNamespace, out typeOwner);
  424.             }
  425.             else if (context is XmlSchemaAny) {
  426.                 typeName = FindExtendedAnyElement((XmlSchemaAny)context, ((flags & TypeFlags.CanBeTextValue) != 0), compileUnit, mainNamespace, out typeOwner);
  427.             }
  428.            
  429.             if (typeName != null && typeName.Length > 0) {
  430.                 // check if the type name is valid
  431.                 typeName = typeName.Replace('+', '.');
  432.                 try {
  433.                     CodeGenerator.ValidateIdentifiers(new CodeTypeReference(typeName));
  434.                 }
  435.                 catch (ArgumentException) {
  436.                     if (qname.IsEmpty) {
  437.                         throw new InvalidOperationException(Res.GetString(Res.XmlImporterExtensionBadLocalTypeName, typeOwner.GetType().FullName, typeName));
  438.                     }
  439.                     else {
  440.                         throw new InvalidOperationException(Res.GetString(Res.XmlImporterExtensionBadTypeName, typeOwner.GetType().FullName, qname.Name, qname.Namespace, typeName));
  441.                     }
  442.                 }
  443.                 foreach (CodeNamespace ns in compileUnit.Namespaces) {
  444.                     CodeGenerator.ValidateIdentifiers(ns);
  445.                 }
  446.                 mapping.TypeDesc = mapping.TypeDesc.CreateMappedTypeDesc(new MappedTypeDesc(typeName, qname.Name, qname.Namespace, type, context, typeOwner, mainNamespace, compileUnit.ReferencedAssemblies));
  447.                
  448.                 if (mapping is ArrayMapping) {
  449.                     TypeMapping top = ((ArrayMapping)mapping).TopLevelMapping;
  450.                     top.TypeName = mapping.TypeName;
  451.                     top.TypeDesc = mapping.TypeDesc;
  452.                 }
  453.                 else {
  454.                     mapping.TypeName = qname.IsEmpty ? null : typeName;
  455.                 }
  456.             }
  457.         }
  458.         string GenerateUniqueTypeName(string desiredName, string ns)
  459.         {
  460.             int i = 1;
  461.            
  462.             string typeName = desiredName;
  463.             while (true) {
  464.                 XmlQualifiedName qname = new XmlQualifiedName(typeName, ns);
  465.                
  466.                 object type = Schemas.Find(qname, typeof(XmlSchemaType));
  467.                 if (type == null) {
  468.                     break;
  469.                 }
  470.                 typeName = desiredName + i.ToString(CultureInfo.InvariantCulture);
  471.                 i++;
  472.             }
  473.             typeName = CodeIdentifier.MakeValid(typeName);
  474.             return TypeIdentifiers.AddUnique(typeName, typeName);
  475.         }
  476.        
  477.         [PermissionSet(SecurityAction.InheritanceDemand, Name = "FullTrust")]
  478.         internal override void ImportDerivedTypes(XmlQualifiedName baseName)
  479.         {
  480.             foreach (XmlSchema schema in Schemas) {
  481.                 if (Schemas.IsReference(schema))
  482.                     continue;
  483.                 if (XmlSchemas.IsDataSet(schema))
  484.                     continue;
  485.                 XmlSchemas.Preprocess(schema);
  486.                 foreach (object item in schema.SchemaTypes.Values) {
  487.                     if (item is XmlSchemaType) {
  488.                         XmlSchemaType type = (XmlSchemaType)item;
  489.                         if (type.DerivedFrom == baseName && TypesInUse[type.Name, schema.TargetNamespace] == null) {
  490.                             ImportType(type.QualifiedName, typeof(TypeMapping), null, TypeFlags.CanBeElementValue, false);
  491.                         }
  492.                     }
  493.                 }
  494.             }
  495.         }
  496.        
  497.         TypeMapping ImportType(XmlQualifiedName name, Type desiredMappingType, Type baseType, TypeFlags flags, bool addref)
  498.         {
  499.             if (name.Name == Soap.UrType && name.Namespace == XmlSchema.Namespace)
  500.                 return ImportRootMapping();
  501.             object type = FindType(name, flags);
  502.            
  503.             TypeMapping mapping = (TypeMapping)ImportedMappings[type];
  504.             if (mapping != null && desiredMappingType.IsAssignableFrom(mapping.GetType()))
  505.                 return mapping;
  506.            
  507.             if (addref)
  508.                 AddReference(name, TypesInUse, Res.XmlCircularTypeReference);
  509.             if (type is XmlSchemaComplexType) {
  510.                 mapping = ImportType((XmlSchemaComplexType)type, name.Namespace, name.Name, desiredMappingType, baseType, flags);
  511.             }
  512.             else if (type is XmlSchemaSimpleType)
  513.                 mapping = ImportDataType((XmlSchemaSimpleType)type, name.Namespace, name.Name, baseType, flags, false);
  514.             else
  515.                 throw new InvalidOperationException(Res.GetString(Res.XmlInternalError));
  516.            
  517.             if (addref && name.Namespace != XmlSchema.Namespace)
  518.                 RemoveReference(name, TypesInUse);
  519.            
  520.             return mapping;
  521.         }
  522.        
  523.         TypeMapping ImportType(XmlSchemaComplexType type, string typeNs, string identifier, Type desiredMappingType, Type baseType, TypeFlags flags)
  524.         {
  525.             if (type.Redefined != null) {
  526.                 // we do not support redefine in the current version
  527.                 throw new NotSupportedException(Res.GetString(Res.XmlUnsupportedRedefine, type.Name, typeNs));
  528.             }
  529.             if (desiredMappingType == typeof(TypeMapping)) {
  530.                 TypeMapping mapping = null;
  531.                
  532.                 if (baseType == null) {
  533.                     if ((mapping = ImportArrayMapping(type, identifier, typeNs, false)) == null) {
  534.                         mapping = ImportAnyMapping(type, identifier, typeNs, false);
  535.                     }
  536.                 }
  537.                 if (mapping == null) {
  538.                     mapping = ImportStructType(type, typeNs, identifier, baseType, false);
  539.                    
  540.                     if (mapping != null && type.Name != null && type.Name.Length != 0)
  541.                         ImportDerivedTypes(new XmlQualifiedName(identifier, typeNs));
  542.                 }
  543.                 return mapping;
  544.             }
  545.             else if (desiredMappingType == typeof(MembersMapping))
  546.                 return ImportMembersType(type, typeNs, identifier);
  547.             else
  548.                 throw new ArgumentException(Res.GetString(Res.XmlInternalError), "desiredMappingType");
  549.         }
  550.        
  551.         MembersMapping ImportMembersType(XmlSchemaType type, string typeNs, string identifier)
  552.         {
  553.             if (!type.DerivedFrom.IsEmpty)
  554.                 throw new InvalidOperationException(Res.GetString(Res.XmlMembersDeriveError));
  555.             CodeIdentifiers memberScope = new CodeIdentifiers();
  556.             memberScope.UseCamelCasing = true;
  557.             bool needExplicitOrder = false;
  558.             MemberMapping[] members = ImportTypeMembers(type, typeNs, identifier, memberScope, new CodeIdentifiers(), new NameTable(), ref needExplicitOrder, false, false);
  559.             MembersMapping mappings = new MembersMapping();
  560.             mappings.HasWrapperElement = true;
  561.             mappings.TypeDesc = Scope.GetTypeDesc(typeof(object[]));
  562.             mappings.Members = members;
  563.             return mappings;
  564.         }
  565.        
  566.         StructMapping ImportStructType(XmlSchemaType type, string typeNs, string identifier, Type baseType, bool arrayLike)
  567.         {
  568.             TypeDesc baseTypeDesc = null;
  569.             Mapping baseMapping = null;
  570.            
  571.             bool isRootType = false;
  572.             if (!type.DerivedFrom.IsEmpty) {
  573.                 baseMapping = ImportType(type.DerivedFrom, typeof(TypeMapping), null, TypeFlags.CanBeElementValue | TypeFlags.CanBeTextValue, false);
  574.                
  575.                 if (baseMapping is StructMapping)
  576.                     baseTypeDesc = ((StructMapping)baseMapping).TypeDesc;
  577.                 else if (baseMapping is ArrayMapping) {
  578.                     baseMapping = ((ArrayMapping)baseMapping).TopLevelMapping;
  579.                     if (baseMapping != null) {
  580.                         ((StructMapping)baseMapping).ReferencedByTopLevelElement = false;
  581.                         baseTypeDesc = ((StructMapping)baseMapping).TypeDesc;
  582.                     }
  583.                 }
  584.                 else
  585.                     baseMapping = null;
  586.             }
  587.             if (baseTypeDesc == null && baseType != null)
  588.                 baseTypeDesc = Scope.GetTypeDesc(baseType);
  589.             if (baseMapping == null) {
  590.                 baseMapping = GetRootMapping();
  591.                 isRootType = true;
  592.             }
  593.             Mapping previousMapping = (Mapping)ImportedMappings[type];
  594.             if (previousMapping != null) {
  595.                 if (previousMapping is StructMapping) {
  596.                     return (StructMapping)previousMapping;
  597.                 }
  598.                 else if (arrayLike && previousMapping is ArrayMapping) {
  599.                     ArrayMapping arrayMapping = (ArrayMapping)previousMapping;
  600.                     if (arrayMapping.TopLevelMapping != null) {
  601.                         return arrayMapping.TopLevelMapping;
  602.                     }
  603.                 }
  604.                 else {
  605.                     throw new InvalidOperationException(Res.GetString(Res.XmlTypeUsedTwice, type.QualifiedName.Name, type.QualifiedName.Namespace));
  606.                 }
  607.             }
  608.             StructMapping structMapping = new StructMapping();
  609.             structMapping.IsReference = Schemas.IsReference(type);
  610.             TypeFlags flags = TypeFlags.Reference;
  611.             if (type is XmlSchemaComplexType) {
  612.                 if (((XmlSchemaComplexType)type).IsAbstract)
  613.                     flags |= TypeFlags.Abstract;
  614.             }
  615.            
  616.             identifier = Accessor.UnescapeName(identifier);
  617.             string typeName = type.Name == null || type.Name.Length == 0 ? GenerateUniqueTypeName(identifier, typeNs) : GenerateUniqueTypeName(identifier);
  618.             structMapping.TypeDesc = new TypeDesc(typeName, typeName, TypeKind.Struct, baseTypeDesc, flags);
  619.             structMapping.Namespace = typeNs;
  620.             structMapping.TypeName = type.Name == null || type.Name.Length == 0 ? null : identifier;
  621.             structMapping.BaseMapping = (StructMapping)baseMapping;
  622.             if (!arrayLike)
  623.                 ImportedMappings.Add(type, structMapping);
  624.             CodeIdentifiers members = new CodeIdentifiers();
  625.             CodeIdentifiers membersScope = structMapping.BaseMapping.Scope.Clone();
  626.             members.AddReserved(typeName);
  627.             membersScope.AddReserved(typeName);
  628.             AddReservedIdentifiersForDataBinding(members);
  629.             if (isRootType)
  630.                 AddReservedIdentifiersForDataBinding(membersScope);
  631.             bool needExplicitOrder = false;
  632.             structMapping.Members = ImportTypeMembers(type, typeNs, identifier, members, membersScope, structMapping, ref needExplicitOrder, true, true);
  633.            
  634.             for (int i = 0; i < structMapping.Members.Length; i++) {
  635.                 StructMapping declaringMapping;
  636.                 MemberMapping baseMember = ((StructMapping)baseMapping).FindDeclaringMapping(structMapping.Members[i], out declaringMapping, structMapping.TypeName);
  637.                 if (baseMember != null && baseMember.TypeDesc != structMapping.Members[i].TypeDesc)
  638.                     throw new InvalidOperationException(Res.GetString(Res.XmlIllegalOverride, type.Name, baseMember.Name, baseMember.TypeDesc.FullName, structMapping.Members[i].TypeDesc.FullName, declaringMapping.TypeDesc.FullName));
  639.             }
  640.             if (needExplicitOrder && !GenerateOrder) {
  641.                 structMapping.SetSequence();
  642.             }
  643.             structMapping.Scope = membersScope;
  644.             Scope.AddTypeMapping(structMapping);
  645.             return structMapping;
  646.         }
  647.        
  648.         StructMapping ImportStructDataType(XmlSchemaSimpleType dataType, string typeNs, string identifier, Type baseType)
  649.         {
  650.             identifier = Accessor.UnescapeName(identifier);
  651.             string typeName = GenerateUniqueTypeName(identifier);
  652.             StructMapping structMapping = new StructMapping();
  653.             structMapping.IsReference = Schemas.IsReference(dataType);
  654.             TypeFlags flags = TypeFlags.Reference;
  655.             TypeDesc baseTypeDesc = Scope.GetTypeDesc(baseType);
  656.             structMapping.TypeDesc = new TypeDesc(typeName, typeName, TypeKind.Struct, baseTypeDesc, flags);
  657.             structMapping.Namespace = typeNs;
  658.             structMapping.TypeName = identifier;
  659.             CodeIdentifiers members = new CodeIdentifiers();
  660.             members.AddReserved(typeName);
  661.             AddReservedIdentifiersForDataBinding(members);
  662.             ImportTextMember(members, new CodeIdentifiers(), null);
  663.             structMapping.Members = (MemberMapping[])members.ToArray(typeof(MemberMapping));
  664.             structMapping.Scope = members;
  665.             Scope.AddTypeMapping(structMapping);
  666.             return structMapping;
  667.         }
  668.        
  669.         class TypeItems
  670.         {
  671.             internal XmlSchemaObjectCollection Attributes = new XmlSchemaObjectCollection();
  672.             internal XmlSchemaAnyAttribute AnyAttribute;
  673.             internal XmlSchemaGroupBase Particle;
  674.             internal XmlQualifiedName baseSimpleType;
  675.             internal bool IsUnbounded;
  676.         }
  677.        
  678.         MemberMapping[] ImportTypeMembers(XmlSchemaType type, string typeNs, string identifier, CodeIdentifiers members, CodeIdentifiers membersScope, INameScope elementsScope, ref bool needExplicitOrder, bool order, bool allowUnboundedElements)
  679.         {
  680.             TypeItems items = GetTypeItems(type);
  681.             bool mixed = IsMixed(type);
  682.            
  683.             if (mixed) {
  684.                 // check if we can transfer the attribute to the base class
  685.                 XmlSchemaType t = type;
  686.                 while (!t.DerivedFrom.IsEmpty) {
  687.                     t = FindType(t.DerivedFrom, TypeFlags.CanBeElementValue | TypeFlags.CanBeTextValue);
  688.                     if (IsMixed(t)) {
  689.                         // keep the mixed attribute on the base class
  690.                         mixed = false;
  691.                         break;
  692.                     }
  693.                 }
  694.             }
  695.            
  696.             if (items.Particle != null) {
  697.                 ImportGroup(items.Particle, identifier, members, membersScope, elementsScope, typeNs, mixed, ref needExplicitOrder, order, items.IsUnbounded,
  698.                 allowUnboundedElements);
  699.             }
  700.             for (int i = 0; i < items.Attributes.Count; i++) {
  701.                 object item = items.Attributes[i];
  702.                 if (item is XmlSchemaAttribute) {
  703.                     ImportAttributeMember((XmlSchemaAttribute)item, identifier, members, membersScope, typeNs);
  704.                 }
  705.                 else if (item is XmlSchemaAttributeGroupRef) {
  706.                     XmlQualifiedName groupName = ((XmlSchemaAttributeGroupRef)item).RefName;
  707.                     ImportAttributeGroupMembers(FindAttributeGroup(groupName), identifier, members, membersScope, groupName.Namespace);
  708.                 }
  709.             }
  710.             if (items.AnyAttribute != null) {
  711.                 ImportAnyAttributeMember(items.AnyAttribute, members, membersScope);
  712.             }
  713.            
  714.             if (items.baseSimpleType != null || (items.Particle == null && mixed)) {
  715.                 ImportTextMember(members, membersScope, mixed ? null : items.baseSimpleType);
  716.             }
  717.            
  718.             ImportXmlnsDeclarationsMember(type, members, membersScope);
  719.             MemberMapping[] typeMembers = (MemberMapping[])members.ToArray(typeof(MemberMapping));
  720.            
  721.             if (order && (GenerateOrder || needExplicitOrder)) {
  722.                 for (int i = 0; i < typeMembers.Length; i++) {
  723.                     typeMembers[i].SequenceId = i;
  724.                 }
  725.             }
  726.             return typeMembers;
  727.         }
  728.        
  729.         static internal bool IsMixed(XmlSchemaType type)
  730.         {
  731.             if (!(type is XmlSchemaComplexType))
  732.                 return false;
  733.            
  734.             XmlSchemaComplexType ct = (XmlSchemaComplexType)type;
  735.             bool mixed = ct.IsMixed;
  736.            
  737.             // check the mixed attribute on the complexContent
  738.             if (!mixed) {
  739.                 if (ct.ContentModel != null && ct.ContentModel is XmlSchemaComplexContent) {
  740.                     mixed = ((XmlSchemaComplexContent)ct.ContentModel).IsMixed;
  741.                 }
  742.             }
  743.             return mixed;
  744.         }
  745.        
  746.         TypeItems GetTypeItems(XmlSchemaType type)
  747.         {
  748.             TypeItems items = new TypeItems();
  749.             if (type is XmlSchemaComplexType) {
  750.                 XmlSchemaParticle particle = null;
  751.                 XmlSchemaComplexType ct = (XmlSchemaComplexType)type;
  752.                 if (ct.ContentModel != null) {
  753.                     XmlSchemaContent content = ct.ContentModel.Content;
  754.                     if (content is XmlSchemaComplexContentExtension) {
  755.                         XmlSchemaComplexContentExtension extension = (XmlSchemaComplexContentExtension)content;
  756.                         items.Attributes = extension.Attributes;
  757.                         items.AnyAttribute = extension.AnyAttribute;
  758.                         particle = extension.Particle;
  759.                     }
  760.                     else if (content is XmlSchemaSimpleContentExtension) {
  761.                         XmlSchemaSimpleContentExtension extension = (XmlSchemaSimpleContentExtension)content;
  762.                         items.Attributes = extension.Attributes;
  763.                         items.AnyAttribute = extension.AnyAttribute;
  764.                         items.baseSimpleType = extension.BaseTypeName;
  765.                     }
  766.                 }
  767.                 else {
  768.                     items.Attributes = ct.Attributes;
  769.                     items.AnyAttribute = ct.AnyAttribute;
  770.                     particle = ct.Particle;
  771.                 }
  772.                 if (particle is XmlSchemaGroupRef) {
  773.                     XmlSchemaGroupRef refGroup = (XmlSchemaGroupRef)particle;
  774.                     items.Particle = FindGroup(refGroup.RefName).Particle;
  775.                     items.IsUnbounded = particle.IsMultipleOccurrence;
  776.                 }
  777.                 else if (particle is XmlSchemaGroupBase) {
  778.                     items.Particle = (XmlSchemaGroupBase)particle;
  779.                     items.IsUnbounded = particle.IsMultipleOccurrence;
  780.                 }
  781.             }
  782.             return items;
  783.         }
  784.        
  785.         void ImportGroup(XmlSchemaGroupBase group, string identifier, CodeIdentifiers members, CodeIdentifiers membersScope, INameScope elementsScope, string ns, bool mixed, ref bool needExplicitOrder, bool allowDuplicates, bool groupRepeats,
  786.         bool allowUnboundedElements)
  787.         {
  788.             if (group is XmlSchemaChoice)
  789.                 ImportChoiceGroup((XmlSchemaChoice)group, identifier, members, membersScope, elementsScope, ns, groupRepeats, ref needExplicitOrder, allowDuplicates);
  790.             else
  791.                 ImportGroupMembers(group, identifier, members, membersScope, elementsScope, ns, groupRepeats, ref mixed, ref needExplicitOrder, allowDuplicates,
  792.                 allowUnboundedElements);
  793.            
  794.             if (mixed) {
  795.                 ImportTextMember(members, membersScope, null);
  796.             }
  797.         }
  798.        
  799.         MemberMapping ImportChoiceGroup(XmlSchemaGroupBase group, string identifier, CodeIdentifiers members, CodeIdentifiers membersScope, INameScope elementsScope, string ns, bool groupRepeats, ref bool needExplicitOrder, bool allowDuplicates)
  800.         {
  801.             NameTable choiceElements = new NameTable();
  802.             if (GatherGroupChoices(group, choiceElements, identifier, ns, ref needExplicitOrder, allowDuplicates))
  803.                 groupRepeats = true;
  804.             MemberMapping member = new MemberMapping();
  805.             member.Elements = (ElementAccessor[])choiceElements.ToArray(typeof(ElementAccessor));
  806.             Array.Sort(member.Elements, new ElementComparer());
  807.            
  808.             AddScopeElements(elementsScope, member.Elements, ref needExplicitOrder, allowDuplicates);
  809.             bool duplicateTypes = false;
  810.             bool nullableMismatch = false;
  811.             Hashtable uniqueTypeDescs = new Hashtable(member.Elements.Length);
  812.            
  813.             for (int i = 0; i < member.Elements.Length; i++) {
  814.                 ElementAccessor element = member.Elements[i];
  815.                 string tdFullName = element.Mapping.TypeDesc.FullName;
  816.                 object val = uniqueTypeDescs[tdFullName];
  817.                 if (val != null) {
  818.                     duplicateTypes = true;
  819.                     ElementAccessor existingElement = (ElementAccessor)val;
  820.                     if (!nullableMismatch && existingElement.IsNullable != element.IsNullable)
  821.                         nullableMismatch = true;
  822.                 }
  823.                 else {
  824.                     uniqueTypeDescs.Add(tdFullName, element);
  825.                 }
  826.             }
  827.             if (nullableMismatch)
  828.                 member.TypeDesc = Scope.GetTypeDesc(typeof(object));
  829.             else {
  830.                 TypeDesc[] typeDescs = new TypeDesc[uniqueTypeDescs.Count];
  831.                 IEnumerator enumerator = uniqueTypeDescs.Values.GetEnumerator();
  832.                 for (int i = 0; i < typeDescs.Length; i++) {
  833.                     if (!enumerator.MoveNext())
  834.                         break;
  835.                     typeDescs[i] = ((ElementAccessor)enumerator.Current).Mapping.TypeDesc;
  836.                 }
  837.                 member.TypeDesc = TypeDesc.FindCommonBaseTypeDesc(typeDescs);
  838.                 if (member.TypeDesc == null)
  839.                     member.TypeDesc = Scope.GetTypeDesc(typeof(object));
  840.             }
  841.            
  842.             if (groupRepeats)
  843.                 member.TypeDesc = member.TypeDesc.CreateArrayTypeDesc();
  844.            
  845.             if (membersScope != null) {
  846.                 member.Name = membersScope.AddUnique(groupRepeats ? "Items" : "Item", member);
  847.                 if (members != null) {
  848.                     members.Add(member.Name, member);
  849.                 }
  850.             }
  851.            
  852.             if (duplicateTypes) {
  853.                 member.ChoiceIdentifier = new ChoiceIdentifierAccessor();
  854.                 member.ChoiceIdentifier.MemberName = member.Name + "ElementName";
  855.                 // we need to create the EnumMapping to store all of the element names
  856.                 member.ChoiceIdentifier.Mapping = ImportEnumeratedChoice(member.Elements, ns, member.Name + "ChoiceType");
  857.                 member.ChoiceIdentifier.MemberIds = new string[member.Elements.Length];
  858.                 ConstantMapping[] constants = ((EnumMapping)member.ChoiceIdentifier.Mapping).Constants;
  859.                 for (int i = 0; i < member.Elements.Length; i++) {
  860.                     member.ChoiceIdentifier.MemberIds[i] = constants[i].Name;
  861.                 }
  862.                 MemberMapping choiceIdentifier = new MemberMapping();
  863.                 choiceIdentifier.Ignore = true;
  864.                 choiceIdentifier.Name = member.ChoiceIdentifier.MemberName;
  865.                 if (groupRepeats) {
  866.                     choiceIdentifier.TypeDesc = member.ChoiceIdentifier.Mapping.TypeDesc.CreateArrayTypeDesc();
  867.                 }
  868.                 else {
  869.                     choiceIdentifier.TypeDesc = member.ChoiceIdentifier.Mapping.TypeDesc;
  870.                 }
  871.                
  872.                 // create element accessor for the choiceIdentifier
  873.                
  874.                 ElementAccessor choiceAccessor = new ElementAccessor();
  875.                 choiceAccessor.Name = choiceIdentifier.Name;
  876.                 choiceAccessor.Namespace = ns;
  877.                 choiceAccessor.Mapping = member.ChoiceIdentifier.Mapping;
  878.                 choiceIdentifier.Elements = new ElementAccessor[] {choiceAccessor};
  879.                
  880.                 if (membersScope != null) {
  881.                     choiceAccessor.Name = choiceIdentifier.Name = member.ChoiceIdentifier.MemberName = membersScope.AddUnique(member.ChoiceIdentifier.MemberName, choiceIdentifier);
  882.                     if (members != null) {
  883.                         members.Add(choiceAccessor.Name, choiceIdentifier);
  884.                     }
  885.                 }
  886.             }
  887.             return member;
  888.         }
  889.        
  890.         bool GatherGroupChoices(XmlSchemaGroup group, NameTable choiceElements, string identifier, string ns, ref bool needExplicitOrder, bool allowDuplicates)
  891.         {
  892.             return GatherGroupChoices(group.Particle, choiceElements, identifier, ns, ref needExplicitOrder, allowDuplicates);
  893.         }
  894.        
  895.         bool GatherGroupChoices(XmlSchemaParticle particle, NameTable choiceElements, string identifier, string ns, ref bool needExplicitOrder, bool allowDuplicates)
  896.         {
  897.             if (particle is XmlSchemaGroupRef) {
  898.                 XmlSchemaGroupRef refGroup = (XmlSchemaGroupRef)particle;
  899.                 if (!refGroup.RefName.IsEmpty) {
  900.                     AddReference(refGroup.RefName, GroupsInUse, Res.XmlCircularGroupReference);
  901.                     if (GatherGroupChoices(FindGroup(refGroup.RefName), choiceElements, identifier, refGroup.RefName.Namespace, ref needExplicitOrder, allowDuplicates)) {
  902.                         RemoveReference(refGroup.RefName, GroupsInUse);
  903.                         return true;
  904.                     }
  905.                     RemoveReference(refGroup.RefName, GroupsInUse);
  906.                 }
  907.             }
  908.             else if (particle is XmlSchemaGroupBase) {
  909.                 XmlSchemaGroupBase group = (XmlSchemaGroupBase)particle;
  910.                 bool groupRepeats = group.IsMultipleOccurrence;
  911.                 XmlSchemaAny any = null;
  912.                 bool duplicateElements = false;
  913.                 for (int i = 0; i < group.Items.Count; i++) {
  914.                     object item = group.Items[i];
  915.                     if (item is XmlSchemaGroupBase || item is XmlSchemaGroupRef) {
  916.                         if (GatherGroupChoices((XmlSchemaParticle)item, choiceElements, identifier, ns, ref needExplicitOrder, allowDuplicates))
  917.                             groupRepeats = true;
  918.                     }
  919.                     else if (item is XmlSchemaAny) {
  920.                         if (GenerateOrder) {
  921.                             AddScopeElements(choiceElements, ImportAny((XmlSchemaAny)item, true, ns), ref duplicateElements, allowDuplicates);
  922.                         }
  923.                         else {
  924.                             any = (XmlSchemaAny)item;
  925.                         }
  926.                     }
  927.                     else if (item is XmlSchemaElement) {
  928.                         XmlSchemaElement element = (XmlSchemaElement)item;
  929.                         XmlSchemaElement headElement = GetTopLevelElement(element);
  930.                         if (headElement != null) {
  931.                             XmlSchemaElement[] elements = GetEquivalentElements(headElement);
  932.                             for (int j = 0; j < elements.Length; j++) {
  933.                                 if (elements[j].IsMultipleOccurrence)
  934.                                     groupRepeats = true;
  935.                                 AddScopeElement(choiceElements, ImportElement(elements[j], identifier, typeof(TypeMapping), null, elements[j].QualifiedName.Namespace, true), ref duplicateElements, allowDuplicates);
  936.                             }
  937.                         }
  938.                         if (element.IsMultipleOccurrence)
  939.                             groupRepeats = true;
  940.                         AddScopeElement(choiceElements, ImportElement(element, identifier, typeof(TypeMapping), null, element.QualifiedName.Namespace, false), ref duplicateElements, allowDuplicates);
  941.                     }
  942.                 }
  943.                 if (any != null) {
  944.                     AddScopeElements(choiceElements, ImportAny(any, true, ns), ref duplicateElements, allowDuplicates);
  945.                 }
  946.                 if (!groupRepeats && !(group is XmlSchemaChoice) && group.Items.Count > 1) {
  947.                     groupRepeats = true;
  948.                 }
  949.                 return groupRepeats;
  950.             }
  951.             return false;
  952.         }
  953.        
  954.         void AddScopeElement(INameScope scope, ElementAccessor element, ref bool duplicateElements, bool allowDuplicates)
  955.         {
  956.             if (scope == null)
  957.                 return;
  958.            
  959.             ElementAccessor scopeElement = (ElementAccessor)scope[element.Name, element.Namespace];
  960.             if (scopeElement != null) {
  961.                 if (!allowDuplicates) {
  962.                     throw new InvalidOperationException(Res.GetString(Res.XmlDuplicateElementInScope, element.Name, element.Namespace));
  963.                 }
  964.                 if (scopeElement.Mapping.TypeDesc != element.Mapping.TypeDesc) {
  965.                     throw new InvalidOperationException(Res.GetString(Res.XmlDuplicateElementInScope1, element.Name, element.Namespace));
  966.                 }
  967.                 duplicateElements = true;
  968.             }
  969.             else {
  970.                 scope[element.Name, element.Namespace] = element;
  971.             }
  972.         }
  973.        
  974.         void AddScopeElements(INameScope scope, ElementAccessor[] elements, ref bool duplicateElements, bool allowDuplicates)
  975.         {
  976.             for (int i = 0; i < elements.Length; i++) {
  977.                 AddScopeElement(scope, elements[i], ref duplicateElements, allowDuplicates);
  978.             }
  979.         }
  980.        
  981.         void ImportGroupMembers(XmlSchemaParticle particle, string identifier, CodeIdentifiers members, CodeIdentifiers membersScope, INameScope elementsScope, string ns, bool groupRepeats, ref bool mixed, ref bool needExplicitOrder, bool allowDuplicates,
  982.         bool allowUnboundedElements)
  983.         {
  984.            
  985.             if (particle is XmlSchemaGroupRef) {
  986.                 XmlSchemaGroupRef refGroup = (XmlSchemaGroupRef)particle;
  987.                 if (!refGroup.RefName.IsEmpty) {
  988.                     AddReference(refGroup.RefName, GroupsInUse, Res.XmlCircularGroupReference);
  989.                     ImportGroupMembers(FindGroup(refGroup.RefName).Particle, identifier, members, membersScope, elementsScope, refGroup.RefName.Namespace, groupRepeats | refGroup.IsMultipleOccurrence, ref mixed, ref needExplicitOrder, allowDuplicates,
  990.                     allowUnboundedElements);
  991.                     RemoveReference(refGroup.RefName, GroupsInUse);
  992.                 }
  993.             }
  994.             else if (particle is XmlSchemaGroupBase) {
  995.                 XmlSchemaGroupBase group = (XmlSchemaGroupBase)particle;
  996.                
  997.                 if (group.IsMultipleOccurrence)
  998.                     groupRepeats = true;
  999.                
  1000.                 if (GenerateOrder && groupRepeats && group.Items.Count > 1) {
  1001.                     ImportChoiceGroup(group, identifier, members, membersScope, elementsScope, ns, groupRepeats, ref needExplicitOrder, allowDuplicates);
  1002.                 }
  1003.                 else {
  1004.                     for (int i = 0; i < group.Items.Count; i++) {
  1005.                         object item = group.Items[i];
  1006.                         if (item is XmlSchemaChoice)
  1007.                             ImportChoiceGroup((XmlSchemaGroupBase)item, identifier, members, membersScope, elementsScope, ns, groupRepeats, ref needExplicitOrder, allowDuplicates);
  1008.                         else if (item is XmlSchemaElement)
  1009.                             ImportElementMember((XmlSchemaElement)item, identifier, members, membersScope, elementsScope, ns, groupRepeats, ref needExplicitOrder, allowDuplicates, allowUnboundedElements
  1010.                             );
  1011.                         else if (item is XmlSchemaAny) {
  1012.                             ImportAnyMember((XmlSchemaAny)item, identifier, members, membersScope, elementsScope, ns, ref mixed, ref needExplicitOrder, allowDuplicates);
  1013.                         }
  1014.                         else if (item is XmlSchemaParticle) {
  1015.                             ImportGroupMembers((XmlSchemaParticle)item, identifier, members, membersScope, elementsScope, ns, groupRepeats, ref mixed, ref needExplicitOrder, allowDuplicates,
  1016.                             true);
  1017.                         }
  1018.                     }
  1019.                 }
  1020.             }
  1021.         }
  1022.        
  1023.         XmlSchemaElement GetTopLevelElement(XmlSchemaElement element)
  1024.         {
  1025.             if (!element.RefName.IsEmpty)
  1026.                 return FindElement(element.RefName);
  1027.             return null;
  1028.         }
  1029.        
  1030.         XmlSchemaElement[] GetEquivalentElements(XmlSchemaElement element)
  1031.         {
  1032.             ArrayList equivalentElements = new ArrayList();
  1033.            
  1034.             foreach (XmlSchema schema in Schemas.SchemaSet.Schemas()) {
  1035.                 for (int j = 0; j < schema.Items.Count; j++) {
  1036.                     object item = schema.Items[j];
  1037.                     if (item is XmlSchemaElement) {
  1038.                         XmlSchemaElement equivalentElement = (XmlSchemaElement)item;
  1039.                         if (!equivalentElement.IsAbstract && equivalentElement.SubstitutionGroup.Namespace == schema.TargetNamespace && equivalentElement.SubstitutionGroup.Name == element.Name) {
  1040.                             equivalentElements.Add(equivalentElement);
  1041.                         }
  1042.                     }
  1043.                 }
  1044.             }
  1045.            
  1046.             return (XmlSchemaElement[])equivalentElements.ToArray(typeof(XmlSchemaElement));
  1047.         }
  1048.        
  1049.         bool ImportSubstitutionGroupMember(XmlSchemaElement element, string identifier, CodeIdentifiers members, CodeIdentifiers membersScope, string ns, bool repeats, ref bool needExplicitOrder, bool allowDuplicates)
  1050.         {
  1051.             XmlSchemaElement[] elements = GetEquivalentElements(element);
  1052.             if (elements.Length == 0)
  1053.                 return false;
  1054.             XmlSchemaChoice choice = new XmlSchemaChoice();
  1055.             for (int i = 0; i < elements.Length; i++)
  1056.                 choice.Items.Add(elements[i]);
  1057.             if (!element.IsAbstract)
  1058.                 choice.Items.Add(element);
  1059.             if (identifier.Length == 0)
  1060.                 identifier = CodeIdentifier.MakeValid(Accessor.UnescapeName(element.Name));
  1061.             else
  1062.                 identifier += CodeIdentifier.MakePascal(Accessor.UnescapeName(element.Name));
  1063.             ImportChoiceGroup(choice, identifier, members, membersScope, null, ns, repeats, ref needExplicitOrder, allowDuplicates);
  1064.            
  1065.             return true;
  1066.         }
  1067.        
  1068.         void ImportTextMember(CodeIdentifiers members, CodeIdentifiers membersScope, XmlQualifiedName simpleContentType)
  1069.         {
  1070.             TypeMapping mapping;
  1071.             bool isMixed = false;
  1072.            
  1073.             if (simpleContentType != null) {
  1074.                 // allow to use all primitive types
  1075.                 mapping = ImportType(simpleContentType, typeof(TypeMapping), null, TypeFlags.CanBeElementValue | TypeFlags.CanBeTextValue, false);
  1076.                 if (!(mapping is PrimitiveMapping || mapping.TypeDesc.CanBeTextValue)) {
  1077.                     return;
  1078.                 }
  1079.             }
  1080.             else {
  1081.                 // this is a case of the mixed content type, just generate string typeDesc
  1082.                 isMixed = true;
  1083.                 mapping = GetDefaultMapping(TypeFlags.CanBeElementValue | TypeFlags.CanBeTextValue);
  1084.             }
  1085.            
  1086.             TextAccessor accessor = new TextAccessor();
  1087.             accessor.Mapping = mapping;
  1088.            
  1089.             MemberMapping member = new MemberMapping();
  1090.             member.Elements = new ElementAccessor[0];
  1091.             member.Text = accessor;
  1092.             if (isMixed) {
  1093.                 // just generate code for the standard mixed case (string[] text)
  1094.                 member.TypeDesc = accessor.Mapping.TypeDesc.CreateArrayTypeDesc();
  1095.                 member.Name = members.MakeRightCase("Text");
  1096.             }
  1097.             else {
  1098.                 // import mapping for the simpleContent
  1099.                 PrimitiveMapping pm = (PrimitiveMapping)accessor.Mapping;
  1100.                 if (pm.IsList) {
  1101.                     member.TypeDesc = accessor.Mapping.TypeDesc.CreateArrayTypeDesc();
  1102.                     member.Name = members.MakeRightCase("Text");
  1103.                 }
  1104.                 else {
  1105.                     member.TypeDesc = accessor.Mapping.TypeDesc;
  1106.                     member.Name = members.MakeRightCase("Value");
  1107.                 }
  1108.             }
  1109.             member.Name = membersScope.AddUnique(member.Name, member);
  1110.             members.Add(member.Name, member);
  1111.         }
  1112.        
  1113.         MemberMapping ImportAnyMember(XmlSchemaAny any, string identifier, CodeIdentifiers members, CodeIdentifiers membersScope, INameScope elementsScope, string ns, ref bool mixed, ref bool needExplicitOrder, bool allowDuplicates)
  1114.         {
  1115.             ElementAccessor[] accessors = ImportAny(any, !mixed, ns);
  1116.             AddScopeElements(elementsScope, accessors, ref needExplicitOrder, allowDuplicates);
  1117.             MemberMapping member = new MemberMapping();
  1118.             member.Elements = accessors;
  1119.             member.Name = membersScope.MakeRightCase("Any");
  1120.             member.Name = membersScope.AddUnique(member.Name, member);
  1121.             members.Add(member.Name, member);
  1122.             member.TypeDesc = ((TypeMapping)accessors[0].Mapping).TypeDesc;
  1123.            
  1124.             bool repeats = any.IsMultipleOccurrence;
  1125.            
  1126.             if (mixed) {
  1127.                 SpecialMapping textMapping = new SpecialMapping();
  1128.                 textMapping.TypeDesc = Scope.GetTypeDesc(typeof(XmlNode));
  1129.                 textMapping.TypeName = textMapping.TypeDesc.Name;
  1130.                 member.TypeDesc = textMapping.TypeDesc;
  1131.                 TextAccessor text = new TextAccessor();
  1132.                 text.Mapping = textMapping;
  1133.                 member.Text = text;
  1134.                 repeats = true;
  1135.                 mixed = false;
  1136.             }
  1137.            
  1138.             if (repeats) {
  1139.                 member.TypeDesc = member.TypeDesc.CreateArrayTypeDesc();
  1140.             }
  1141.             return member;
  1142.         }
  1143.         ElementAccessor[] ImportAny(XmlSchemaAny any, bool makeElement, string targetNamespace)
  1144.         {
  1145.             SpecialMapping mapping = new SpecialMapping();
  1146.            
  1147.             mapping.TypeDesc = Scope.GetTypeDesc(makeElement ? typeof(XmlElement) : typeof(XmlNode));
  1148.             mapping.TypeName = mapping.TypeDesc.Name;
  1149.            
  1150.            
  1151.             TypeFlags flags = TypeFlags.CanBeElementValue;
  1152.             if (makeElement)
  1153.                 flags |= TypeFlags.CanBeTextValue;
  1154.            
  1155.             // let the extensions to run
  1156.             RunSchemaExtensions(mapping, XmlQualifiedName.Empty, null, any, flags);
  1157.            
  1158.             if (GenerateOrder && any.Namespace != null) {
  1159.                 NamespaceList list = new NamespaceList(any.Namespace, targetNamespace);
  1160.                
  1161.                 if (list.Type == NamespaceList.ListType.Set) {
  1162.                     ICollection namespaces = list.Enumerate;
  1163.                     ElementAccessor[] accessors = new ElementAccessor[namespaces.Count == 0 ? 1 : namespaces.Count];
  1164.                     int count = 0;
  1165.                     foreach (string ns in list.Enumerate) {
  1166.                         ElementAccessor accessor = new ElementAccessor();
  1167.                         accessor.Mapping = mapping;
  1168.                         accessor.Any = true;
  1169.                         accessor.Namespace = ns;
  1170.                         accessors[count++] = accessor;
  1171.                     }
  1172.                     if (count > 0) {
  1173.                         return accessors;
  1174.                     }
  1175.                 }
  1176.             }
  1177.            
  1178.             ElementAccessor anyAccessor = new ElementAccessor();
  1179.             anyAccessor.Mapping = mapping;
  1180.             anyAccessor.Any = true;
  1181.             return new ElementAccessor[] {anyAccessor};
  1182.         }
  1183.        
  1184.         ElementAccessor ImportArray(XmlSchemaElement element, string identifier, string ns, bool repeats)
  1185.         {
  1186.             if (repeats)
  1187.                 return null;
  1188.             if (element.SchemaType == null)
  1189.                 return null;
  1190.             if (element.IsMultipleOccurrence)
  1191.                 return null;
  1192.             XmlSchemaType type = element.SchemaType;
  1193.             ArrayMapping arrayMapping = ImportArrayMapping(type, identifier, ns, repeats);
  1194.             if (arrayMapping == null)
  1195.                 return null;
  1196.             ElementAccessor arrayAccessor = new ElementAccessor();
  1197.             arrayAccessor.Name = element.Name;
  1198.             arrayAccessor.Namespace = ns;
  1199.             arrayAccessor.Mapping = arrayMapping;
  1200.             if (arrayMapping.TypeDesc.IsNullable)
  1201.                 arrayAccessor.IsNullable = element.IsNillable;
  1202.             arrayAccessor.Form = ElementForm(ns, element);
  1203.             return arrayAccessor;
  1204.         }
  1205.        
  1206.         ArrayMapping ImportArrayMapping(XmlSchemaType type, string identifier, string ns, bool repeats)
  1207.         {
  1208.             if (!(type is XmlSchemaComplexType))
  1209.                 return null;
  1210.             if (!type.DerivedFrom.IsEmpty)
  1211.                 return null;
  1212.             if (IsMixed(type))
  1213.                 return null;
  1214.            
  1215.             Mapping previousMapping = (Mapping)ImportedMappings[type];
  1216.             if (previousMapping != null) {
  1217.                 if (previousMapping is ArrayMapping)
  1218.                     return (ArrayMapping)previousMapping;
  1219.                 else
  1220.                     return null;
  1221.             }
  1222.            
  1223.             TypeItems items = GetTypeItems(type);
  1224.            
  1225.             if (items.Attributes != null && items.Attributes.Count > 0)
  1226.                 return null;
  1227.             if (items.AnyAttribute != null)
  1228.                 return null;
  1229.             if (items.Particle == null)
  1230.                 return null;
  1231.            
  1232.             XmlSchemaGroupBase item = items.Particle;
  1233.             ArrayMapping arrayMapping = new ArrayMapping();
  1234.            
  1235.             arrayMapping.TypeName = identifier;
  1236.             arrayMapping.Namespace = ns;
  1237.            
  1238.             if (item is XmlSchemaChoice) {
  1239.                 XmlSchemaChoice choice = (XmlSchemaChoice)item;
  1240.                 if (!choice.IsMultipleOccurrence)
  1241.                     return null;
  1242.                 bool needExplicitOrder = false;
  1243.                 MemberMapping choiceMember = ImportChoiceGroup(choice, identifier, null, null, null, ns, true, ref needExplicitOrder, false);
  1244.                 if (choiceMember.ChoiceIdentifier != null)
  1245.                     return null;
  1246.                 arrayMapping.TypeDesc = choiceMember.TypeDesc;
  1247.                 arrayMapping.Elements = choiceMember.Elements;
  1248.                 arrayMapping.TypeName = (type.Name == null || type.Name.Length == 0) ? "ArrayOf" + CodeIdentifier.MakePascal(arrayMapping.TypeDesc.Name) : type.Name;
  1249.             }
  1250.             else if (item is XmlSchemaAll || item is XmlSchemaSequence) {
  1251.                 if (item.Items.Count != 1 || !(item.Items[0] is XmlSchemaElement))
  1252.                     return null;
  1253.                 XmlSchemaElement itemElement = (XmlSchemaElement)item.Items[0];
  1254.                 if (!itemElement.IsMultipleOccurrence)
  1255.                     return null;
  1256.                 ElementAccessor itemAccessor = ImportElement(itemElement, identifier, typeof(TypeMapping), null, ns, false);
  1257.                 if (itemAccessor.Any)
  1258.                     return null;
  1259.                 arrayMapping.Elements = new ElementAccessor[] {itemAccessor};
  1260.                 arrayMapping.TypeDesc = ((TypeMapping)itemAccessor.Mapping).TypeDesc.CreateArrayTypeDesc();
  1261.                 arrayMapping.TypeName = (type.Name == null || type.Name.Length == 0) ? "ArrayOf" + CodeIdentifier.MakePascal(itemAccessor.Mapping.TypeDesc.Name) : type.Name;
  1262.             }
  1263.             else {
  1264.                 return null;
  1265.             }
  1266.             ImportedMappings[type] = arrayMapping;
  1267.             Scope.AddTypeMapping(arrayMapping);
  1268.             // for the array-like mappings we need to create a struct mapping for the case when it referenced by the top-level element
  1269.             arrayMapping.TopLevelMapping = ImportStructType(type, ns, identifier, null, true);
  1270.             if (type.Name != null && type.Name.Length != 0)
  1271.                 ImportDerivedTypes(new XmlQualifiedName(identifier, ns));
  1272.            
  1273.             arrayMapping.TopLevelMapping.ReferencedByTopLevelElement = true;
  1274.             return arrayMapping;
  1275.         }
  1276.        
  1277.         SpecialMapping ImportAnyMapping(XmlSchemaType type, string identifier, string ns, bool repeats)
  1278.         {
  1279.             if (type == null)
  1280.                 return null;
  1281.             if (!type.DerivedFrom.IsEmpty)
  1282.                 return null;
  1283.            
  1284.             bool mixed = IsMixed(type);
  1285.             TypeItems items = GetTypeItems(type);
  1286.             if (items.Particle == null)
  1287.                 return null;
  1288.             if (!(items.Particle is XmlSchemaAll || items.Particle is XmlSchemaSequence))
  1289.                 return null;
  1290.             if (items.Attributes != null && items.Attributes.Count > 0)
  1291.                 return null;
  1292.             XmlSchemaGroupBase group = (XmlSchemaGroupBase)items.Particle;
  1293.            
  1294.             if (group.Items.Count != 1 || !(group.Items[0] is XmlSchemaAny))
  1295.                 return null;
  1296.             XmlSchemaAny any = (XmlSchemaAny)group.Items[0];
  1297.            
  1298.             SpecialMapping mapping = new SpecialMapping();
  1299.             // check for special named any case
  1300.             if (items.AnyAttribute != null && any.IsMultipleOccurrence && mixed) {
  1301.                 mapping.NamedAny = true;
  1302.                 mapping.TypeDesc = Scope.GetTypeDesc(typeof(XmlElement));
  1303.             }
  1304.             else if (items.AnyAttribute != null || any.IsMultipleOccurrence) {
  1305.                 // these only work for named any case -- otherwise import as struct
  1306.                 return null;
  1307.             }
  1308.             else {
  1309.                 mapping.TypeDesc = Scope.GetTypeDesc(mixed ? typeof(XmlNode) : typeof(XmlElement));
  1310.             }
  1311.            
  1312.             TypeFlags flags = TypeFlags.CanBeElementValue;
  1313.             if (items.AnyAttribute != null || mixed)
  1314.                 flags |= TypeFlags.CanBeTextValue;
  1315.            
  1316.             // let the extensions to run
  1317.             RunSchemaExtensions(mapping, XmlQualifiedName.Empty, null, any, flags);
  1318.            
  1319.             mapping.TypeName = mapping.TypeDesc.Name;
  1320.             if (repeats)
  1321.                 mapping.TypeDesc = mapping.TypeDesc.CreateArrayTypeDesc();
  1322.            
  1323.             return mapping;
  1324.         }
  1325.        
  1326.         void ImportElementMember(XmlSchemaElement element, string identifier, CodeIdentifiers members, CodeIdentifiers membersScope, INameScope elementsScope, string ns, bool repeats, ref bool needExplicitOrder, bool allowDuplicates, bool allowUnboundedElements
  1327.         )
  1328.         {
  1329.             repeats = repeats | element.IsMultipleOccurrence;
  1330.             XmlSchemaElement headElement = GetTopLevelElement(element);
  1331.             if (headElement != null && ImportSubstitutionGroupMember(headElement, identifier, members, membersScope, ns, repeats, ref needExplicitOrder, allowDuplicates)) {
  1332.                 return;
  1333.             }
  1334.             ElementAccessor accessor;
  1335.             if ((accessor = ImportArray(element, identifier, ns, repeats)) == null) {
  1336.                 accessor = ImportElement(element, identifier, typeof(TypeMapping), null, ns, false);
  1337.             }
  1338.            
  1339.             MemberMapping member = new MemberMapping();
  1340.             string name = CodeIdentifier.MakeValid(Accessor.UnescapeName(accessor.Name));
  1341.             member.Name = membersScope.AddUnique(name, member);
  1342.            
  1343.             if (member.Name.EndsWith("Specified", StringComparison.Ordinal)) {
  1344.                 name = member.Name;
  1345.                 member.Name = membersScope.AddUnique(member.Name, member);
  1346.                 membersScope.Remove(name);
  1347.             }
  1348.             members.Add(member.Name, member);
  1349.             // we do not support lists for elements
  1350.             if (accessor.Mapping.IsList) {
  1351.                 accessor.Mapping = GetDefaultMapping(TypeFlags.CanBeElementValue | TypeFlags.CanBeTextValue);
  1352.                 member.TypeDesc = accessor.Mapping.TypeDesc;
  1353.             }
  1354.             else {
  1355.                 member.TypeDesc = accessor.Mapping.TypeDesc;
  1356.             }
  1357.            
  1358.             AddScopeElement(elementsScope, accessor, ref needExplicitOrder, allowDuplicates);
  1359.             member.Elements = new ElementAccessor[] {accessor};
  1360.            
  1361.             if (element.IsMultipleOccurrence || repeats) {
  1362.                 if (!allowUnboundedElements && accessor.Mapping is ArrayMapping) {
  1363.                     accessor.Mapping = ((ArrayMapping)accessor.Mapping).TopLevelMapping;
  1364.                     accessor.Mapping.ReferencedByTopLevelElement = false;
  1365.                     accessor.Mapping.ReferencedByElement = true;
  1366.                 }
  1367.                 member.TypeDesc = accessor.Mapping.TypeDesc.CreateArrayTypeDesc();
  1368.             }
  1369.            
  1370.             if (element.MinOccurs == 0 && member.TypeDesc.IsValueType && !element.HasDefault && !member.TypeDesc.HasIsEmpty) {
  1371.                 member.CheckSpecified = true;
  1372.             }
  1373.         }
  1374.        
  1375.         void ImportAttributeMember(XmlSchemaAttribute attribute, string identifier, CodeIdentifiers members, CodeIdentifiers membersScope, string ns)
  1376.         {
  1377.             AttributeAccessor accessor = ImportAttribute(attribute, identifier, ns, attribute);
  1378.             if (accessor == null)
  1379.                 return;
  1380.             MemberMapping member = new MemberMapping();
  1381.             member.Elements = new ElementAccessor[0];
  1382.             member.Attribute = accessor;
  1383.             member.Name = CodeIdentifier.MakeValid(Accessor.UnescapeName(accessor.Name));
  1384.             member.Name = membersScope.AddUnique(member.Name, member);
  1385.             if (member.Name.EndsWith("Specified", StringComparison.Ordinal)) {
  1386.                 string name = member.Name;
  1387.                 member.Name = membersScope.AddUnique(member.Name, member);
  1388.                 membersScope.Remove(name);
  1389.             }
  1390.             members.Add(member.Name, member);
  1391.             member.TypeDesc = accessor.IsList ? accessor.Mapping.TypeDesc.CreateArrayTypeDesc() : accessor.Mapping.TypeDesc;
  1392.            
  1393.             if ((attribute.Use == XmlSchemaUse.Optional || attribute.Use == XmlSchemaUse.None) && member.TypeDesc.IsValueType && !attribute.HasDefault && !member.TypeDesc.HasIsEmpty) {
  1394.                 member.CheckSpecified = true;
  1395.             }
  1396.         }
  1397.        
  1398.         void ImportAnyAttributeMember(XmlSchemaAnyAttribute any, CodeIdentifiers members, CodeIdentifiers membersScope)
  1399.         {
  1400.             SpecialMapping mapping = new SpecialMapping();
  1401.             mapping.TypeDesc = Scope.GetTypeDesc(typeof(XmlAttribute));
  1402.             mapping.TypeName = mapping.TypeDesc.Name;
  1403.            
  1404.             AttributeAccessor accessor = new AttributeAccessor();
  1405.             accessor.Any = true;
  1406.             accessor.Mapping = mapping;
  1407.            
  1408.             MemberMapping member = new MemberMapping();
  1409.             member.Elements = new ElementAccessor[0];
  1410.             member.Attribute = accessor;
  1411.             member.Name = membersScope.MakeRightCase("AnyAttr");
  1412.             member.Name = membersScope.AddUnique(member.Name, member);
  1413.             members.Add(member.Name, member);
  1414.             member.TypeDesc = ((TypeMapping)accessor.Mapping).TypeDesc;
  1415.             member.TypeDesc = member.TypeDesc.CreateArrayTypeDesc();
  1416.         }
  1417.        
  1418.         bool KeepXmlnsDeclarations(XmlSchemaType type, out string xmlnsMemberName)
  1419.         {
  1420.             xmlnsMemberName = null;
  1421.             if (type.Annotation == null)
  1422.                 return false;
  1423.             if (type.Annotation.Items == null || type.Annotation.Items.Count == 0)
  1424.                 return false;
  1425.            
  1426.             foreach (XmlSchemaObject o in type.Annotation.Items) {
  1427.                 if (o is XmlSchemaAppInfo) {
  1428.                     XmlNode[] nodes = ((XmlSchemaAppInfo)o).Markup;
  1429.                     if (nodes != null && nodes.Length > 0) {
  1430.                         foreach (XmlNode node in nodes) {
  1431.                             if (node is XmlElement) {
  1432.                                 XmlElement e = (XmlElement)node;
  1433.                                 if (e.Name == "keepNamespaceDeclarations") {
  1434.                                     if (e.LastNode is XmlText) {
  1435.                                         xmlnsMemberName = (((XmlText)e.LastNode).Value).Trim(null);
  1436.                                     }
  1437.                                     return true;
  1438.                                 }
  1439.                             }
  1440.                         }
  1441.                     }
  1442.                 }
  1443.             }
  1444.             return false;
  1445.         }
  1446.        
  1447.         void ImportXmlnsDeclarationsMember(XmlSchemaType type, CodeIdentifiers members, CodeIdentifiers membersScope)
  1448.         {
  1449.             string xmlnsMemberName;
  1450.             if (!KeepXmlnsDeclarations(type, out xmlnsMemberName))
  1451.                 return;
  1452.             TypeDesc xmlnsTypeDesc = Scope.GetTypeDesc(typeof(XmlSerializerNamespaces));
  1453.             StructMapping xmlnsMapping = new StructMapping();
  1454.            
  1455.             xmlnsMapping.TypeDesc = xmlnsTypeDesc;
  1456.             xmlnsMapping.TypeName = xmlnsMapping.TypeDesc.Name;
  1457.             xmlnsMapping.Members = new MemberMapping[0];
  1458.             xmlnsMapping.IncludeInSchema = false;
  1459.             xmlnsMapping.ReferencedByTopLevelElement = true;
  1460.            
  1461.             ElementAccessor xmlns = new ElementAccessor();
  1462.             xmlns.Mapping = xmlnsMapping;
  1463.            
  1464.             MemberMapping member = new MemberMapping();
  1465.             member.Elements = new ElementAccessor[] {xmlns};
  1466.             member.Name = CodeIdentifier.MakeValid(xmlnsMemberName == null ? "Namespaces" : xmlnsMemberName);
  1467.             member.Name = membersScope.AddUnique(member.Name, member);
  1468.             members.Add(member.Name, member);
  1469.             member.TypeDesc = xmlnsTypeDesc;
  1470.             member.Xmlns = new XmlnsAccessor();
  1471.             member.Ignore = true;
  1472.         }
  1473.        
  1474.         void ImportAttributeGroupMembers(XmlSchemaAttributeGroup group, string identifier, CodeIdentifiers members, CodeIdentifiers membersScope, string ns)
  1475.         {
  1476.             for (int i = 0; i < group.Attributes.Count; i++) {
  1477.                 object item = group.Attributes[i];
  1478.                 if (item is XmlSchemaAttributeGroup)
  1479.                     ImportAttributeGroupMembers((XmlSchemaAttributeGroup)item, identifier, members, membersScope, ns);
  1480.                 else if (item is XmlSchemaAttribute)
  1481.                     ImportAttributeMember((XmlSchemaAttribute)item, identifier, members, membersScope, ns);
  1482.             }
  1483.             if (group.AnyAttribute != null)
  1484.                 ImportAnyAttributeMember(group.AnyAttribute, members, membersScope);
  1485.         }
  1486.        
  1487.         AttributeAccessor ImportSpecialAttribute(XmlQualifiedName name, string identifier)
  1488.         {
  1489.             PrimitiveMapping mapping = new PrimitiveMapping();
  1490.             mapping.TypeDesc = Scope.GetTypeDesc(typeof(string));
  1491.             mapping.TypeName = mapping.TypeDesc.DataType.Name;
  1492.             AttributeAccessor accessor = new AttributeAccessor();
  1493.             accessor.Name = name.Name;
  1494.             accessor.Namespace = XmlReservedNs.NsXml;
  1495.             accessor.CheckSpecial();
  1496.             accessor.Mapping = mapping;
  1497.             return accessor;
  1498.         }
  1499.        
  1500.         AttributeAccessor ImportAttribute(XmlSchemaAttribute attribute, string identifier, string ns, XmlSchemaAttribute defaultValueProvider)
  1501.         {
  1502.             if (attribute.Use == XmlSchemaUse.Prohibited)
  1503.                 return null;
  1504.             if (!attribute.RefName.IsEmpty) {
  1505.                 if (attribute.RefName.Namespace == XmlReservedNs.NsXml)
  1506.                     return ImportSpecialAttribute(attribute.RefName, identifier);
  1507.                 else
  1508.                     return ImportAttribute(FindAttribute(attribute.RefName), identifier, attribute.RefName.Namespace, defaultValueProvider);
  1509.             }
  1510.             TypeMapping mapping;
  1511.             if (attribute.Name.Length == 0)
  1512.                 throw new InvalidOperationException(Res.GetString(Res.XmlAttributeHasNoName));
  1513.             if (identifier.Length == 0)
  1514.                 identifier = CodeIdentifier.MakeValid(attribute.Name);
  1515.             else
  1516.                 identifier += CodeIdentifier.MakePascal(attribute.Name);
  1517.             if (!attribute.SchemaTypeName.IsEmpty)
  1518.                 mapping = (TypeMapping)ImportType(attribute.SchemaTypeName, typeof(TypeMapping), null, TypeFlags.CanBeAttributeValue, false);
  1519.             else if (attribute.SchemaType != null)
  1520.                 mapping = ImportDataType((XmlSchemaSimpleType)attribute.SchemaType, ns, identifier, null, TypeFlags.CanBeAttributeValue, false);
  1521.             else {
  1522.                 mapping = GetDefaultMapping(TypeFlags.CanBeAttributeValue);
  1523.             }
  1524.            
  1525.             // let the extensions to run
  1526.             if (mapping != null && !mapping.TypeDesc.IsMappedType) {
  1527.                 RunSchemaExtensions(mapping, attribute.SchemaTypeName, attribute.SchemaType, attribute, TypeFlags.CanBeElementValue | TypeFlags.CanBeAttributeValue | TypeFlags.CanBeTextValue);
  1528.             }
  1529.             AttributeAccessor accessor = new AttributeAccessor();
  1530.             accessor.Name = attribute.Name;
  1531.             accessor.Namespace = ns;
  1532.             accessor.Form = AttributeForm(ns, attribute);
  1533.             accessor.CheckSpecial();
  1534.             accessor.Mapping = mapping;
  1535.             accessor.IsList = mapping.IsList;
  1536.             accessor.IsOptional = attribute.Use != XmlSchemaUse.Required;
  1537.            
  1538.             if (defaultValueProvider.DefaultValue != null) {
  1539.                 accessor.Default = defaultValueProvider.DefaultValue;
  1540.             }
  1541.             else if (defaultValueProvider.FixedValue != null) {
  1542.                 accessor.Default = defaultValueProvider.FixedValue;
  1543.                 accessor.IsFixed = true;
  1544.             }
  1545.             else if (attribute != defaultValueProvider) {
  1546.                 if (attribute.DefaultValue != null) {
  1547.                     accessor.Default = attribute.DefaultValue;
  1548.                 }
  1549.                 else if (attribute.FixedValue != null) {
  1550.                     accessor.Default = attribute.FixedValue;
  1551.                     accessor.IsFixed = true;
  1552.                 }
  1553.             }
  1554.             return accessor;
  1555.         }
  1556.        
  1557.         TypeMapping ImportDataType(XmlSchemaSimpleType dataType, string typeNs, string identifier, Type baseType, TypeFlags flags, bool isList)
  1558.         {
  1559.             if (baseType != null)
  1560.                 return ImportStructDataType(dataType, typeNs, identifier, baseType);
  1561.            
  1562.             TypeMapping mapping = ImportNonXsdPrimitiveDataType(dataType, typeNs, flags);
  1563.             if (mapping != null)
  1564.                 return mapping;
  1565.            
  1566.             if (dataType.Content is XmlSchemaSimpleTypeRestriction) {
  1567.                 XmlSchemaSimpleTypeRestriction restriction = (XmlSchemaSimpleTypeRestriction)dataType.Content;
  1568.                 foreach (object o in restriction.Facets) {
  1569.                     if (o is XmlSchemaEnumerationFacet) {
  1570.                         return ImportEnumeratedDataType(dataType, typeNs, identifier, flags, isList);
  1571.                     }
  1572.                 }
  1573.                 if (restriction.BaseType != null) {
  1574.                     return ImportDataType(restriction.BaseType, typeNs, identifier, null, flags, false);
  1575.                 }
  1576.                 else {
  1577.                     AddReference(restriction.BaseTypeName, TypesInUse, Res.XmlCircularTypeReference);
  1578.                     mapping = ImportDataType(FindDataType(restriction.BaseTypeName, flags), restriction.BaseTypeName.Namespace, identifier, null, flags, false);
  1579.                     if (restriction.BaseTypeName.Namespace != XmlSchema.Namespace)
  1580.                         RemoveReference(restriction.BaseTypeName, TypesInUse);
  1581.                     return mapping;
  1582.                 }
  1583.             }
  1584.             else if (dataType.Content is XmlSchemaSimpleTypeList || dataType.Content is XmlSchemaSimpleTypeUnion) {
  1585.                 if (dataType.Content is XmlSchemaSimpleTypeList) {
  1586.                     // check if we have enumeration list
  1587.                     XmlSchemaSimpleTypeList list = (XmlSchemaSimpleTypeList)dataType.Content;
  1588.                     if (list.ItemType != null) {
  1589.                         mapping = ImportDataType(list.ItemType, typeNs, identifier, null, flags, true);
  1590.                         if (mapping != null) {
  1591.                             mapping.TypeName = dataType.Name;
  1592.                             return mapping;
  1593.                         }
  1594.                     }
  1595.                     else if (list.ItemTypeName != null && !list.ItemTypeName.IsEmpty) {
  1596.                         mapping = ImportType(list.ItemTypeName, typeof(TypeMapping), null, TypeFlags.CanBeAttributeValue, true);
  1597.                         if (mapping != null && mapping is PrimitiveMapping) {
  1598.                             ((PrimitiveMapping)mapping).IsList = true;
  1599.                             return mapping;
  1600.                         }
  1601.                     }
  1602.                 }
  1603.                 return GetDefaultMapping(flags);
  1604.             }
  1605.             return ImportPrimitiveDataType(dataType, flags);
  1606.         }
  1607.        
  1608.         TypeMapping ImportEnumeratedDataType(XmlSchemaSimpleType dataType, string typeNs, string identifier, TypeFlags flags, bool isList)
  1609.         {
  1610.             TypeMapping mapping = (TypeMapping)ImportedMappings[dataType];
  1611.             if (mapping != null)
  1612.                 return mapping;
  1613.            
  1614.             XmlSchemaType sourceType = dataType;
  1615.             while (!sourceType.DerivedFrom.IsEmpty) {
  1616.                 sourceType = FindType(sourceType.DerivedFrom, TypeFlags.CanBeElementValue | TypeFlags.CanBeAttributeValue);
  1617.             }
  1618.             if (sourceType is XmlSchemaComplexType)
  1619.                 return null;
  1620.             TypeDesc sourceTypeDesc = Scope.GetTypeDesc((XmlSchemaSimpleType)sourceType);
  1621.             if (sourceTypeDesc != null && sourceTypeDesc.FullName != typeof(string).FullName)
  1622.                 return ImportPrimitiveDataType(dataType, flags);
  1623.             identifier = Accessor.UnescapeName(identifier);
  1624.             string typeName = GenerateUniqueTypeName(identifier);
  1625.             EnumMapping enumMapping = new EnumMapping();
  1626.             enumMapping.IsReference = Schemas.IsReference(dataType);
  1627.             enumMapping.TypeDesc = new TypeDesc(typeName, typeName, TypeKind.Enum, null, 0);
  1628.             if (dataType.Name != null && dataType.Name.Length > 0)
  1629.                 enumMapping.TypeName = identifier;
  1630.             enumMapping.Namespace = typeNs;
  1631.             enumMapping.IsFlags = isList;
  1632.            
  1633.             CodeIdentifiers constants = new CodeIdentifiers();
  1634.             XmlSchemaSimpleTypeContent content = dataType.Content;
  1635.            
  1636.             if (content is XmlSchemaSimpleTypeRestriction) {
  1637.                 XmlSchemaSimpleTypeRestriction restriction = (XmlSchemaSimpleTypeRestriction)content;
  1638.                 for (int i = 0; i < restriction.Facets.Count; i++) {
  1639.                     object facet = restriction.Facets[i];
  1640.                     if (!(facet is XmlSchemaEnumerationFacet))
  1641.                         continue;
  1642.                     XmlSchemaEnumerationFacet enumeration = (XmlSchemaEnumerationFacet)facet;
  1643.                     // validate the enumeration value
  1644.                     if (sourceTypeDesc != null && sourceTypeDesc.HasCustomFormatter) {
  1645.                         XmlCustomFormatter.ToDefaultValue(enumeration.Value, sourceTypeDesc.FormatterName);
  1646.                     }
  1647.                     ConstantMapping constant = new ConstantMapping();
  1648.                     string constantName = CodeIdentifier.MakeValid(enumeration.Value);
  1649.                     constant.Name = constants.AddUnique(constantName, constant);
  1650.                     constant.XmlName = enumeration.Value;
  1651.                     constant.Value = i;
  1652.                 }
  1653.             }
  1654.             enumMapping.Constants = (ConstantMapping[])constants.ToArray(typeof(ConstantMapping));
  1655.             if (isList && enumMapping.Constants.Length > 63) {
  1656.                 // if we have 64+ flag constants we cannot map the type to long enum, we will use string mapping instead.
  1657.                 mapping = GetDefaultMapping(TypeFlags.CanBeElementValue | TypeFlags.CanBeTextValue | TypeFlags.CanBeAttributeValue);
  1658.                 ImportedMappings.Add(dataType, mapping);
  1659.                 return mapping;
  1660.             }
  1661.             ImportedMappings.Add(dataType, enumMapping);
  1662.             Scope.AddTypeMapping(enumMapping);
  1663.             return enumMapping;
  1664.         }
  1665.        
  1666.         internal class ElementComparer : IComparer
  1667.         {
  1668.             public int Compare(object o1, object o2)
  1669.             {
  1670.                 ElementAccessor e1 = (ElementAccessor)o1;
  1671.                 ElementAccessor e2 = (ElementAccessor)o2;
  1672.                 return String.Compare(e1.ToString(string.Empty), e2.ToString(string.Empty), StringComparison.Ordinal);
  1673.             }
  1674.         }
  1675.        
  1676.         EnumMapping ImportEnumeratedChoice(ElementAccessor[] choice, string typeNs, string typeName)
  1677.         {
  1678.             typeName = GenerateUniqueTypeName(Accessor.UnescapeName(typeName), typeNs);
  1679.             EnumMapping enumMapping = new EnumMapping();
  1680.             enumMapping.TypeDesc = new TypeDesc(typeName, typeName, TypeKind.Enum, null, 0);
  1681.             enumMapping.TypeName = typeName;
  1682.             enumMapping.Namespace = typeNs;
  1683.             enumMapping.IsFlags = false;
  1684.             enumMapping.IncludeInSchema = false;
  1685.            
  1686.             if (GenerateOrder) {
  1687.                 Array.Sort(choice, new ElementComparer());
  1688.             }
  1689.             CodeIdentifiers constants = new CodeIdentifiers();
  1690.             for (int i = 0; i < choice.Length; i++) {
  1691.                 ElementAccessor element = choice[i];
  1692.                 ConstantMapping constant = new ConstantMapping();
  1693.                 string constantName = CodeIdentifier.MakeValid(element.Name);
  1694.                 constant.Name = constants.AddUnique(constantName, constant);
  1695.                 constant.XmlName = element.ToString(typeNs);
  1696.                 constant.Value = i;
  1697.             }
  1698.             enumMapping.Constants = (ConstantMapping[])constants.ToArray(typeof(ConstantMapping));
  1699.             Scope.AddTypeMapping(enumMapping);
  1700.             return enumMapping;
  1701.         }
  1702.        
  1703.         PrimitiveMapping ImportPrimitiveDataType(XmlSchemaSimpleType dataType, TypeFlags flags)
  1704.         {
  1705.             TypeDesc sourceTypeDesc = GetDataTypeSource(dataType, flags);
  1706.             PrimitiveMapping mapping = new PrimitiveMapping();
  1707.             mapping.TypeDesc = sourceTypeDesc;
  1708.             mapping.TypeName = sourceTypeDesc.DataType.Name;
  1709.             mapping.Namespace = mapping.TypeDesc.IsXsdType ? XmlSchema.Namespace : UrtTypes.Namespace;
  1710.             return mapping;
  1711.         }
  1712.        
  1713.         PrimitiveMapping ImportNonXsdPrimitiveDataType(XmlSchemaSimpleType dataType, string ns, TypeFlags flags)
  1714.         {
  1715.             PrimitiveMapping mapping = null;
  1716.             TypeDesc typeDesc = null;
  1717.             if (dataType.Name != null && dataType.Name.Length != 0) {
  1718.                 typeDesc = Scope.GetTypeDesc(dataType.Name, ns, flags);
  1719.                 if (typeDesc != null) {
  1720.                     mapping = new PrimitiveMapping();
  1721.                     mapping.TypeDesc = typeDesc;
  1722.                     mapping.TypeName = typeDesc.DataType.Name;
  1723.                     mapping.Namespace = mapping.TypeDesc.IsXsdType ? XmlSchema.Namespace : ns;
  1724.                 }
  1725.             }
  1726.             return mapping;
  1727.         }
  1728.        
  1729.         XmlSchemaGroup FindGroup(XmlQualifiedName name)
  1730.         {
  1731.             XmlSchemaGroup group = (XmlSchemaGroup)Schemas.Find(name, typeof(XmlSchemaGroup));
  1732.             if (group == null)
  1733.                 throw new InvalidOperationException(Res.GetString(Res.XmlMissingGroup, name.Name));
  1734.            
  1735.             return group;
  1736.         }
  1737.        
  1738.         XmlSchemaAttributeGroup FindAttributeGroup(XmlQualifiedName name)
  1739.         {
  1740.             XmlSchemaAttributeGroup group = (XmlSchemaAttributeGroup)Schemas.Find(name, typeof(XmlSchemaAttributeGroup));
  1741.             if (group == null)
  1742.                 throw new InvalidOperationException(Res.GetString(Res.XmlMissingAttributeGroup, name.Name));
  1743.            
  1744.             return group;
  1745.         }
  1746.        
  1747.         static internal XmlQualifiedName BaseTypeName(XmlSchemaSimpleType dataType)
  1748.         {
  1749.             XmlSchemaSimpleTypeContent content = dataType.Content;
  1750.             if (content is XmlSchemaSimpleTypeRestriction) {
  1751.                 return ((XmlSchemaSimpleTypeRestriction)content).BaseTypeName;
  1752.             }
  1753.             else if (content is XmlSchemaSimpleTypeList) {
  1754.                 XmlSchemaSimpleTypeList list = (XmlSchemaSimpleTypeList)content;
  1755.                 if (list.ItemTypeName != null && !list.ItemTypeName.IsEmpty)
  1756.                     return list.ItemTypeName;
  1757.                 if (list.ItemType != null) {
  1758.                     return BaseTypeName(list.ItemType);
  1759.                 }
  1760.             }
  1761.             return new XmlQualifiedName("string", XmlSchema.Namespace);
  1762.         }
  1763.        
  1764.         TypeDesc GetDataTypeSource(XmlSchemaSimpleType dataType, TypeFlags flags)
  1765.         {
  1766.             TypeDesc typeDesc = null;
  1767.             if (dataType.Name != null && dataType.Name.Length != 0) {
  1768.                 typeDesc = Scope.GetTypeDesc(dataType);
  1769.                 if (typeDesc != null)
  1770.                     return typeDesc;
  1771.             }
  1772.             XmlQualifiedName qname = BaseTypeName(dataType);
  1773.             AddReference(qname, TypesInUse, Res.XmlCircularTypeReference);
  1774.             typeDesc = GetDataTypeSource(FindDataType(qname, flags), flags);
  1775.             if (qname.Namespace != XmlSchema.Namespace)
  1776.                 RemoveReference(qname, TypesInUse);
  1777.            
  1778.             return typeDesc;
  1779.         }
  1780.        
  1781.         XmlSchemaSimpleType FindDataType(XmlQualifiedName name, TypeFlags flags)
  1782.         {
  1783.             if (name == null || name.IsEmpty) {
  1784.                 return (XmlSchemaSimpleType)Scope.GetTypeDesc(typeof(string)).DataType;
  1785.             }
  1786.             TypeDesc typeDesc = Scope.GetTypeDesc(name.Name, name.Namespace, flags);
  1787.             if (typeDesc != null && typeDesc.DataType is XmlSchemaSimpleType)
  1788.                 return (XmlSchemaSimpleType)typeDesc.DataType;
  1789.             XmlSchemaSimpleType dataType = (XmlSchemaSimpleType)Schemas.Find(name, typeof(XmlSchemaSimpleType));
  1790.             if (dataType != null) {
  1791.                 return dataType;
  1792.             }
  1793.             if (name.Namespace == XmlSchema.Namespace)
  1794.                 return (XmlSchemaSimpleType)Scope.GetTypeDesc("string", XmlSchema.Namespace, flags).DataType;
  1795.             else {
  1796.                 if (name.Name == Soap.Array && name.Namespace == Soap.Encoding) {
  1797.                     throw new InvalidOperationException(Res.GetString(Res.XmlInvalidEncoding, name.ToString()));
  1798.                 }
  1799.                 else {
  1800.                     throw new InvalidOperationException(Res.GetString(Res.XmlMissingDataType, name.ToString()));
  1801.                 }
  1802.             }
  1803.         }
  1804.        
  1805.         XmlSchemaType FindType(XmlQualifiedName name, TypeFlags flags)
  1806.         {
  1807.             if (name == null || name.IsEmpty) {
  1808.                 return Scope.GetTypeDesc(typeof(string)).DataType;
  1809.             }
  1810.             object type = Schemas.Find(name, typeof(XmlSchemaComplexType));
  1811.             if (type != null) {
  1812.                 return (XmlSchemaComplexType)type;
  1813.             }
  1814.             return FindDataType(name, flags);
  1815.         }
  1816.        
  1817.         XmlSchemaElement FindElement(XmlQualifiedName name)
  1818.         {
  1819.             XmlSchemaElement element = (XmlSchemaElement)Schemas.Find(name, typeof(XmlSchemaElement));
  1820.             if (element == null)
  1821.                 throw new InvalidOperationException(Res.GetString(Res.XmlMissingElement, name.ToString()));
  1822.             return element;
  1823.         }
  1824.        
  1825.         XmlSchemaAttribute FindAttribute(XmlQualifiedName name)
  1826.         {
  1827.             XmlSchemaAttribute attribute = (XmlSchemaAttribute)Schemas.Find(name, typeof(XmlSchemaAttribute));
  1828.             if (attribute == null)
  1829.                 throw new InvalidOperationException(Res.GetString(Res.XmlMissingAttribute, name.Name));
  1830.            
  1831.             return attribute;
  1832.         }
  1833.        
  1834.         XmlSchemaForm ElementForm(string ns, XmlSchemaElement element)
  1835.         {
  1836.             if (element.Form == XmlSchemaForm.None) {
  1837.                 XmlSchemaObject parent = element;
  1838.                 while (parent.Parent != null) {
  1839.                     parent = parent.Parent;
  1840.                 }
  1841.                 XmlSchema schema = parent as XmlSchema;
  1842.                 if (schema != null) {
  1843.                     if (ns == null || ns.Length == 0) {
  1844.                         return schema.ElementFormDefault == XmlSchemaForm.None ? XmlSchemaForm.Unqualified : schema.ElementFormDefault;
  1845.                     }
  1846.                     else {
  1847.                         XmlSchemas.Preprocess(schema);
  1848.                         return element.QualifiedName.Namespace == null || element.QualifiedName.Namespace.Length == 0 ? XmlSchemaForm.Unqualified : XmlSchemaForm.Qualified;
  1849.                     }
  1850.                 }
  1851.                 return XmlSchemaForm.Qualified;
  1852.             }
  1853.             return element.Form;
  1854.         }
  1855.        
  1856.         internal string FindExtendedAnyElement(XmlSchemaAny any, bool mixed, CodeCompileUnit compileUnit, CodeNamespace mainNamespace, out SchemaImporterExtension extension)
  1857.         {
  1858.             extension = null;
  1859.             foreach (SchemaImporterExtension ex in Extensions) {
  1860.                 string typeName = ex.ImportAnyElement(any, mixed, Schemas, this, compileUnit, mainNamespace, Options, CodeProvider);
  1861.                 if (typeName != null && typeName.Length > 0) {
  1862.                     extension = ex;
  1863.                     return typeName;
  1864.                 }
  1865.             }
  1866.             return null;
  1867.         }
  1868.        
  1869.         internal string FindExtendedType(string name, string ns, XmlSchemaObject context, CodeCompileUnit compileUnit, CodeNamespace mainNamespace, out SchemaImporterExtension extension)
  1870.         {
  1871.             extension = null;
  1872.             foreach (SchemaImporterExtension ex in Extensions) {
  1873.                 string typeName = ex.ImportSchemaType(name, ns, context, Schemas, this, compileUnit, mainNamespace, Options, CodeProvider);
  1874.                 if (typeName != null && typeName.Length > 0) {
  1875.                     extension = ex;
  1876.                     return typeName;
  1877.                 }
  1878.             }
  1879.             return null;
  1880.         }
  1881.        
  1882.         internal string FindExtendedType(XmlSchemaType type, XmlSchemaObject context, CodeCompileUnit compileUnit, CodeNamespace mainNamespace, out SchemaImporterExtension extension)
  1883.         {
  1884.             extension = null;
  1885.             foreach (SchemaImporterExtension ex in Extensions) {
  1886.                 string typeName = ex.ImportSchemaType(type, context, Schemas, this, compileUnit, mainNamespace, Options, CodeProvider);
  1887.                 if (typeName != null && typeName.Length > 0) {
  1888.                     extension = ex;
  1889.                     return typeName;
  1890.                 }
  1891.             }
  1892.             return null;
  1893.         }
  1894.        
  1895.         XmlSchemaForm AttributeForm(string ns, XmlSchemaAttribute attribute)
  1896.         {
  1897.             if (attribute.Form == XmlSchemaForm.None) {
  1898.                 XmlSchemaObject parent = attribute;
  1899.                 while (parent.Parent != null) {
  1900.                     parent = parent.Parent;
  1901.                 }
  1902.                 XmlSchema schema = parent as XmlSchema;
  1903.                 if (schema != null) {
  1904.                     if (ns == null || ns.Length == 0) {
  1905.                         return schema.AttributeFormDefault == XmlSchemaForm.None ? XmlSchemaForm.Unqualified : schema.AttributeFormDefault;
  1906.                     }
  1907.                     else {
  1908.                         XmlSchemas.Preprocess(schema);
  1909.                         return attribute.QualifiedName.Namespace == null || attribute.QualifiedName.Namespace.Length == 0 ? XmlSchemaForm.Unqualified : XmlSchemaForm.Qualified;
  1910.                     }
  1911.                 }
  1912.                 return XmlSchemaForm.Unqualified;
  1913.             }
  1914.             return attribute.Form;
  1915.         }
  1916.     }
  1917. }

Developer Fusion