The Labs \ Source Viewer \ SSCLI \ System.Xml.Schema \ XmlSchemaInference

  1. //------------------------------------------------------------------------------
  2. // <copyright file="Infer.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. // <owner current="true" primary="true">priyal</owner>
  15. // <owner current="false" primary="false">nithyas</owner>
  16. //------------------------------------------------------------------------------
  17. using System;
  18. using System.IO;
  19. using System.Xml;
  20. using System.Collections;
  21. using System.Diagnostics;
  22. using System.Globalization;
  23. using System.Security.Permissions;
  24. namespace System.Xml.Schema
  25. {
  26.    
  27.     /// <include file='doc\Infer.uex' path='docs/doc[@for="Infer"]/*' />
  28.     /// <summary>
  29.     /// Infer class serves for infering XML Schema from given XML instance document.
  30.     /// </summary>
  31.     public sealed class XmlSchemaInference
  32.     {
  33.         static internal XmlQualifiedName ST_boolean = new XmlQualifiedName("boolean", XmlSchema.Namespace);
  34.         static internal XmlQualifiedName ST_byte = new XmlQualifiedName("byte", XmlSchema.Namespace);
  35.         static internal XmlQualifiedName ST_unsignedByte = new XmlQualifiedName("unsignedByte", XmlSchema.Namespace);
  36.         static internal XmlQualifiedName ST_short = new XmlQualifiedName("short", XmlSchema.Namespace);
  37.         static internal XmlQualifiedName ST_unsignedShort = new XmlQualifiedName("unsignedShort", XmlSchema.Namespace);
  38.         static internal XmlQualifiedName ST_int = new XmlQualifiedName("int", XmlSchema.Namespace);
  39.         static internal XmlQualifiedName ST_unsignedInt = new XmlQualifiedName("unsignedInt", XmlSchema.Namespace);
  40.         static internal XmlQualifiedName ST_long = new XmlQualifiedName("long", XmlSchema.Namespace);
  41.         static internal XmlQualifiedName ST_unsignedLong = new XmlQualifiedName("unsignedLong", XmlSchema.Namespace);
  42.         static internal XmlQualifiedName ST_integer = new XmlQualifiedName("integer", XmlSchema.Namespace);
  43.         static internal XmlQualifiedName ST_decimal = new XmlQualifiedName("decimal", XmlSchema.Namespace);
  44.         static internal XmlQualifiedName ST_float = new XmlQualifiedName("float", XmlSchema.Namespace);
  45.         static internal XmlQualifiedName ST_double = new XmlQualifiedName("double", XmlSchema.Namespace);
  46.         static internal XmlQualifiedName ST_duration = new XmlQualifiedName("duration", XmlSchema.Namespace);
  47.         static internal XmlQualifiedName ST_dateTime = new XmlQualifiedName("dateTime", XmlSchema.Namespace);
  48.         static internal XmlQualifiedName ST_time = new XmlQualifiedName("time", XmlSchema.Namespace);
  49.         static internal XmlQualifiedName ST_date = new XmlQualifiedName("date", XmlSchema.Namespace);
  50.         static internal XmlQualifiedName ST_gYearMonth = new XmlQualifiedName("gYearMonth", XmlSchema.Namespace);
  51.         static internal XmlQualifiedName ST_string = new XmlQualifiedName("string", XmlSchema.Namespace);
  52.         static internal XmlQualifiedName ST_anySimpleType = new XmlQualifiedName("anySimpleType", XmlSchema.Namespace);
  53.        
  54.         static internal XmlQualifiedName[] SimpleTypes = {ST_boolean, ST_byte, ST_unsignedByte, ST_short, ST_unsignedShort, ST_int, ST_unsignedInt, ST_long, ST_unsignedLong, ST_integer,
  55.         ST_decimal, ST_float, ST_double, ST_duration, ST_dateTime, ST_time, ST_date, ST_gYearMonth, ST_string};
  56.        
  57.         internal const short HC_ST_boolean = 0;
  58.         internal const short HC_ST_byte = 1;
  59.         internal const short HC_ST_unsignedByte = 2;
  60.         internal const short HC_ST_short = 3;
  61.         internal const short HC_ST_unsignedShort = 4;
  62.         internal const short HC_ST_int = 5;
  63.         internal const short HC_ST_unsignedInt = 6;
  64.         internal const short HC_ST_long = 7;
  65.         internal const short HC_ST_unsignedLong = 8;
  66.         internal const short HC_ST_integer = 9;
  67.         internal const short HC_ST_decimal = 10;
  68.         internal const short HC_ST_float = 11;
  69.         internal const short HC_ST_double = 12;
  70.         internal const short HC_ST_duration = 13;
  71.         internal const short HC_ST_dateTime = 14;
  72.         internal const short HC_ST_time = 15;
  73.         internal const short HC_ST_date = 16;
  74.         internal const short HC_ST_gYearMonth = 17;
  75.         internal const short HC_ST_string = 18;
  76.         internal const short HC_ST_Count = HC_ST_string + 1;
  77.        
  78.        
  79.         internal const int TF_boolean = 1 << HC_ST_boolean;
  80.         internal const int TF_byte = 1 << HC_ST_byte;
  81.         internal const int TF_unsignedByte = 1 << HC_ST_unsignedByte;
  82.         internal const int TF_short = 1 << HC_ST_short;
  83.         internal const int TF_unsignedShort = 1 << HC_ST_unsignedShort;
  84.         internal const int TF_int = 1 << HC_ST_int;
  85.         internal const int TF_unsignedInt = 1 << HC_ST_unsignedInt;
  86.         internal const int TF_long = 1 << HC_ST_long;
  87.         internal const int TF_unsignedLong = 1 << HC_ST_unsignedLong;
  88.         internal const int TF_integer = 1 << HC_ST_integer;
  89.         internal const int TF_decimal = 1 << HC_ST_decimal;
  90.         internal const int TF_float = 1 << HC_ST_float;
  91.         internal const int TF_double = 1 << HC_ST_double;
  92.         internal const int TF_duration = 1 << HC_ST_duration;
  93.         internal const int TF_dateTime = 1 << HC_ST_dateTime;
  94.         internal const int TF_time = 1 << HC_ST_time;
  95.         internal const int TF_date = 1 << HC_ST_date;
  96.         internal const int TF_gYearMonth = 1 << HC_ST_gYearMonth;
  97.         internal const int TF_string = 1 << HC_ST_string;
  98.        
  99.         XmlSchema rootSchema = null;
  100.         //(XmlSchema) xsc[TargetNamespace];
  101.         private XmlSchemaSet schemaSet;
  102.         private XmlReader xtr;
  103.         private NameTable nametable;
  104.         private string TargetNamespace;
  105.         private XmlNamespaceManager NamespaceManager;
  106.         //private Hashtable schemas; //contains collection of schemas before they get added to the XmlSchemaSet xsc
  107.         //private bool bRefine = false; //indicates if we are going to infer or refine schema when InferSchema is called
  108.         ArrayList schemaList;
  109.         InferenceOption occurrence = InferenceOption.Restricted;
  110.         InferenceOption typeInference = InferenceOption.Restricted;
  111.        
  112. /*  internal struct ReplaceList
  113.             {
  114.                 internal XmlSchemaObjectCollection col;
  115.                 internal int position;
  116.                 internal ReplaceList(XmlSchemaObjectCollection col, int position)
  117.                 {
  118.                     this.col = col;
  119.                     this.position = position;
  120.                 }
  121.             }*/       
  122.        
  123.         /// <include file='doc\Infer.uex' path='docs/doc[@for="InferenceOption"]/*' />
  124.         public enum InferenceOption
  125.         {
  126.             /// <include file='doc\Infer.uex' path='docs/doc[@for="InferenceOption.Restricted"]/*' />
  127.             Restricted,
  128.             /// <include file='doc\Infer.uex' path='docs/doc[@for="InferenceOption.Relaxed"]/*' />
  129.             Relaxed
  130.         }
  131.        
  132.         /// <include file='doc\Infer.uex' path='docs/doc[@for="Infer.Occurrence"]/*' />
  133.         public InferenceOption Occurrence {
  134.             get { return this.occurrence; }
  135.             set { this.occurrence = value; }
  136.         }
  137.        
  138.         /// <include file='doc\Infer.uex' path='docs/doc[@for="Infer.TypeInference"]/*' />
  139.         public InferenceOption TypeInference {
  140.             get { return this.typeInference; }
  141.             set { this.typeInference = value; }
  142.         }
  143.        
  144.         /// <include file='doc\Infer.uex' path='docs/doc[@for="Infer.Infer"]/*' />
  145.         public XmlSchemaInference()
  146.         {
  147.             this.nametable = new NameTable();
  148.             this.NamespaceManager = new XmlNamespaceManager(nametable);
  149.             this.NamespaceManager.AddNamespace("xs", XmlSchema.Namespace);
  150.             this.schemaList = new ArrayList();
  151.         }
  152.        
  153.         /// <include file='doc\Infer.uex' path='docs/doc[@for="Infer.InferSchema"]/*' />
  154.         public XmlSchemaSet InferSchema(XmlReader instanceDocument)
  155.         {
  156.             return InferSchema1(instanceDocument, new XmlSchemaSet(nametable));
  157.         }
  158.        
  159.         /// <include file='doc\Infer.uex' path='docs/doc[@for="Infer.InferSchema1"]/*' />
  160.         public XmlSchemaSet InferSchema(XmlReader instanceDocument, XmlSchemaSet schemas)
  161.         {
  162.             if (schemas == null) {
  163.                 schemas = new XmlSchemaSet(nametable);
  164.             }
  165.             return InferSchema1(instanceDocument, schemas);
  166.         }
  167.         internal XmlSchemaSet InferSchema1(XmlReader instanceDocument, XmlSchemaSet schemas)
  168.         {
  169.             if (instanceDocument == null) {
  170.                 throw new ArgumentNullException("instanceDocument");
  171.             }
  172.             this.rootSchema = null;
  173.             xtr = instanceDocument;
  174.             schemas.Compile();
  175.             this.schemaSet = schemas;
  176.             //schemas = new Hashtable();
  177.             //while(xtr.Read())
  178.            
  179.             while (xtr.NodeType != XmlNodeType.Element && xtr.Read())
  180.                 ;
  181.            
  182.            
  183.             if (xtr.NodeType == XmlNodeType.Element) {
  184.                 //Create and process the root element
  185.                 TargetNamespace = xtr.NamespaceURI;
  186.                 if (xtr.NamespaceURI == XmlSchema.Namespace) {
  187.                     throw new XmlSchemaInferenceException(Res.SchInf_schema, 0, 0);
  188.                 }
  189.                 XmlSchemaElement xse = null;
  190.                 foreach (XmlSchemaElement elem in schemas.GlobalElements.Values) {
  191.                     if (elem.Name == xtr.LocalName && elem.QualifiedName.Namespace == xtr.NamespaceURI) {
  192.                         rootSchema = elem.Parent as XmlSchema;
  193.                         xse = elem;
  194.                         break;
  195.                     }
  196.                 }
  197.                
  198.                 if (rootSchema == null) {
  199.                     //rootSchema = CreateXmlSchema(xtr.NamespaceURI);
  200.                     xse = AddElement(xtr.LocalName, xtr.Prefix, xtr.NamespaceURI, null, null, -1);
  201.                 }
  202.                 else {
  203.                     //bRefine = true;
  204.                     InferElement(xse, false, rootSchema);
  205.                 }
  206.                
  207.                 /*  foreach (ReplaceList listItem in schemaList)
  208.                     {
  209.                         if (listItem.position < listItem.col.Count)
  210.                         {
  211.                             XmlSchemaElement particle = listItem.col[listItem.position] as XmlSchemaElement;
  212.                             if (particle != null && (particle.RefName.Namespace == XmlSchema.Namespace))
  213.                             {
  214.                                 XmlSchemaAny any = new XmlSchemaAny();
  215.                                 if (particle.MaxOccurs != 1)
  216.                                 {
  217.                                     any.MaxOccurs = particle.MaxOccurs;
  218.                                 }
  219.                                 if (particle.MinOccurs != 1)
  220.                                 {
  221.                                     any.MinOccurs = particle.MinOccurs;
  222.                                 }
  223.                                 any.ProcessContents = XmlSchemaContentProcessing.Skip;
  224.                                 any.MinOccurs = decimal.Zero;
  225.                                 any.Namespace = particle.RefName.Namespace;
  226.                                 listItem.col[listItem.position] = any;
  227.                             }
  228.                         }
  229.                     }*/               
  230. foreach (string prefix in this.NamespaceManager) {
  231.                     if (!prefix.Equals("xml") && !prefix.Equals("xmlns")) {
  232.                         string ns = this.NamespaceManager.LookupNamespace(this.nametable.Get(prefix));
  233.                         if (ns.Length != 0) {
  234.                             //Do not add xmlns=""
  235.                             rootSchema.Namespaces.Add(prefix, ns);
  236.                         }
  237.                     }
  238.                 }
  239.                 Debug.Assert(this.rootSchema != null, "rootSchema is null");
  240.                 schemas.Reprocess(rootSchema);
  241.                 schemas.Compile();
  242.                 //break;
  243.             }
  244.             else {
  245.                 throw new XmlSchemaInferenceException(Res.SchInf_NoElement, 0, 0);
  246.             }
  247.             return schemas;
  248.         }
  249.        
  250.         private XmlSchemaAttribute AddAttribute(string localName, string prefix, string childURI, string attrValue, bool bCreatingNewType, XmlSchema parentSchema, XmlSchemaObjectCollection addLocation, XmlSchemaObjectTable compiledAttributes)
  251.         {
  252.             if (childURI == XmlSchema.Namespace) {
  253.                 throw new XmlSchemaInferenceException(Res.SchInf_schema, 0, 0);
  254.             }
  255.            
  256.             XmlSchemaAttribute xsa = null;
  257.             int AttributeType = -1;
  258.             XmlSchemaAttribute returnedAttribute = null;
  259.             //this value will change to attributeReference if childURI!= parentURI
  260.             XmlSchema xs = null;
  261.             bool add = true;
  262.            
  263.             Debug.Assert(compiledAttributes != null);
  264.             //AttributeUses is never null
  265.             ICollection searchCollection;
  266.             if (compiledAttributes.Count > 0) {
  267.                 searchCollection = compiledAttributes.Values;
  268.             }
  269.             else {
  270.                 searchCollection = addLocation;
  271.             }
  272.             if (childURI == "http://www.w3.org/XML/1998/namespace") {
  273.                 XmlSchemaAttribute attributeReference = null;
  274.                 //see if the reference exists
  275.                 attributeReference = FindAttributeRef(searchCollection, localName, childURI);
  276.                 if (attributeReference == null) {
  277.                     attributeReference = new XmlSchemaAttribute();
  278.                     attributeReference.RefName = new XmlQualifiedName(localName, childURI);
  279.                     if (bCreatingNewType && this.Occurrence == InferenceOption.Restricted) {
  280.                         attributeReference.Use = XmlSchemaUse.Required;
  281.                     }
  282.                     else {
  283.                         attributeReference.Use = XmlSchemaUse.Optional;
  284.                     }
  285.                    
  286.                     addLocation.Add(attributeReference);
  287.                 }
  288.                 returnedAttribute = attributeReference;
  289.             }
  290.             else {
  291.                 if (childURI.Length == 0) {
  292.                     xs = parentSchema;
  293.                     add = false;
  294.                 }
  295.                 else if (childURI != null && !schemaSet.Contains(childURI)) {
  296.                     /*if (parentSchema.AttributeFormDefault = XmlSchemaForm.Unqualified && childURI.Length == 0)
  297.                     {
  298.                         xs = parentSchema;
  299.                         add = false;
  300.                         break;
  301.                     }*/                   
  302. xs = new XmlSchema();
  303.                     xs.AttributeFormDefault = XmlSchemaForm.Unqualified;
  304.                     xs.ElementFormDefault = XmlSchemaForm.Qualified;
  305.                     if (childURI.Length != 0)
  306.                         xs.TargetNamespace = childURI;
  307.                     //schemas.Add(childURI, xs);
  308.                     this.schemaSet.Add(xs);
  309.                     if (prefix.Length != 0 && String.Compare(prefix, "xml", StringComparison.OrdinalIgnoreCase) != 0)
  310.                         NamespaceManager.AddNamespace(prefix, childURI);
  311.                 }
  312.                 else {
  313.                     ArrayList col = this.schemaSet.Schemas(childURI) as ArrayList;
  314.                     if (col != null && col.Count > 0) {
  315.                         xs = col[0] as XmlSchema;
  316.                     }
  317.                    
  318.                 }
  319.                 if (childURI.Length != 0) {
  320.                     XmlSchemaAttribute attributeReference = null;
  321.                     //see if the reference exists
  322.                     attributeReference = FindAttributeRef(searchCollection, localName, childURI);
  323.                     if (attributeReference == null) {
  324.                         attributeReference = new XmlSchemaAttribute();
  325.                         attributeReference.RefName = new XmlQualifiedName(localName, childURI);
  326.                         if (bCreatingNewType && this.Occurrence == InferenceOption.Restricted) {
  327.                             attributeReference.Use = XmlSchemaUse.Required;
  328.                         }
  329.                         else {
  330.                             attributeReference.Use = XmlSchemaUse.Optional;
  331.                         }
  332.                        
  333.                         addLocation.Add(attributeReference);
  334.                     }
  335.                     returnedAttribute = attributeReference;
  336.                    
  337.                     //see if the attribute exists on the global level
  338.                     xsa = FindAttribute(xs.Items, localName);
  339.                     if (xsa == null) {
  340.                         xsa = new XmlSchemaAttribute();
  341.                         xsa.Name = localName;
  342.                         xsa.SchemaTypeName = RefineSimpleType(attrValue, ref AttributeType);
  343.                         xsa.LineNumber = AttributeType;
  344.                         //we use LineNumber to store flags of valid types
  345.                         xs.Items.Add(xsa);
  346.                        
  347.                     }
  348.                     else {
  349.                         if (xsa.Parent == null) {
  350.                             AttributeType = xsa.LineNumber;
  351.                             // we use LineNumber to store flags of valid types
  352.                         }
  353.                         else {
  354.                             AttributeType = GetSchemaType(xsa.SchemaTypeName);
  355.                             xsa.Parent = null;
  356.                         }
  357.                         xsa.SchemaTypeName = RefineSimpleType(attrValue, ref AttributeType);
  358.                         xsa.LineNumber = AttributeType;
  359.                         // we use LineNumber to store flags of valid types
  360.                     }
  361.                 }
  362.                 else {
  363.                     xsa = FindAttribute(searchCollection, localName);
  364.                     if (xsa == null) {
  365.                         xsa = new XmlSchemaAttribute();
  366.                         xsa.Name = localName;
  367.                         xsa.SchemaTypeName = RefineSimpleType(attrValue, ref AttributeType);
  368.                         xsa.LineNumber = AttributeType;
  369.                         // we use LineNumber to store flags of valid types
  370.                         if (bCreatingNewType && this.Occurrence == InferenceOption.Restricted)
  371.                             xsa.Use = XmlSchemaUse.Required;
  372.                         else
  373.                             xsa.Use = XmlSchemaUse.Optional;
  374.                         addLocation.Add(xsa);
  375.                         if (xs.AttributeFormDefault != XmlSchemaForm.Unqualified) {
  376.                             xsa.Form = XmlSchemaForm.Unqualified;
  377.                         }
  378.                     }
  379.                     else {
  380.                         if (xsa.Parent == null) {
  381.                             AttributeType = xsa.LineNumber;
  382.                             // we use LineNumber to store flags of valid types
  383.                         }
  384.                         else {
  385.                             AttributeType = GetSchemaType(xsa.SchemaTypeName);
  386.                             xsa.Parent = null;
  387.                         }
  388.                         xsa.SchemaTypeName = RefineSimpleType(attrValue, ref AttributeType);
  389.                         xsa.LineNumber = AttributeType;
  390.                         // we use LineNumber to store flags of valid types
  391.                     }
  392.                     returnedAttribute = xsa;
  393.                 }
  394.             }
  395.             string nullString = null;
  396.             if (add && childURI != parentSchema.TargetNamespace) {
  397.                 foreach (XmlSchemaExternal external in parentSchema.Includes) {
  398.                     XmlSchemaImport import = external as XmlSchemaImport;
  399.                     if (import == null) {
  400.                         continue;
  401.                     }
  402.                     if (import.Namespace == childURI) {
  403.                         add = false;
  404.                     }
  405.                 }
  406.                 if (add) {
  407.                     XmlSchemaImport import = new XmlSchemaImport();
  408.                     import.Schema = xs;
  409.                     if (childURI.Length != 0) {
  410.                         nullString = childURI;
  411.                     }
  412.                     import.Namespace = nullString;
  413.                     parentSchema.Includes.Add(import);
  414.                 }
  415.             }
  416.            
  417.            
  418.             return returnedAttribute;
  419.         }
  420.        
  421.         private XmlSchema CreateXmlSchema(string targetNS)
  422.         {
  423.             Debug.Assert(targetNS == null || targetNS.Length > 0, "targetns for schema is empty");
  424.             XmlSchema xs = new XmlSchema();
  425.             xs.AttributeFormDefault = XmlSchemaForm.Unqualified;
  426.             xs.ElementFormDefault = XmlSchemaForm.Qualified;
  427.             xs.TargetNamespace = targetNS;
  428.             this.schemaSet.Add(xs);
  429.             return xs;
  430.         }
  431.        
  432.         private XmlSchemaElement AddElement(string localName, string prefix, string childURI, XmlSchema parentSchema, XmlSchemaObjectCollection addLocation, int positionWithinCollection)
  433.         {
  434.             if (childURI == XmlSchema.Namespace) {
  435.                 throw new XmlSchemaInferenceException(Res.SchInf_schema, 0, 0);
  436.             }
  437.            
  438.             XmlSchemaElement xse = null;
  439.             XmlSchemaElement returnedElement = xse;
  440.             //this value will change to elementReference if childURI!= parentURI
  441.             XmlSchema xs = null;
  442.             bool bCreatingNewType = true;
  443.             if (childURI == String.Empty) {
  444.                 childURI = null;
  445.             }
  446.             // The new element belongs to the same ns as parent and addlocation is not null
  447.             if (parentSchema != null && childURI == parentSchema.TargetNamespace) {
  448.                 xse = new XmlSchemaElement();
  449.                 xse.Name = localName;
  450.                 xs = parentSchema;
  451.                 if (xs.ElementFormDefault != XmlSchemaForm.Qualified && addLocation != null) {
  452.                     xse.Form = XmlSchemaForm.Qualified;
  453.                 }
  454.             }
  455.             else if (schemaSet.Contains(childURI)) {
  456.                 xse = this.FindGlobalElement(childURI, localName, out xs);
  457.                 if (xse == null) {
  458.                     ArrayList col = this.schemaSet.Schemas(childURI) as ArrayList;
  459.                     if (col != null && col.Count > 0) {
  460.                         xs = col[0] as XmlSchema;
  461.                     }
  462.                     xse = new XmlSchemaElement();
  463.                     xse.Name = localName;
  464.                     xs.Items.Add(xse);
  465.                 }
  466.                 else
  467.                     bCreatingNewType = false;
  468.                
  469.             }
  470.             else {
  471.                 xs = CreateXmlSchema(childURI);
  472.                 if (prefix.Length != 0)
  473.                     NamespaceManager.AddNamespace(prefix, childURI);
  474.                 xse = new XmlSchemaElement();
  475.                 xse.Name = localName;
  476.                 xs.Items.Add(xse);
  477.                 //add global element declaration only when creating new schema
  478.             }
  479.             if (parentSchema == null) {
  480.                 parentSchema = xs;
  481.                 this.rootSchema = parentSchema;
  482.             }
  483.            
  484.             if (childURI != parentSchema.TargetNamespace) {
  485.                 bool add = true;
  486.                
  487.                 foreach (XmlSchemaExternal external in parentSchema.Includes) {
  488.                     XmlSchemaImport import = external as XmlSchemaImport;
  489.                     if (import == null) {
  490.                         continue;
  491.                     }
  492.                     //Debug.WriteLine(import.Schema.TargetNamespace);
  493.                    
  494.                     if (import.Namespace == childURI) {
  495.                         add = false;
  496.                     }
  497.                 }
  498.                 if (add) {
  499.                     XmlSchemaImport import = new XmlSchemaImport();
  500.                     import.Schema = xs;
  501.                     import.Namespace = childURI;
  502.                     parentSchema.Includes.Add(import);
  503.                 }
  504.             }
  505.             returnedElement = xse;
  506.             if (addLocation != null) {
  507.                 if (childURI == parentSchema.TargetNamespace) {
  508.                     if (this.Occurrence == InferenceOption.Relaxed)/*&& parentSchema.Items != addLocation*/ {
  509.                         xse.MinOccurs = 0;
  510.                     }
  511.                     if (positionWithinCollection == -1) {
  512.                         positionWithinCollection = addLocation.Add(xse);
  513.                     }
  514.                     else {
  515.                         addLocation.Insert(positionWithinCollection, xse);
  516.                     }
  517.                 }
  518.                 else {
  519.                     XmlSchemaElement elementReference = new XmlSchemaElement();
  520.                     elementReference.RefName = new XmlQualifiedName(localName, childURI);
  521.                     if (this.Occurrence == InferenceOption.Relaxed) {
  522.                         elementReference.MinOccurs = 0;
  523.                     }
  524.                     if (positionWithinCollection == -1) {
  525.                         positionWithinCollection = addLocation.Add(elementReference);
  526.                     }
  527.                     else {
  528.                         addLocation.Insert(positionWithinCollection, elementReference);
  529.                     }
  530.                     returnedElement = elementReference;
  531.                     /* if (childURI == XmlSchema.Namespace)
  532.                         {
  533.                             schemaList.Add(new ReplaceList(addLocation, positionWithinCollection));
  534.                         }*/                   
  535.                 }
  536.             }
  537.            
  538.            
  539.             InferElement(xse, bCreatingNewType, xs);
  540.            
  541.             return returnedElement;
  542.         }
  543.        
  544.         /// <summary>
  545.         /// Sets type of the xse based on the currently read element.
  546.         /// If the type is already set, verifies that it matches the instance and if not, updates the type to validate the instance.
  547.         /// </summary>
  548.         /// <param name="xse">XmlSchemaElement corresponding to the element just read by the xtr XmlTextReader</param>
  549.         /// <param name="bCreatingNewType">true if the type is newly created, false if the type already existed and matches the current element name</param>
  550.         /// <param name="nsContext">namespaceURI of the parent element. Used to distinguish if ref= should be used when parent is in different ns than child.</param>
  551.         internal void InferElement(XmlSchemaElement xse, bool bCreatingNewType, XmlSchema parentSchema)
  552.         {
  553.            
  554.             bool bEmptyElement = xtr.IsEmptyElement;
  555.             int lastUsedSeqItem = -1;
  556.            
  557.             Hashtable table = new Hashtable();
  558.             XmlSchemaType schemaType = GetEffectiveSchemaType(xse, bCreatingNewType);
  559.             XmlSchemaComplexType ct = schemaType as XmlSchemaComplexType;
  560.            
  561.             //infer type based on content of the current element
  562.             if (xtr.MoveToFirstAttribute()) {
  563.                 ProcessAttributes(ref xse, schemaType, bCreatingNewType, parentSchema);
  564.             }
  565.             else {
  566.                 if (!bCreatingNewType && ct != null) {
  567.                     //if type already exists and can potentially have attributes
  568.                     MakeExistingAttributesOptional(ct, null);
  569.                 }
  570.             }
  571.             if (ct == null || ct == XmlSchemaComplexType.AnyType) {
  572.                 //It was null or simple type, after processing attributes, this might have been set
  573.                 ct = xse.SchemaType as XmlSchemaComplexType;
  574.             }
  575.             //xse's type is set either to complex type if attributes exist or null
  576.             //<element attr="3232" />
  577.             if (bEmptyElement) {
  578.                 if (!bCreatingNewType) {
  579.                     if (null != ct) {
  580.                        
  581.                         if (null != ct.Particle) {
  582.                             ct.Particle.MinOccurs = 0;
  583.                         }
  584.                         else if (null != ct.ContentModel) {
  585.                             XmlSchemaSimpleContentExtension sce = CheckSimpleContentExtension(ct);
  586.                             sce.BaseTypeName = ST_string;
  587.                             sce.LineNumber = TF_string;
  588.                         }
  589.                     }
  590.                     else if (!xse.SchemaTypeName.IsEmpty) {
  591.                         xse.LineNumber = TF_string;
  592.                         xse.SchemaTypeName = ST_string;
  593.                     }
  594.                 }
  595.                 else {
  596.                     xse.LineNumber = TF_string;
  597.                     //xse.SchemaTypeName = ST_string; //My change
  598.                 }
  599.                 return;
  600.                 //We are done processing this element - all attributes are already added
  601.             }
  602.             bool bWhiteSpace = false;
  603.             do {
  604.                 xtr.Read();
  605.                 if (xtr.NodeType == XmlNodeType.Whitespace) {
  606.                     bWhiteSpace = true;
  607.                 }
  608.                 if (xtr.NodeType == XmlNodeType.EntityReference) {
  609.                     throw new XmlSchemaInferenceException(Res.SchInf_entity, 0, 0);
  610.                 }
  611.             }
  612.             while ((!xtr.EOF) && (xtr.NodeType != XmlNodeType.EndElement) && (xtr.NodeType != XmlNodeType.CDATA) && (xtr.NodeType != XmlNodeType.Element) && (xtr.NodeType != XmlNodeType.Text));
  613.            
  614.             if (xtr.NodeType == XmlNodeType.EndElement) {
  615.                 if (bWhiteSpace) {
  616.                     if (ct != null) {
  617.                         if (null != ct.ContentModel) {
  618.                             XmlSchemaSimpleContentExtension sce = CheckSimpleContentExtension(ct);
  619.                             sce.BaseTypeName = ST_string;
  620.                             sce.LineNumber = TF_string;
  621.                         }
  622.                         else if (bCreatingNewType) {
  623.                             //attributes exist, but both Particle and ContentModel == null - this must be complex type with simpleContent extension
  624.                             XmlSchemaSimpleContent sc = new XmlSchemaSimpleContent();
  625.                             ct.ContentModel = sc;
  626.                             XmlSchemaSimpleContentExtension sce = new XmlSchemaSimpleContentExtension();
  627.                             sc.Content = sce;
  628.                            
  629.                             MoveAttributes(ct, sce, bCreatingNewType);
  630.                            
  631.                             sce.BaseTypeName = ST_string;
  632.                             sce.LineNumber = TF_string;
  633.                         }
  634.                         else
  635.                             ct.IsMixed = true;
  636.                     }
  637.                     else {
  638.                         xse.SchemaTypeName = ST_string;
  639.                         xse.LineNumber = TF_string;
  640.                     }
  641.                 }
  642.                 if (bCreatingNewType) {
  643.                     xse.LineNumber = TF_string;
  644.                     //xse.SchemaTypeName = ST_string; //my change
  645.                 }
  646.                 else {
  647.                     if (null != ct) {
  648.                         if (null != ct.Particle) {
  649.                             ct.Particle.MinOccurs = 0;
  650.                         }
  651.                         else if (null != ct.ContentModel) {
  652.                             XmlSchemaSimpleContentExtension sce = CheckSimpleContentExtension(ct);
  653.                             sce.BaseTypeName = ST_string;
  654.                             sce.LineNumber = TF_string;
  655.                         }
  656.                     }
  657.                     else if (!xse.SchemaTypeName.IsEmpty) {
  658.                         xse.LineNumber = TF_string;
  659.                         xse.SchemaTypeName = ST_string;
  660.                     }
  661.                 }
  662.                
  663.                 return;
  664.                 //<element attr="232"></element>
  665.             }
  666.             int iChildNumber = 0;
  667.             bool bCreatingNewSequence = false;
  668.             while (!xtr.EOF && (xtr.NodeType != XmlNodeType.EndElement)) {
  669.                 bool bNextNodeAlreadyRead = false;
  670.                 //In some cases we have to look ahead one node. If true means that we did look ahead.
  671.                 iChildNumber++;
  672.                 //node can be simple type, complex with simple content or complex with mixed content
  673.                 if ((xtr.NodeType == XmlNodeType.Text) || (xtr.NodeType == XmlNodeType.CDATA)) {
  674.                     if (null != ct) {
  675.                         if (null != ct.Particle) {
  676.                             ct.IsMixed = true;
  677.                             if (iChildNumber == 1) {
  678.                                 //if this is the only child and other elements do not follow, we must set particle minOccurs="0"
  679.                                 do {
  680.                                     xtr.Read();
  681.                                 }
  682.                                 while ((!xtr.EOF) && ((xtr.NodeType == XmlNodeType.CDATA) || (xtr.NodeType == XmlNodeType.Text) || (xtr.NodeType == XmlNodeType.Comment) || (xtr.NodeType == XmlNodeType.ProcessingInstruction) || (xtr.NodeType == XmlNodeType.Whitespace) || (xtr.NodeType == XmlNodeType.SignificantWhitespace) || (xtr.NodeType == XmlNodeType.XmlDeclaration)));
  683.                                 bNextNodeAlreadyRead = true;
  684.                                 if (xtr.NodeType == XmlNodeType.EndElement)
  685.                                     ct.Particle.MinOccurs = decimal.Zero;
  686.                             }
  687.                         }
  688.                         else if (null != ct.ContentModel) {
  689.                             //complexType with simpleContent
  690.                             XmlSchemaSimpleContentExtension sce = CheckSimpleContentExtension(ct);
  691.                             if ((xtr.NodeType == XmlNodeType.Text) && (iChildNumber == 1)) {
  692.                                 int SimpleType = -1;
  693.                                 if (xse.Parent == null) {
  694.                                     SimpleType = sce.LineNumber;
  695.                                     // we use LineNumber to represent valid type flags
  696.                                 }
  697.                                 else {
  698.                                     SimpleType = GetSchemaType(sce.BaseTypeName);
  699.                                     xse.Parent = null;
  700.                                 }
  701.                                 sce.BaseTypeName = RefineSimpleType(xtr.Value, ref SimpleType);
  702.                                 sce.LineNumber = SimpleType;
  703.                                 // we use LineNumber to represent valid type flags
  704.                             }
  705.                             else {
  706.                                 sce.BaseTypeName = ST_string;
  707.                                 sce.LineNumber = TF_string;
  708.                             }
  709.                         }
  710.                         else {
  711.                             //attributes exist, but both Particle and ContentModel == null - this must be complex type with simpleContent extension
  712.                             XmlSchemaSimpleContent sc = new XmlSchemaSimpleContent();
  713.                             ct.ContentModel = sc;
  714.                             XmlSchemaSimpleContentExtension sce = new XmlSchemaSimpleContentExtension();
  715.                             sc.Content = sce;
  716.                            
  717.                             MoveAttributes(ct, sce, bCreatingNewType);
  718.                            
  719.                             if (xtr.NodeType == XmlNodeType.Text) {
  720.                                 int TypeFlags;
  721.                                 if (!bCreatingNewType)
  722.                                     TypeFlags = TF_string;
  723.                                 else
  724.                                     //previously this was empty element
  725.                                     TypeFlags = -1;
  726.                                 sce.BaseTypeName = RefineSimpleType(xtr.Value, ref TypeFlags);
  727.                                 sce.LineNumber = TypeFlags;
  728.                                 // we use LineNumber to store flags of valid types
  729.                             }
  730.                             else {
  731.                                 sce.BaseTypeName = ST_string;
  732.                                 sce.LineNumber = TF_string;
  733.                             }
  734.                            
  735.                         }
  736.                     }
  737.                     else {
  738.                         //node is currently empty or with SimpleType
  739.                         //node will become simple type
  740.                         if (iChildNumber > 1) {
  741.                             //more than one consecutive text nodes probably with PI in between
  742.                             xse.SchemaTypeName = ST_string;
  743.                             xse.LineNumber = TF_string;
  744.                             // we use LineNumber to store flags of valid types
  745.                         }
  746.                         else {
  747.                             int TypeFlags = -1;
  748.                             if (bCreatingNewType)
  749.                                 if (xtr.NodeType == XmlNodeType.Text) {
  750.                                     xse.SchemaTypeName = RefineSimpleType(xtr.Value, ref TypeFlags);
  751.                                     xse.LineNumber = TypeFlags;
  752.                                     // we use LineNumber to store flags of valid types
  753.                                 }
  754.                                 else {
  755.                                     xse.SchemaTypeName = ST_string;
  756.                                     xse.LineNumber = TF_string;
  757.                                     // we use LineNumber to store flags of valid types
  758.                                 }
  759.                             else if (xtr.NodeType == XmlNodeType.Text) {
  760.                                 if (xse.Parent == null) {
  761.                                     TypeFlags = xse.LineNumber;
  762.                                 }
  763.                                 else {
  764.                                     TypeFlags = GetSchemaType(xse.SchemaTypeName);
  765.                                     if (TypeFlags == -1 && xse.LineNumber == TF_string) {
  766.                                         //Since schemaTypeName is not set for empty elements (<e></e>)
  767.                                         TypeFlags = TF_string;
  768.                                     }
  769.                                     xse.Parent = null;
  770.                                 }
  771.                                 xse.SchemaTypeName = RefineSimpleType(xtr.Value, ref TypeFlags);
  772.                                 //simple type
  773.                                 xse.LineNumber = TypeFlags;
  774.                                 // we use LineNumber to store flags of valid types
  775.                             }
  776.                             else {
  777.                                 xse.SchemaTypeName = ST_string;
  778.                                 xse.LineNumber = TF_string;
  779.                                 // we use LineNumber to store flags of valid types
  780.                             }
  781.                         }
  782.                     }
  783.                 }
  784.                 else if (xtr.NodeType == XmlNodeType.Element) {
  785.                     XmlQualifiedName qname = new XmlQualifiedName(xtr.LocalName, xtr.NamespaceURI);
  786.                     bool Maxoccursflag = false;
  787.                     if (table.Contains(qname)) {
  788.                         Maxoccursflag = true;
  789.                     }
  790.                     else {
  791.                         table.Add(qname, null);
  792.                     }
  793.                     if (ct == null) {
  794.                         //untill now the element was empty or SimpleType - it now becomes complex type
  795.                         ct = new XmlSchemaComplexType();
  796.                         xse.SchemaType = ct;
  797.                         if (!xse.SchemaTypeName.IsEmpty) {
  798.                             ct.IsMixed = true;
  799.                             xse.SchemaTypeName = XmlQualifiedName.Empty;
  800.                         }
  801.                     }
  802.                     if (ct.ContentModel != null) {
  803.                         //type was previously identified as simple content extension - we need to convert it to sequence
  804.                         XmlSchemaSimpleContentExtension sce = CheckSimpleContentExtension(ct);
  805.                         MoveAttributes(sce, ct);
  806.                         ct.ContentModel = null;
  807.                         ct.IsMixed = true;
  808.                         if (ct.Particle != null)
  809.                             throw new XmlSchemaInferenceException(Res.SchInf_particle, 0, 0);
  810.                         ct.Particle = new XmlSchemaSequence();
  811.                         bCreatingNewSequence = true;
  812.                         XmlSchemaElement subelement = AddElement(xtr.LocalName, xtr.Prefix, xtr.NamespaceURI, parentSchema, ((XmlSchemaSequence)ct.Particle).Items, -1);
  813.                         lastUsedSeqItem = 0;
  814.                         if (!bCreatingNewType)
  815.                             ct.Particle.MinOccurs = 0;
  816.                         //previously this was simple type so subelements did not exist
  817.                     }
  818.                     else if (ct.Particle == null) {
  819.                         ct.Particle = new XmlSchemaSequence();
  820.                         bCreatingNewSequence = true;
  821.                         XmlSchemaElement subelement = AddElement(xtr.LocalName, xtr.Prefix, xtr.NamespaceURI, parentSchema, ((XmlSchemaSequence)ct.Particle).Items, -1);
  822.                         if (!bCreatingNewType) {
  823.                             ((XmlSchemaSequence)ct.Particle).MinOccurs = decimal.Zero;
  824.                             // subelement.MinOccurs = decimal.Zero;
  825.                         }
  826.                        
  827.                         lastUsedSeqItem = 0;
  828.                     }
  829.                     else {
  830.                         bool bParticleChanged = false;
  831.                         XmlSchemaElement subelement = FindMatchingElement(bCreatingNewType || bCreatingNewSequence, xtr, ct, ref lastUsedSeqItem, ref bParticleChanged, parentSchema, Maxoccursflag);
  832.                     }
  833.                 }
  834.                 else if (xtr.NodeType == XmlNodeType.Text) {
  835.                     if (ct == null)
  836.                         throw new XmlSchemaInferenceException(Res.SchInf_ct, 0, 0);
  837.                     ct.IsMixed = true;
  838.                 }
  839.                 do {
  840.                     if (xtr.NodeType == XmlNodeType.EntityReference) {
  841.                         throw new XmlSchemaInferenceException(Res.SchInf_entity, 0, 0);
  842.                        
  843.                     }
  844.                     if (!bNextNodeAlreadyRead) {
  845.                         xtr.Read();
  846.                     }
  847.                     else {
  848.                         bNextNodeAlreadyRead = false;
  849.                     }
  850.                 }
  851.                 while ((!xtr.EOF) && (xtr.NodeType != XmlNodeType.EndElement) && (xtr.NodeType != XmlNodeType.CDATA) && (xtr.NodeType != XmlNodeType.Element) && (xtr.NodeType != XmlNodeType.Text));
  852.             }
  853.             if (lastUsedSeqItem != -1) {
  854.                 //Verify if all elements in a sequence exist, if not set MinOccurs=0
  855.                 while (++lastUsedSeqItem < ((XmlSchemaSequence)ct.Particle).Items.Count) {
  856.                     if (((XmlSchemaSequence)ct.Particle).Items[lastUsedSeqItem].GetType() != typeof(XmlSchemaElement))
  857.                         throw new XmlSchemaInferenceException(Res.SchInf_seq, 0, 0);
  858.                     XmlSchemaElement subElement = (XmlSchemaElement)((XmlSchemaSequence)ct.Particle).Items[lastUsedSeqItem];
  859.                     subElement.MinOccurs = 0;
  860.                 }
  861.             }
  862.            
  863.         }
  864.        
  865.         private XmlSchemaSimpleContentExtension CheckSimpleContentExtension(XmlSchemaComplexType ct)
  866.         {
  867.             XmlSchemaSimpleContent sc = ct.ContentModel as XmlSchemaSimpleContent;
  868.             if (sc == null) {
  869.                 throw new XmlSchemaInferenceException(Res.SchInf_simplecontent, 0, 0);
  870.             }
  871.             XmlSchemaSimpleContentExtension sce = sc.Content as XmlSchemaSimpleContentExtension;
  872.             if (sce == null) {
  873.                 throw new XmlSchemaInferenceException(Res.SchInf_extension, 0, 0);
  874.             }
  875.             return sce;
  876.         }
  877.        
  878.         private XmlSchemaType GetEffectiveSchemaType(XmlSchemaElement elem, bool bCreatingNewType)
  879.         {
  880.             XmlSchemaType effectiveSchemaType = null;
  881.             if (!bCreatingNewType && elem.ElementSchemaType != null) {
  882.                 effectiveSchemaType = elem.ElementSchemaType;
  883.             }
  884.             else {
  885.                 //creating new type, hence look up pre-compiled info
  886.                 Debug.Assert(elem.ElementDecl == null);
  887.                 if (elem.SchemaType != null) {
  888.                     effectiveSchemaType = elem.SchemaType;
  889.                 }
  890.                 else if (elem.SchemaTypeName != XmlQualifiedName.Empty) {
  891.                     effectiveSchemaType = schemaSet.GlobalTypes[elem.SchemaTypeName] as XmlSchemaType;
  892.                     if (effectiveSchemaType == null) {
  893.                         effectiveSchemaType = XmlSchemaType.GetBuiltInSimpleType(elem.SchemaTypeName);
  894.                     }
  895.                     if (effectiveSchemaType == null) {
  896.                         effectiveSchemaType = XmlSchemaType.GetBuiltInComplexType(elem.SchemaTypeName);
  897.                     }
  898.                 }
  899.             }
  900.             return effectiveSchemaType;
  901.         }
  902.         /// <summary>
  903.         /// Verifies that the current element has its corresponding element in the sequence and order is the same.
  904.         /// If the order is not the same, it changes the particle from Sequence to Sequence with Choice.
  905.         /// If there is more elements of the same kind in the sequence, sets maxOccurs to unbounded
  906.         /// </summary>
  907.         /// <param name="bCreatingNewType">True if this is a new type. This is important for setting minOccurs=0 for elements that did not exist in a particle.</param>
  908.         /// <param name="xtr">text reader positioned to the current element</param>
  909.         /// <param name="ct">complex type with Sequence or Choice Particle</param>
  910.         /// <param name="lastUsedSeqItem">ordinal number in the sequence to indicate current sequence position</param>
  911.         /// <param name="itemsMadeOptional">hashtable of elements with minOccurs changed to 0 in order to satisfy sequence requirements. These elements will be rolled back if Sequence becomes Sequence of Choice.</param>
  912.         /// <param name="bParticleChanged">This indicates to the caller if Sequence was changed to Choice</param>
  913.         internal XmlSchemaElement FindMatchingElement(bool bCreatingNewType, XmlReader xtr, XmlSchemaComplexType ct, ref int lastUsedSeqItem, ref bool bParticleChanged, XmlSchema parentSchema, bool setMaxoccurs)
  914.         {
  915.             if (xtr.NamespaceURI == XmlSchema.Namespace) {
  916.                 throw new XmlSchemaInferenceException(Res.SchInf_schema, 0, 0);
  917.             }
  918.            
  919.             bool bItemNotUsedYet = ((lastUsedSeqItem == -1) ? true : false);
  920.             XmlSchemaObjectCollection minOccursCandidates = new XmlSchemaObjectCollection();
  921.             //elements that are skipped in the sequence and need minOccurs modified.
  922.             if (ct.Particle.GetType() == typeof(XmlSchemaSequence)) {
  923.                 string childURI = xtr.NamespaceURI;
  924.                 if (childURI.Length == 0) {
  925.                     childURI = null;
  926.                 }
  927.                 XmlSchemaSequence xss = (XmlSchemaSequence)ct.Particle;
  928.                 if (xss.Items.Count < 1 && !bCreatingNewType) {
  929.                     lastUsedSeqItem = 0;
  930.                     XmlSchemaElement e = AddElement(xtr.LocalName, xtr.Prefix, xtr.NamespaceURI, parentSchema, xss.Items, -1);
  931.                     e.MinOccurs = 0;
  932.                     return e;
  933.                 }
  934.                 if (xss.Items[0].GetType() == typeof(XmlSchemaChoice)) {
  935.                     // <sequence minOccurs="0" maxOccurs="unbounded"><choice><element>...</choice></sequence>
  936.                     XmlSchemaChoice xsch = (XmlSchemaChoice)xss.Items[0];
  937.                     foreach (XmlSchemaParticle particle in xsch.Items) {
  938.                         XmlSchemaElement el = particle as XmlSchemaElement;
  939.                         if (el == null) {
  940.                             throw new XmlSchemaInferenceException(Res.SchInf_UnknownParticle, 0, 0);
  941.                         }
  942.                         if ((el.Name == xtr.LocalName) && (parentSchema.TargetNamespace == childURI)) {
  943.                             // element is in the same namespace
  944.                             InferElement(el, false, parentSchema);
  945.                             SetMinMaxOccurs(el, setMaxoccurs);
  946.                             return el;
  947.                         }
  948.                         else if ((el.RefName.Name == xtr.LocalName) && (el.RefName.Namespace == xtr.NamespaceURI)) {
  949.                             XmlSchemaElement referencedElement = FindGlobalElement(childURI, xtr.LocalName, out parentSchema);
  950.                             InferElement(referencedElement, false, parentSchema);
  951.                             SetMinMaxOccurs(el, setMaxoccurs);
  952.                             return referencedElement;
  953.                         }
  954.                     }
  955.                     XmlSchemaElement subElement = AddElement(xtr.LocalName, xtr.Prefix, xtr.NamespaceURI, parentSchema, xsch.Items, -1);
  956.                     return subElement;
  957.                 }
  958.                 else {
  959.                     //this should be sequence of elements
  960.                     int iSeqItem = 0;
  961.                     //iterator through schema sequence items
  962.                     if (lastUsedSeqItem >= 0)
  963.                         iSeqItem = lastUsedSeqItem;
  964.                     XmlSchemaParticle particle = xss.Items[iSeqItem] as XmlSchemaParticle;
  965.                     XmlSchemaElement el = particle as XmlSchemaElement;
  966.                     if (el == null) {
  967.                         throw new XmlSchemaInferenceException(Res.SchInf_UnknownParticle, 0, 0);
  968.                     }
  969.                     if (el.Name == xtr.LocalName && parentSchema.TargetNamespace == childURI) {
  970.                         if (!bItemNotUsedYet)
  971.                             //read: if item was already used one or more times
  972.                             el.MaxOccurs = decimal.MaxValue;
  973.                         //set it to unbounded
  974.                         lastUsedSeqItem = iSeqItem;
  975.                         InferElement(el, false, parentSchema);
  976.                         SetMinMaxOccurs(el, false);
  977.                         return el;
  978.                     }
  979.                     else if (el.RefName.Name == xtr.LocalName && el.RefName.Namespace == xtr.NamespaceURI) {
  980.                         if (!bItemNotUsedYet)
  981.                             //read: if item was already used one or more times
  982.                             el.MaxOccurs = decimal.MaxValue;
  983.                         //set it to unbounded
  984.                         lastUsedSeqItem = iSeqItem;
  985.                         XmlSchemaElement referencedElement = FindGlobalElement(childURI, xtr.LocalName, out parentSchema);
  986.                         InferElement(referencedElement, false, parentSchema);
  987.                         SetMinMaxOccurs(el, false);
  988.                         return el;
  989.                     }
  990.                     if (bItemNotUsedYet && el.MinOccurs != decimal.Zero)
  991.                         minOccursCandidates.Add(el);
  992.                     iSeqItem++;
  993.                     while (iSeqItem < xss.Items.Count) {
  994.                         particle = xss.Items[iSeqItem] as XmlSchemaParticle;
  995.                         el = particle as XmlSchemaElement;
  996.                         if (el == null) {
  997.                             throw new XmlSchemaInferenceException(Res.SchInf_UnknownParticle, 0, 0);
  998.                         }
  999.                         if (el.Name == xtr.LocalName && parentSchema.TargetNamespace == childURI) {
  1000.                             lastUsedSeqItem = iSeqItem;
  1001.                             foreach (XmlSchemaElement minOccursElement in minOccursCandidates)
  1002.                                 minOccursElement.MinOccurs = decimal.Zero;
  1003.                             InferElement(el, false, parentSchema);
  1004.                             SetMinMaxOccurs(el, setMaxoccurs);
  1005.                             return el;
  1006.                         }
  1007.                         else if (el.RefName.Name == xtr.LocalName && el.RefName.Namespace == xtr.NamespaceURI) {
  1008.                             lastUsedSeqItem = iSeqItem;
  1009.                             foreach (XmlSchemaElement minOccursElement in minOccursCandidates)
  1010.                                 minOccursElement.MinOccurs = decimal.Zero;
  1011.                             XmlSchemaElement referencedElement = FindGlobalElement(childURI, xtr.LocalName, out parentSchema);
  1012.                             InferElement(referencedElement, false, parentSchema);
  1013.                             SetMinMaxOccurs(el, setMaxoccurs);
  1014.                             return referencedElement;
  1015.                         }
  1016.                        
  1017.                        
  1018.                         minOccursCandidates.Add(el);
  1019.                         iSeqItem++;
  1020.                     }
  1021.                    
  1022.                     //element not found in the sequence order, if it is found out of order change Sequence of elements to Sequence of Choices otherwise insert into sequence as optional
  1023.                     XmlSchemaElement subElement = null;
  1024.                     XmlSchemaElement actualElement = null;
  1025.                    
  1026.                     if (parentSchema.TargetNamespace == childURI) {
  1027.                         subElement = FindElement(xss.Items, xtr.LocalName);
  1028.                         actualElement = subElement;
  1029.                     }
  1030.                     else {
  1031.                         subElement = FindElementRef(xss.Items, xtr.LocalName, xtr.NamespaceURI);
  1032.                         if (subElement != null) {
  1033.                             actualElement = FindGlobalElement(childURI, xtr.LocalName, out parentSchema);
  1034.                         }
  1035.                     }
  1036.                     if (null != subElement) {
  1037.                         XmlSchemaChoice xsc = new XmlSchemaChoice();
  1038.                         xsc.MaxOccurs = decimal.MaxValue;
  1039.                         SetMinMaxOccurs(subElement, setMaxoccurs);
  1040.                         InferElement(actualElement, false, parentSchema);
  1041.                         foreach (XmlSchemaElement copyElement in xss.Items) {
  1042.                             xsc.Items.Add(CreateNewElementforChoice(copyElement));
  1043.                         }
  1044.                         xss.Items.Clear();
  1045.                         xss.Items.Add(xsc);
  1046.                         return subElement;
  1047.                     }
  1048.                     else {
  1049.                         subElement = AddElement(xtr.LocalName, xtr.Prefix, xtr.NamespaceURI, parentSchema, xss.Items, ++lastUsedSeqItem);
  1050.                         if (!bCreatingNewType)
  1051.                             subElement.MinOccurs = decimal.Zero;
  1052.                         return subElement;
  1053.                     }
  1054.                 }
  1055.             }
  1056.             else {
  1057.                 throw new XmlSchemaInferenceException(Res.SchInf_noseq, 0, 0);
  1058.             }
  1059.            
  1060.         }
  1061.         internal void ProcessAttributes(ref XmlSchemaElement xse, XmlSchemaType effectiveSchemaType, bool bCreatingNewType, XmlSchema parentSchema)
  1062.         {
  1063.             XmlSchemaObjectCollection attributesSeen = new XmlSchemaObjectCollection();
  1064.             XmlSchemaComplexType ct = effectiveSchemaType as XmlSchemaComplexType;
  1065.            
  1066.             Debug.Assert(xtr.NodeType == XmlNodeType.Attribute);
  1067.             do {
  1068.                 if (xtr.NamespaceURI == XmlSchema.Namespace) {
  1069.                     throw new XmlSchemaInferenceException(Res.SchInf_schema, 0, 0);
  1070.                 }
  1071.                
  1072.                 if (xtr.NamespaceURI == "http://www.w3.org/2000/xmlns/") {
  1073.                     if (xtr.Prefix == "xmlns")
  1074.                         NamespaceManager.AddNamespace(xtr.LocalName, xtr.Value);
  1075.                 }
  1076.                 else if (xtr.NamespaceURI == "http://www.w3.org/2001/XMLSchema-instance") {
  1077.                     string localName = xtr.LocalName;
  1078.                     if (localName == "nil") {
  1079.                         xse.IsNillable = true;
  1080.                     }
  1081.                     else if (localName != "type" && localName != "schemaLocation" && localName != "noNamespaceSchemaLocation") {
  1082.                         throw new XmlSchemaInferenceException(Res.Sch_NotXsiAttribute, localName);
  1083.                     }
  1084.                 }
  1085.                 else {
  1086.                     if (ct == null || ct == XmlSchemaComplexType.AnyType) {
  1087.                         ct = new XmlSchemaComplexType();
  1088.                         xse.SchemaType = ct;
  1089.                     }
  1090.                    
  1091.                     XmlSchemaAttribute xsa = null;
  1092.                     //The earlier assumption of checking just schemaTypeName !Empty is not correct for schemas that are not generated by us, schemaTypeName can point to any complex type as well
  1093.                     //Check that it is a simple type by checking typeCode
  1094.                     //Switch to complex type simple content extension
  1095.                     if (effectiveSchemaType != null && effectiveSchemaType.Datatype != null && !xse.SchemaTypeName.IsEmpty) {
  1096.                         //type was previously simple type, now it will become complex with simple type extension
  1097.                         Debug.Assert(ct != null);
  1098.                         XmlSchemaSimpleContent sc = new XmlSchemaSimpleContent();
  1099.                         ct.ContentModel = sc;
  1100.                         XmlSchemaSimpleContentExtension sce = new XmlSchemaSimpleContentExtension();
  1101.                         sc.Content = sce;
  1102.                         sce.BaseTypeName = xse.SchemaTypeName;
  1103.                         sce.LineNumber = xse.LineNumber;
  1104.                         xse.LineNumber = 0;
  1105.                         xse.SchemaTypeName = XmlQualifiedName.Empty;
  1106.                         //re-set the name
  1107.                     }
  1108.                    
  1109.                     Debug.Assert(ct != null);
  1110.                     //either the user-defined type itself is a complex type or we switched from a simple type to a complex type
  1111.                     if (ct.ContentModel != null) {
  1112.                         XmlSchemaSimpleContentExtension sce = CheckSimpleContentExtension(ct);
  1113.                         Debug.Assert(sce != null);
  1114.                         xsa = AddAttribute(xtr.LocalName, xtr.Prefix, xtr.NamespaceURI, xtr.Value, bCreatingNewType, parentSchema, sce.Attributes, ct.AttributeUses);
  1115.                     }
  1116.                     //add atributes directly to complex type
  1117.                     else {
  1118.                         xsa = AddAttribute(xtr.LocalName, xtr.Prefix, xtr.NamespaceURI, xtr.Value, bCreatingNewType, parentSchema, ct.Attributes, ct.AttributeUses);
  1119.                     }
  1120.                     if (xsa != null) {
  1121.                         attributesSeen.Add(xsa);
  1122.                     }
  1123.                 }
  1124.                
  1125.             }
  1126.             while (xtr.MoveToNextAttribute());
  1127.             if (!bCreatingNewType) {
  1128.                 //make attributes that did not appear this time optional
  1129.                 if (ct != null) {
  1130.                     MakeExistingAttributesOptional(ct, attributesSeen);
  1131.                 }
  1132.             }
  1133.         }
  1134.        
  1135.         private void MoveAttributes(XmlSchemaSimpleContentExtension scExtension, XmlSchemaComplexType ct)
  1136.         {
  1137.             //copy all attributes from the simple content to the complex type
  1138.             //This is ok since when we move from complex type to simple content extension we copy from AttributeUses property
  1139.             foreach (XmlSchemaAttribute attr in scExtension.Attributes) {
  1140.                 //since simpleContent is being cleared
  1141.                 ct.Attributes.Add(attr);
  1142.             }
  1143.         }
  1144.        
  1145.         private void MoveAttributes(XmlSchemaComplexType ct, XmlSchemaSimpleContentExtension simpleContentExtension, bool bCreatingNewType)
  1146.         {
  1147.             //copy all attributes from the complex type to the simple content
  1148.            
  1149.             ICollection sourceCollection;
  1150.             if (!bCreatingNewType && ct.AttributeUses.Count > 0) {
  1151.                 sourceCollection = ct.AttributeUses.Values;
  1152.             }
  1153.             else {
  1154.                 sourceCollection = ct.Attributes;
  1155.             }
  1156.            
  1157.             foreach (XmlSchemaAttribute attr in sourceCollection) {
  1158.                 simpleContentExtension.Attributes.Add(attr);
  1159.             }
  1160.             ct.Attributes.Clear();
  1161.             //Clear from pre-compiled property, post compiled will be cleared on Re-process and Compile()
  1162.         }
  1163.        
  1164.         internal XmlSchemaAttribute FindAttribute(ICollection attributes, string attrName)
  1165.         {
  1166.             foreach (XmlSchemaObject xsa in attributes) {
  1167.                 XmlSchemaAttribute schemaAttribute = xsa as XmlSchemaAttribute;
  1168.                 if (schemaAttribute != null) {
  1169.                     if (schemaAttribute.Name == attrName) {
  1170.                         return schemaAttribute;
  1171.                     }
  1172.                    
  1173.                 }
  1174.             }
  1175.             return null;
  1176.         }
  1177.        
  1178.         internal XmlSchemaElement FindGlobalElement(string namespaceURI, string localName, out XmlSchema parentSchema)
  1179.         {
  1180.             ICollection col = this.schemaSet.Schemas(namespaceURI);
  1181.             XmlSchemaElement xse = null;
  1182.             parentSchema = null;
  1183.             foreach (XmlSchema schema in col) {
  1184.                 xse = FindElement(schema.Items, localName);
  1185.                 if (xse != null) {
  1186.                     parentSchema = schema;
  1187.                     return xse;
  1188.                 }
  1189.             }
  1190.             return null;
  1191.         }
  1192.        
  1193.        
  1194.         internal XmlSchemaElement FindElement(XmlSchemaObjectCollection elements, string elementName)
  1195.         {
  1196.             foreach (XmlSchemaObject obj in elements) {
  1197.                 XmlSchemaElement xse = obj as XmlSchemaElement;
  1198.                 if (xse != null && xse.RefName != null) {
  1199.                     if (xse.Name == elementName) {
  1200.                         return xse;
  1201.                     }
  1202.                 }
  1203.             }
  1204.             return null;
  1205.         }
  1206.        
  1207.         internal XmlSchemaAttribute FindAttributeRef(ICollection attributes, string attributeName, string nsURI)
  1208.         {
  1209.             foreach (XmlSchemaObject xsa in attributes) {
  1210.                 XmlSchemaAttribute schemaAttribute = xsa as XmlSchemaAttribute;
  1211.                 if (schemaAttribute != null) {
  1212.                     if (schemaAttribute.RefName.Name == attributeName && schemaAttribute.RefName.Namespace == nsURI) {
  1213.                         return schemaAttribute;
  1214.                     }
  1215.                    
  1216.                 }
  1217.             }
  1218.             return null;
  1219.         }
  1220.        
  1221.         internal XmlSchemaElement FindElementRef(XmlSchemaObjectCollection elements, string elementName, string nsURI)
  1222.         {
  1223.             foreach (XmlSchemaObject obj in elements) {
  1224.                 XmlSchemaElement xse = obj as XmlSchemaElement;
  1225.                 if (xse != null && xse.RefName != null) {
  1226.                     if (xse.RefName.Name == elementName && xse.RefName.Namespace == nsURI) {
  1227.                         return xse;
  1228.                     }
  1229.                 }
  1230.             }
  1231.             return null;
  1232.         }
  1233.        
  1234.         internal void MakeExistingAttributesOptional(XmlSchemaComplexType ct, XmlSchemaObjectCollection attributesInInstance)
  1235.         {
  1236.             if (ct == null) {
  1237.                 throw new XmlSchemaInferenceException(Res.SchInf_noct, 0, 0);
  1238.             }
  1239.             if (ct.ContentModel != null) {
  1240.                 XmlSchemaSimpleContentExtension xssce = CheckSimpleContentExtension(ct);
  1241.                 SwitchUseToOptional(xssce.Attributes, attributesInInstance);
  1242.             }
  1243.             else {
  1244.                 //either <xs:attribute> as child of xs:complexType or the attributes are within the content model
  1245.                 SwitchUseToOptional(ct.Attributes, attributesInInstance);
  1246.             }
  1247.         }
  1248.        
  1249.         private void SwitchUseToOptional(XmlSchemaObjectCollection attributes, XmlSchemaObjectCollection attributesInInstance)
  1250.         {
  1251.             foreach (XmlSchemaObject attrObj in attributes) {
  1252.                 if (attrObj is XmlSchemaAttribute) {
  1253.                     XmlSchemaAttribute attr = attrObj as XmlSchemaAttribute;
  1254.                     if (attributesInInstance != null) {
  1255.                         if (attr.RefName.Name.Length == 0) {
  1256.                             //If the attribute is not present in this instance, make it optional
  1257.                             if (null == FindAttribute(attributesInInstance, attr.Name)) {
  1258.                                 attr.Use = XmlSchemaUse.Optional;
  1259.                             }
  1260.                         }
  1261.                         else {
  1262.                             if (null == FindAttributeRef(attributesInInstance, attr.RefName.Name, attr.RefName.Namespace)) {
  1263.                                 attr.Use = XmlSchemaUse.Optional;
  1264.                             }
  1265.                         }
  1266.                     }
  1267.                     else {
  1268.                         attr.Use = XmlSchemaUse.Optional;
  1269.                     }
  1270.                 }
  1271.             }
  1272.         }
  1273.        
  1274.         internal XmlQualifiedName RefineSimpleType(string s, ref int iTypeFlags)
  1275.         {
  1276.             bool bNeedsRangeCheck = false;
  1277.             s = s.Trim();
  1278.             if (iTypeFlags == TF_string || this.typeInference == InferenceOption.Relaxed)
  1279.                 return ST_string;
  1280.             iTypeFlags &= InferSimpleType(s, ref bNeedsRangeCheck);
  1281.             if (iTypeFlags == TF_string)
  1282.                 return ST_string;
  1283.             if (bNeedsRangeCheck) {
  1284.                 if ((iTypeFlags & TF_byte) != 0) {
  1285.                     try {
  1286.                         XmlConvert.ToSByte(s);
  1287.                         //sbyte.Parse(s);
  1288.                         if ((iTypeFlags & TF_unsignedByte) != 0)
  1289.                             return ST_unsignedByte;
  1290.                         else
  1291.                             //number is positive and fits byte -> it also fits unsignedByte
  1292.                             return ST_byte;
  1293.                     }
  1294.                     catch (FormatException) {
  1295.                     }
  1296.                     catch (OverflowException) {
  1297.                     }
  1298.                     iTypeFlags &= (~TF_byte);
  1299.                 }
  1300.                 if ((iTypeFlags & TF_unsignedByte) != 0) {
  1301.                     try {
  1302.                         XmlConvert.ToByte(s);
  1303.                         //byte.Parse(s);
  1304.                         return ST_unsignedByte;
  1305.                     }
  1306.                     catch (FormatException) {
  1307.                     }
  1308.                     catch (OverflowException) {
  1309.                     }
  1310.                     iTypeFlags &= (~TF_unsignedByte);
  1311.                 }
  1312.                 if ((iTypeFlags & TF_short) != 0) {
  1313.                     try {
  1314.                         XmlConvert.ToInt16(s);
  1315.                         //short.Parse(s);
  1316.                         if ((iTypeFlags & TF_unsignedShort) != 0)
  1317.                             return ST_unsignedShort;
  1318.                         else
  1319.                             //number is positive and fits short -> it also fits unsignedShort
  1320.                             return ST_short;
  1321.                     }
  1322.                     catch (FormatException) {
  1323.                     }
  1324.                     catch (OverflowException) {
  1325.                     }
  1326.                     iTypeFlags &= (~TF_short);
  1327.                 }
  1328.                 if ((iTypeFlags & TF_unsignedShort) != 0) {
  1329.                     try {
  1330.                         XmlConvert.ToUInt16(s);
  1331.                         //ushort.Parse(s);
  1332.                         return ST_unsignedShort;
  1333.                     }
  1334.                     catch (FormatException) {
  1335.                     }
  1336.                     catch (OverflowException) {
  1337.                     }
  1338.                     iTypeFlags &= (~TF_unsignedShort);
  1339.                 }
  1340.                 if ((iTypeFlags & TF_int) != 0) {
  1341.                     try {
  1342.                         XmlConvert.ToInt32(s);
  1343.                         //int.Parse(s);
  1344.                         if ((iTypeFlags & TF_unsignedInt) != 0)
  1345.                             return ST_unsignedInt;
  1346.                         else
  1347.                             //number is positive and fits int -> it also fits unsignedInt
  1348.                             return ST_int;
  1349.                     }
  1350.                     catch (FormatException) {
  1351.                     }
  1352.                     catch (OverflowException) {
  1353.                     }
  1354.                     iTypeFlags &= (~TF_int);
  1355.                 }
  1356.                 if ((iTypeFlags & TF_unsignedInt) != 0) {
  1357.                     try {
  1358.                         XmlConvert.ToUInt32(s);
  1359.                         //uint.Parse(s);
  1360.                         return ST_unsignedInt;
  1361.                     }
  1362.                     catch (FormatException) {
  1363.                     }
  1364.                     catch (OverflowException) {
  1365.                     }
  1366.                     iTypeFlags &= (~TF_unsignedInt);
  1367.                 }
  1368.                 if ((iTypeFlags & TF_long) != 0) {
  1369.                     try {
  1370.                         XmlConvert.ToInt64(s);
  1371.                         //long.Parse(s);
  1372.                         if ((iTypeFlags & TF_unsignedLong) != 0)
  1373.                             return ST_unsignedLong;
  1374.                         else
  1375.                             //number is positive and fits long -> it also fits unsignedLong
  1376.                             return ST_long;
  1377.                     }
  1378.                     catch (FormatException) {
  1379.                     }
  1380.                     catch (OverflowException) {
  1381.                     }
  1382.                     iTypeFlags &= (~TF_long);
  1383.                 }
  1384.                 if ((iTypeFlags & TF_unsignedLong) != 0) {
  1385.                     try {
  1386.                         XmlConvert.ToUInt64(s);
  1387.                         //ulong.Parse(s);
  1388.                         return ST_unsignedLong;
  1389.                     }
  1390.                     catch (FormatException) {
  1391.                     }
  1392.                     catch (OverflowException) {
  1393.                     }
  1394.                     iTypeFlags &= (~TF_unsignedLong);
  1395.                 }
  1396.                 if ((iTypeFlags & TF_float) != 0) {
  1397.                     try {
  1398.                         XmlConvert.ToSingle(s);
  1399.                         if ((iTypeFlags & TF_integer) != 0)
  1400.                             return ST_integer;
  1401.                         else if ((iTypeFlags & TF_decimal) != 0)
  1402.                             return ST_decimal;
  1403.                         else
  1404.                             return ST_float;
  1405.                     }
  1406.                     catch (FormatException) {
  1407.                     }
  1408.                     catch (OverflowException) {
  1409.                     }
  1410.                     iTypeFlags &= (~TF_float);
  1411.                 }
  1412.                 if ((iTypeFlags & TF_double) != 0) {
  1413.                     try {
  1414.                         XmlConvert.ToDouble(s);
  1415.                         if ((iTypeFlags & TF_integer) != 0)
  1416.                             return ST_integer;
  1417.                         else if ((iTypeFlags & TF_decimal) != 0)
  1418.                             return ST_decimal;
  1419.                         else
  1420.                             return ST_double;
  1421.                     }
  1422.                     catch (FormatException) {
  1423.                     }
  1424.                     catch (OverflowException) {
  1425.                     }
  1426.                     iTypeFlags &= (~TF_double);
  1427.                 }
  1428.                 if ((iTypeFlags & TF_integer) != 0)
  1429.                     return ST_integer;
  1430.                 else if ((iTypeFlags & TF_decimal) != 0)
  1431.                     return ST_decimal;
  1432.                 else if (iTypeFlags == (TF_gYearMonth | TF_string)) {
  1433.                     try {
  1434.                         XmlConvert.ToDateTime(s, XmlDateTimeSerializationMode.RoundtripKind);
  1435.                         return ST_gYearMonth;
  1436.                     }
  1437.                     catch (FormatException) {
  1438.                     }
  1439.                     catch (OverflowException) {
  1440.                     }
  1441.                     iTypeFlags = TF_string;
  1442.                     return ST_string;
  1443.                 }
  1444.                 else if (iTypeFlags == (TF_duration | TF_string)) {
  1445.                     try {
  1446.                         XmlConvert.ToTimeSpan(s);
  1447.                         return ST_duration;
  1448.                     }
  1449.                     catch (FormatException) {
  1450.                     }
  1451.                     catch (OverflowException) {
  1452.                     }
  1453.                     iTypeFlags = TF_string;
  1454.                     return ST_string;
  1455.                 }
  1456.                 else if (iTypeFlags == (TF_boolean | TF_string)) {
  1457.                     return ST_boolean;
  1458.                 }
  1459.                
  1460.             }
  1461.            
  1462.             switch (iTypeFlags) {
  1463.                 case TF_string:
  1464.                     return ST_string;
  1465.                 case TF_boolean:
  1466.                     return ST_boolean;
  1467.                 case TF_byte:
  1468.                     return ST_byte;
  1469.                 case TF_unsignedByte:
  1470.                     return ST_unsignedByte;
  1471.                 case TF_short:
  1472.                     return ST_short;
  1473.                 case TF_unsignedShort:
  1474.                     return ST_unsignedShort;
  1475.                 case TF_int:
  1476.                     return ST_int;
  1477.                 case TF_unsignedInt:
  1478.                     return ST_unsignedInt;
  1479.                 case TF_long:
  1480.                     return ST_long;
  1481.                 case TF_unsignedLong:
  1482.                     return ST_unsignedLong;
  1483.                 case TF_integer:
  1484.                     return ST_integer;
  1485.                 case TF_decimal:
  1486.                     return ST_decimal;
  1487.                 case TF_float:
  1488.                     return ST_float;
  1489.                 case TF_double:
  1490.                     return ST_double;
  1491.                 case TF_duration:
  1492.                     return ST_duration;
  1493.                 case TF_dateTime:
  1494.                     return ST_dateTime;
  1495.                 case TF_time:
  1496.                     return ST_time;
  1497.                 case TF_date:
  1498.                     return ST_date;
  1499.                 case TF_gYearMonth:
  1500.                     return ST_gYearMonth;
  1501.                 case TF_boolean | TF_string:
  1502.                    
  1503.                     return ST_boolean;
  1504.                 case TF_dateTime | TF_string:
  1505.                     return ST_dateTime;
  1506.                 case TF_date | TF_string:
  1507.                     return ST_date;
  1508.                 case TF_time | TF_string:
  1509.                     return ST_time;
  1510.                 case TF_float | TF_double | TF_string:
  1511.                     return ST_float;
  1512.                 case TF_double | TF_string:
  1513.                     return ST_double;
  1514.                 default:
  1515.                    
  1516.                     Debug.Assert(false, "Expected type not matched");
  1517.                     return ST_string;
  1518.             }
  1519.             /*          if (currentType == null)
  1520.                                 return SimpleTypes[newType];
  1521.                             else
  1522.                                 return SimpleTypes[ST_Map[newType,(short) ST_Codes[currentType]]];
  1523.                                 */           
  1524.         }
  1525.        
  1526.         static internal int InferSimpleType(string s, ref bool bNeedsRangeCheck)
  1527.         {
  1528.             bool bNegative = false;
  1529.             bool bPositive = false;
  1530.             bool bDate = false;
  1531.             bool bTime = false;
  1532.             bool bMissingDay = false;
  1533.            
  1534.             if (s.Length == 0)
  1535.                 return TF_string;
  1536.             int i = 0;
  1537.             switch (s[i]) {
  1538.                 case 't':
  1539.                 case 'f':
  1540.                     if (s == "true")
  1541.                         return TF_boolean | TF_string;
  1542.                     else if (s == "false")
  1543.                         return TF_boolean | TF_string;
  1544.                     else
  1545.                         return TF_string;
  1546.                     break;
  1547.                 case 'N':
  1548.                     //try to match "NaN"
  1549.                     if (s == "NaN")
  1550.                         return TF_float | TF_double | TF_string;
  1551.                     else
  1552.                         return TF_string;
  1553.                     break;
  1554.                 case 'I':
  1555.                     INF:
  1556.                     //else
  1557.                     //try to match "INF"
  1558.                     if (s.Substring(i) == "INF")
  1559.                         return TF_float | TF_double | TF_string;
  1560.                     else
  1561.                         return TF_string;
  1562.                     break;
  1563.                 case '.':
  1564.                     FRACTION:
  1565.                     //try to match ".9999" decimal/float/double
  1566.                     bNeedsRangeCheck = true;
  1567.                     i++;
  1568.                     if (i == s.Length) {
  1569.                         if ((i == 1) || (i == 2 && (bPositive || bNegative)))
  1570.                             return TF_string;
  1571.                         else
  1572.                             //"." "-." "+."
  1573.                             return TF_decimal | TF_float | TF_double | TF_string;
  1574.                     }
  1575.                     switch (s[i]) {
  1576.                         case 'e':
  1577.                         case 'E':
  1578.                             goto EXPONENT;
  1579.                             break;
  1580.                         default:
  1581.                             if (s[i] >= '0' && s[i] <= '9')
  1582.                                 goto DEC_PART;
  1583.                             else
  1584.                                 return TF_string;
  1585.                             break;
  1586.                     }
  1587.                     DEC_PART:
  1588.                     i++;
  1589.                     if (i == s.Length)
  1590.                         return TF_decimal | TF_float | TF_double | TF_string;
  1591.                     //"9999.9" was matched
  1592.                     switch (s[i]) {
  1593.                         case 'e':
  1594.                         case 'E':
  1595.                             goto EXPONENT;
  1596.                             break;
  1597.                         default:
  1598.                             if (s[i] >= '0' && s[i] <= '9')
  1599.                                 goto DEC_PART;
  1600.                             else
  1601.                                 return TF_string;
  1602.                             break;
  1603.                     }
  1604.                     EXPONENT:
  1605.                     i++;
  1606.                     if (i == s.Length)
  1607.                         return TF_string;
  1608.                     switch (s[i]) {
  1609.                         case '+':
  1610.                         case '-':
  1611.                             goto E1;
  1612.                             break;
  1613.                         default:
  1614.                             if (s[i] >= '0' && s[i] <= '9')
  1615.                                 goto EXP_PART;
  1616.                             else
  1617.                                 return TF_string;
  1618.                             break;
  1619.                     }
  1620.                     E1:
  1621.                     i++;
  1622.                     if (i == s.Length)
  1623.                         return TF_string;
  1624.                     //".9999e+" was matched
  1625.                     if (s[i] >= '0' && s[i] <= '9')
  1626.                         goto EXP_PART;
  1627.                     else
  1628.                         return TF_string;
  1629.                     EXP_PART:
  1630.                     //".999e+X was matched
  1631.                     i++;
  1632.                     if (i == s.Length)
  1633.                         return TF_float | TF_double | TF_string;
  1634.                     //".9999e+99" was matched
  1635.                     if (s[i] >= '0' && s[i] <= '9')
  1636.                         goto EXP_PART;
  1637.                     else
  1638.                         //".9999e+9
  1639.                         return TF_string;
  1640.                     break;
  1641.                 case '-':
  1642.                     //".9999e+999X" was matched
  1643.                     bNegative = true;
  1644.                     i++;
  1645.                     if (i == s.Length)
  1646.                         return TF_string;
  1647.                     switch (s[i]) {
  1648.                         case 'I':
  1649.                             //try to match "-INF"
  1650.                             goto INF;
  1651.                             break;
  1652.                         case '.':
  1653.                             //try to match "-.9999"
  1654.                             goto FRACTION;
  1655.                             break;
  1656.                         case 'P':
  1657.                             goto DURATION;
  1658.                             break;
  1659.                         default:
  1660.                             if (s[i] >= '0' && s[i] <= '9')
  1661.                                 goto NUMBER;
  1662.                             else
  1663.                                 //-9
  1664.                                 return TF_string;
  1665.                             break;
  1666.                     }
  1667.                     break;
  1668.                 case '+':
  1669.                     bPositive = true;
  1670.                     i++;
  1671.                     if (i == s.Length)
  1672.                         return TF_string;
  1673.                     switch (s[i]) {
  1674.                         case '.':
  1675.                             //try to match "+.9999"
  1676.                             goto FRACTION;
  1677.                             break;
  1678.                         case 'P':
  1679.                             goto DURATION;
  1680.                             break;
  1681.                         default:
  1682.                             if (s[i] >= '0' && s[i] <= '9')
  1683.                                 goto NUMBER;
  1684.                             else
  1685.                                 //"+9
  1686.                                 return TF_string;
  1687.                             break;
  1688.                     }
  1689.                     break;
  1690.                 case 'P':
  1691.                     DURATION:
  1692.                     //try to match duration
  1693.                     i++;
  1694.                     if (i == s.Length)
  1695.                         return TF_string;
  1696.                     switch (s[i]) {
  1697.                         case 'T':
  1698.                             goto D7;
  1699.                             break;
  1700.                         default:
  1701.                             if (s[i] >= '0' && s[i] <= '9')
  1702.                                 goto D1;
  1703.                             else
  1704.                                 //"P9"
  1705.                                 return TF_string;
  1706.                             break;
  1707.                     }
  1708.                     D1:
  1709.                     i++;
  1710.                     if (i == s.Length)
  1711.                         return TF_string;
  1712.                     //"P999" was matched
  1713.                     switch (s[i]) {
  1714.                         case 'Y':
  1715.                             goto D2;
  1716.                             break;
  1717.                         case 'M':
  1718.                             goto D4;
  1719.                             break;
  1720.                         case 'D':
  1721.                             goto D6;
  1722.                             break;
  1723.                         default:
  1724.                             if (s[i] >= '0' && s[i] <= '9')
  1725.                                 goto D1;
  1726.                             else
  1727.                                 return TF_string;
  1728.                             break;
  1729.                     }
  1730.                     D2:
  1731.                     i++;
  1732.                     if (i == s.Length) {
  1733.                         bNeedsRangeCheck = true;
  1734.                         return TF_duration | TF_string;
  1735.                         //"P999Y" was matched
  1736.                     }
  1737.                     switch (s[i]) {
  1738.                         case 'T':
  1739.                             goto D7;
  1740.                             break;
  1741.                         default:
  1742.                             if (s[i] >= '0' && s[i] <= '9')
  1743.                                 goto D3;
  1744.                             else
  1745.                                 return TF_string;
  1746.                             break;
  1747.                     }
  1748.                     D3:
  1749.                     i++;
  1750.                     if (i == s.Length)
  1751.                         return TF_string;
  1752.                     //"P999Y9" was matched
  1753.                     switch (s[i]) {
  1754.                         case 'M':
  1755.                             goto D4;
  1756.                             break;
  1757.                         case 'D':
  1758.                             goto D6;
  1759.                             break;
  1760.                         default:
  1761.                             if (s[i] >= '0' && s[i] <= '9')
  1762.                                 goto D3;
  1763.                             else
  1764.                                 return TF_string;
  1765.                             break;
  1766.                     }
  1767.                     D4:
  1768.                     i++;
  1769.                     if (i == s.Length) {
  1770.                         bNeedsRangeCheck = true;
  1771.                         return TF_duration | TF_string;
  1772.                         //"P999Y999M" was matched
  1773.                     }
  1774.                     switch (s[i]) {
  1775.                         case 'T':
  1776.                             goto D7;
  1777.                             break;
  1778.                         default:
  1779.                             if (s[i] >= '0' && s[i] <= '9')
  1780.                                 goto D5;
  1781.                             else
  1782.                                 return TF_string;
  1783.                             break;
  1784.                     }
  1785.                     D5:
  1786.                     i++;
  1787.                     if (i == s.Length)
  1788.                         return TF_string;
  1789.                     //"P999Y999M9" was matched
  1790.                     switch (s[i]) {
  1791.                         case 'D':
  1792.                             goto D6;
  1793.                             break;
  1794.                         default:
  1795.                             if (s[i] >= '0' && s[i] <= '9')
  1796.                                 goto D5;
  1797.                             else
  1798.                                 return TF_string;
  1799.                             break;
  1800.                     }
  1801.                     D6:
  1802.                     i++;
  1803.                     if (i == s.Length) {
  1804.                         bNeedsRangeCheck = true;
  1805.                         return TF_duration | TF_string;
  1806.                         //"P999Y999M999D" was matched
  1807.                     }
  1808.                     switch (s[i]) {
  1809.                         case 'T':
  1810.                             goto D7;
  1811.                             break;
  1812.                         default:
  1813.                             return TF_string;
  1814.                     }
  1815.                     D7:
  1816.                     i++;
  1817.                     if (i == s.Length)
  1818.                         return TF_string;
  1819.                     //"P999Y999M9999DT" was matched
  1820.                     if (s[i] >= '0' && s[i] <= '9')
  1821.                         goto D8;
  1822.                     else
  1823.                         return TF_string;
  1824.                     D8:
  1825.                     i++;
  1826.                     if (i == s.Length)
  1827.                         return TF_string;
  1828.                     //"___T9" was matched
  1829.                     switch (s[i]) {
  1830.                         case 'H':
  1831.                             goto D9;
  1832.                             break;
  1833.                         case 'M':
  1834.                             goto D11;
  1835.                             break;
  1836.                         case '.':
  1837.                             goto D13;
  1838.                             break;
  1839.                         case 'S':
  1840.                             goto D15;
  1841.                             break;
  1842.                         default:
  1843.                             if (s[i] >= '0' && s[i] <= '9')
  1844.                                 goto D8;
  1845.                             else
  1846.                                 return TF_string;
  1847.                             break;
  1848.                     }
  1849.                     D9:
  1850.                     i++;
  1851.                     if (i == s.Length) {
  1852.                         bNeedsRangeCheck = true;
  1853.                         return TF_duration | TF_string;
  1854.                         //"___T999H" was matched
  1855.                     }
  1856.                     if (s[i] >= '0' && s[i] <= '9')
  1857.                         goto D10;
  1858.                     else
  1859.                         return TF_string;
  1860.                     D10:
  1861.                     i++;
  1862.                     if (i == s.Length)
  1863.                         return TF_string;
  1864.                     //"___T999H9" was matched
  1865.                     switch (s[i]) {
  1866.                         case 'M':
  1867.                             goto D11;
  1868.                             break;
  1869.                         case '.':
  1870.                             goto D13;
  1871.                             break;
  1872.                         case 'S':
  1873.                             goto D15;
  1874.                             break;
  1875.                         default:
  1876.                             if (s[i] >= '0' && s[i] <= '9')
  1877.                                 goto D10;
  1878.                             else
  1879.                                 return TF_string;
  1880.                             break;
  1881.                     }
  1882.                     D11:
  1883.                     i++;
  1884.                     if (i == s.Length) {
  1885.                         bNeedsRangeCheck = true;
  1886.                         return TF_duration | TF_string;
  1887.                         //"___T999H999M" was matched
  1888.                     }
  1889.                     if (s[i] >= '0' && s[i] <= '9')
  1890.                         goto D12;
  1891.                     else
  1892.                         return TF_string;
  1893.                     D12:
  1894.                     i++;
  1895.                     if (i == s.Length)
  1896.                         return TF_string;
  1897.                     //"___T999H999M9" was matched
  1898.                     switch (s[i]) {
  1899.                         case '.':
  1900.                             goto D13;
  1901.                             break;
  1902.                         case 'S':
  1903.                             goto D15;
  1904.                             break;
  1905.                         default:
  1906.                             if (s[i] >= '0' && s[i] <= '9')
  1907.                                 goto D12;
  1908.                             else
  1909.                                 return TF_string;
  1910.                             break;
  1911.                     }
  1912.                     D13:
  1913.                     i++;
  1914.                     if (i == s.Length) {
  1915.                         bNeedsRangeCheck = true;
  1916.                         return TF_duration | TF_string;
  1917.                         //"___T999H999M999." was matched
  1918.                     }
  1919.                     if (s[i] >= '0' && s[i] <= '9')
  1920.                         goto D14;
  1921.                     else
  1922.                         return TF_string;
  1923.                     D14:
  1924.                     i++;
  1925.                     if (i == s.Length)
  1926.                         return TF_string;
  1927.                     //"___T999H999M999.9" was matched
  1928.                     switch (s[i]) {
  1929.                         case 'S':
  1930.                             goto D15;
  1931.                             break;
  1932.                         default:
  1933.                             if (s[i] >= '0' && s[i] <= '9')
  1934.                                 goto D14;
  1935.                             else
  1936.                                 return TF_string;
  1937.                             break;
  1938.                     }
  1939.                     D15:
  1940.                     i++;
  1941.                     if (i == s.Length) {
  1942.                         bNeedsRangeCheck = true;
  1943.                         return TF_duration | TF_string;
  1944.                         //"___T999H999M999.999S" was matched
  1945.                     }
  1946.                     else
  1947.                         return TF_string;
  1948.                     break;
  1949.                 case '0':
  1950.                 case '1':
  1951.                 case '2':
  1952.                 case '3':
  1953.                 case '4':
  1954.                 case '5':
  1955.                 case '6':
  1956.                 case '7':
  1957.                 case '8':
  1958.                 case '9':
  1959.                     NUMBER:
  1960.                     i++;
  1961.                     if (i == s.Length) {
  1962.                         bNeedsRangeCheck = true;
  1963.                         if (bNegative || bPositive)
  1964.                             return TF_byte | TF_short | TF_int | TF_long | TF_integer | TF_decimal | TF_float | TF_double | TF_string;
  1965.                         //"-9"
  1966.                         else {
  1967.                             if (s == "0" || s == "1")
  1968.                                 return TF_boolean | TF_byte | TF_short | TF_int | TF_long | TF_integer | TF_decimal | TF_float | TF_double | TF_unsignedByte | TF_unsignedShort | TF_unsignedInt | TF_unsignedLong | TF_string;
  1969.                             else
  1970.                                 return TF_byte | TF_short | TF_int | TF_long | TF_integer | TF_decimal | TF_float | TF_double | TF_unsignedByte | TF_unsignedShort | TF_unsignedInt | TF_unsignedLong | TF_string;
  1971.                         }
  1972.                     }
  1973.                     switch (s[i]) {
  1974.                         case '.':
  1975.                             goto FRACTION;
  1976.                             break;
  1977.                         case 'e':
  1978.                         case 'E':
  1979.                             bNeedsRangeCheck = true;
  1980.                             return TF_float | TF_double | TF_string;
  1981.                         default:
  1982.                             if (s[i] >= '0' && s[i] <= '9')
  1983.                                 goto N2;
  1984.                             else
  1985.                                 return TF_string;
  1986.                             break;
  1987.                     }
  1988.                     N2:
  1989.                     i++;
  1990.                     if (i == s.Length) {
  1991.                         bNeedsRangeCheck = true;
  1992.                         if (bNegative || bPositive)
  1993.                             return TF_byte | TF_short | TF_int | TF_long | TF_integer | TF_decimal | TF_float | TF_double | TF_string;
  1994.                         else
  1995.                             //"-9"
  1996.                             return TF_byte | TF_short | TF_int | TF_long | TF_integer | TF_decimal | TF_float | TF_double | TF_unsignedByte | TF_unsignedShort | TF_unsignedInt | TF_unsignedLong | TF_string;
  1997.                     }
  1998.                     switch (s[i]) {
  1999.                         case '.':
  2000.                             goto FRACTION;
  2001.                             break;
  2002.                         case ':':
  2003.                             bTime = true;
  2004.                             goto MINUTE;
  2005.                             break;
  2006.                         case 'e':
  2007.                         case 'E':
  2008.                             bNeedsRangeCheck = true;
  2009.                             return TF_float | TF_double | TF_string;
  2010.                         default:
  2011.                             if (s[i] >= '0' && s[i] <= '9')
  2012.                                 goto N3;
  2013.                             else
  2014.                                 return TF_string;
  2015.                             break;
  2016.                     }
  2017.                     N3:
  2018.                    
  2019.                     i++;
  2020.                     if (i == s.Length) {
  2021.                         bNeedsRangeCheck = true;
  2022.                         //three digits may not fit byte and unsignedByte
  2023.                         if (bNegative || bPositive)
  2024.                             return TF_byte | TF_short | TF_int | TF_long | TF_integer | TF_decimal | TF_float | TF_double | TF_string;
  2025.                         else
  2026.                             //"-9"
  2027.                             return TF_byte | TF_short | TF_int | TF_long | TF_integer | TF_decimal | TF_float | TF_double | TF_unsignedByte | TF_unsignedShort | TF_unsignedInt | TF_unsignedLong | TF_string;
  2028.                     }
  2029.                     switch (s[i]) {
  2030.                         case '.':
  2031.                             goto FRACTION;
  2032.                             break;
  2033.                         case 'e':
  2034.                         case 'E':
  2035.                             bNeedsRangeCheck = true;
  2036.                             return TF_float | TF_double | TF_string;
  2037.                         default:
  2038.                             if (s[i] >= '0' && s[i] <= '9')
  2039.                                 goto N4;
  2040.                             else
  2041.                                 return TF_string;
  2042.                             break;
  2043.                     }
  2044.                     N4:
  2045.                     i++;
  2046.                     if (i == s.Length) {
  2047.                         bNeedsRangeCheck = true;
  2048.                         if (bNegative || bPositive)
  2049.                             return TF_byte | TF_short | TF_int | TF_long | TF_integer | TF_decimal | TF_float | TF_double | TF_string;
  2050.                         else
  2051.                             //"-9"
  2052.                             return TF_byte | TF_short | TF_int | TF_long | TF_integer | TF_decimal | TF_float | TF_double | TF_unsignedByte | TF_unsignedShort | TF_unsignedInt | TF_unsignedLong | TF_string;
  2053.                     }
  2054.                    
  2055.                     switch (s[i]) {
  2056.                         case '-':
  2057.                             bDate = true;
  2058.                             goto DATE;
  2059.                             break;
  2060.                         case '.':
  2061.                             goto FRACTION;
  2062.                             break;
  2063.                         case 'e':
  2064.                         case 'E':
  2065.                             bNeedsRangeCheck = true;
  2066.                             return TF_float | TF_double | TF_string;
  2067.                         default:
  2068.                             if (s[i] >= '0' && s[i] <= '9')
  2069.                                 goto N4;
  2070.                             else
  2071.                                 return TF_string;
  2072.                             break;
  2073.                     }
  2074.                     DATE:
  2075.                     i++;
  2076.                     if (i == s.Length)
  2077.                         return TF_string;
  2078.                     //"9999-"
  2079.                     if (s[i] < '0' || s[i] > '9')
  2080.                         return TF_string;
  2081.                     i++;
  2082.                     if (i == s.Length)
  2083.                         return TF_string;
  2084.                     //"9999-9"
  2085.                     if (s[i] < '0' || s[i] > '9')
  2086.                         return TF_string;
  2087.                     i++;
  2088.                     if (i == s.Length) {
  2089.                         bNeedsRangeCheck = true;
  2090.                         return TF_gYearMonth | TF_string;
  2091.                         //"9999-99"
  2092.                     }
  2093.                     switch (s[i]) {
  2094.                         case '-':
  2095.                             goto DAY;
  2096.                             break;
  2097.                         case 'Z':
  2098.                         case 'z':
  2099.                             bMissingDay = true;
  2100.                             goto ZULU;
  2101.                             break;
  2102.                         case '+':
  2103.                             bMissingDay = true;
  2104.                             goto ZONE_SHIFT;
  2105.                             break;
  2106.                         default:
  2107.                             return TF_string;
  2108.                     }
  2109.                     DAY:
  2110.                     i++;
  2111.                     if (i == s.Length)
  2112.                         return TF_string;
  2113.                     //"9999-99-"
  2114.                     if (s[i] < '0' || s[i] > '9')
  2115.                         return TF_string;
  2116.                     i++;
  2117.                     if (i == s.Length)
  2118.                         return TF_string;
  2119.                     //"9999-99-9"
  2120.                     if (s[i] < '0' || s[i] > '9')
  2121.                         return TF_string;
  2122.                     i++;
  2123.                     if (i == s.Length)
  2124.                         return DateTime(s, bDate, bTime);
  2125.                     //"9999-99-99"
  2126.                     switch (s[i]) {
  2127.                         case 'Z':
  2128.                         case 'z':
  2129.                             goto ZULU;
  2130.                             break;
  2131.                         case '+':
  2132.                         case '-':
  2133.                             goto ZONE_SHIFT;
  2134.                             break;
  2135.                         case 'T':
  2136.                             bTime = true;
  2137.                             goto TIME;
  2138.                             break;
  2139.                         case ':':
  2140.                             bMissingDay = true;
  2141.                             goto ZONE_SHIFT_MINUTE;
  2142.                             break;
  2143.                         default:
  2144.                             return TF_string;
  2145.                     }
  2146.                     ZULU:
  2147.                     i++;
  2148.                     if (i == s.Length) {
  2149.                         if (bMissingDay) {
  2150.                             bNeedsRangeCheck = true;
  2151.                             return TF_gYearMonth | TF_string;
  2152.                         }
  2153.                         else {
  2154.                             return DateTime(s, bDate, bTime);
  2155.                         }
  2156.                     }
  2157.                     else
  2158.                         return TF_string;
  2159.                     ZONE_SHIFT:
  2160.                     i++;
  2161.                     if (i == s.Length)
  2162.                         return TF_string;
  2163.                     if (s[i] < '0' || s[i] > '9')
  2164.                         return TF_string;
  2165.                     i++;
  2166.                     if (i == s.Length)
  2167.                         return TF_string;
  2168.                     if (s[i] < '0' || s[i] > '9')
  2169.                         return TF_string;
  2170.                     i++;
  2171.                     if (i == s.Length)
  2172.                         return TF_string;
  2173.                     if (s[i] != ':')
  2174.                         return TF_string;
  2175.                     ZONE_SHIFT_MINUTE:
  2176.                     i++;
  2177.                     if (i == s.Length)
  2178.                         return TF_string;
  2179.                     if (s[i] < '0' || s[i] > '9')
  2180.                         return TF_string;
  2181.                     i++;
  2182.                     if (i == s.Length)
  2183.                         return TF_string;
  2184.                     if (s[i] < '0' || s[i] > '9')
  2185.                         return TF_string;
  2186.                     i++;
  2187.                     if (i == s.Length) {
  2188.                         if (bMissingDay) {
  2189.                             bNeedsRangeCheck = true;
  2190.                             return TF_gYearMonth | TF_string;
  2191.                         }
  2192.                         else {
  2193.                             return DateTime(s, bDate, bTime);
  2194.                         }
  2195.                     }
  2196.                     else
  2197.                         return TF_string;
  2198.                     TIME:
  2199.                     i++;
  2200.                     if (i == s.Length)
  2201.                         return TF_string;
  2202.                     if (s[i] < '0' || s[i] > '9')
  2203.                         return TF_string;
  2204.                     i++;
  2205.                     if (i == s.Length)
  2206.                         return TF_string;
  2207.                     if (s[i] < '0' || s[i] > '9')
  2208.                         return TF_string;
  2209.                     i++;
  2210.                     if (i == s.Length)
  2211.                         return TF_string;
  2212.                     if (s[i] != ':')
  2213.                         return TF_string;
  2214.                     MINUTE:
  2215.                     i++;
  2216.                     if (i == s.Length)
  2217.                         return TF_string;
  2218.                     if (s[i] < '0' || s[i] > '9')
  2219.                         return TF_string;
  2220.                     i++;
  2221.                     if (i == s.Length)
  2222.                         return TF_string;
  2223.                     if (s[i] < '0' || s[i] > '9')
  2224.                         return TF_string;
  2225.                     i++;
  2226.                     if (i == s.Length)
  2227.                         return TF_string;
  2228.                     if (s[i] != ':')
  2229.                         return TF_string;
  2230.                     i++;
  2231.                     if (i == s.Length)
  2232.                         return TF_string;
  2233.                     if (s[i] < '0' || s[i] > '9')
  2234.                         return TF_string;
  2235.                     i++;
  2236.                     if (i == s.Length)
  2237.                         return TF_string;
  2238.                     if (s[i] < '0' || s[i] > '9')
  2239.                         return TF_string;
  2240.                     i++;
  2241.                     if (i == s.Length)
  2242.                         return DateTime(s, bDate, bTime);
  2243.                     switch (s[i]) {
  2244.                         case 'Z':
  2245.                         case 'z':
  2246.                             goto ZULU;
  2247.                             break;
  2248.                         case '+':
  2249.                         case '-':
  2250.                             goto ZONE_SHIFT;
  2251.                             break;
  2252.                         case '.':
  2253.                             goto SECOND_FRACTION;
  2254.                             break;
  2255.                         default:
  2256.                             return TF_string;
  2257.                     }
  2258.                     SECOND_FRACTION:
  2259.                     i++;
  2260.                     if (i == s.Length)
  2261.                         return TF_string;
  2262.                     if (s[i] < '0' || s[i] > '9')
  2263.                         return TF_string;
  2264.                     FRACT_DIGITS:
  2265.                     i++;
  2266.                     if (i == s.Length)
  2267.                         return DateTime(s, bDate, bTime);
  2268.                     switch (s[i]) {
  2269.                         case 'Z':
  2270.                         case 'z':
  2271.                             goto ZULU;
  2272.                             break;
  2273.                         case '+':
  2274.                         case '-':
  2275.                             goto ZONE_SHIFT;
  2276.                             break;
  2277.                         default:
  2278.                             if (s[i] >= '0' && s[i] <= '9')
  2279.                                 goto FRACT_DIGITS;
  2280.                             else
  2281.                                 return TF_string;
  2282.                             break;
  2283.                        
  2284.                     }
  2285.                     break;
  2286.                 default:
  2287.                     return TF_string;
  2288.             }
  2289.         }
  2290.        
  2291.         static internal int DateTime(string s, bool bDate, bool bTime)
  2292.         {
  2293.             try {
  2294.                 XmlConvert.ToDateTime(s, XmlDateTimeSerializationMode.RoundtripKind);
  2295.             }
  2296.             catch (FormatException) {
  2297.                 return TF_string;
  2298.             }
  2299.             if (bDate && bTime)
  2300.                 return TF_dateTime | TF_string;
  2301.             else if (bDate)
  2302.                 return TF_date | TF_string;
  2303.             else if (bTime)
  2304.                 return TF_time | TF_string;
  2305.             else {
  2306.                 Debug.Assert(false, "Expected date, time or dateTime");
  2307.                 return TF_string;
  2308.             }
  2309.         }
  2310.         XmlSchemaElement CreateNewElementforChoice(XmlSchemaElement copyElement)
  2311.         {
  2312.             XmlSchemaElement newElement = new XmlSchemaElement();
  2313.             newElement.Annotation = copyElement.Annotation;
  2314.             newElement.Block = copyElement.Block;
  2315.             newElement.DefaultValue = copyElement.DefaultValue;
  2316.             newElement.Final = copyElement.Final;
  2317.             newElement.FixedValue = copyElement.FixedValue;
  2318.             newElement.Form = copyElement.Form;
  2319.             newElement.Id = copyElement.Id;
  2320.             // newElement.IsAbstract = copyElement.IsAbstract;
  2321.             if (copyElement.IsNillable) {
  2322.                 newElement.IsNillable = copyElement.IsNillable;
  2323.             }
  2324.             newElement.LineNumber = copyElement.LineNumber;
  2325.             newElement.LinePosition = copyElement.LinePosition;
  2326.             newElement.Name = copyElement.Name;
  2327.             newElement.Namespaces = copyElement.Namespaces;
  2328.             newElement.RefName = copyElement.RefName;
  2329.             newElement.SchemaType = copyElement.SchemaType;
  2330.             newElement.SchemaTypeName = copyElement.SchemaTypeName;
  2331.             newElement.SourceUri = copyElement.SourceUri;
  2332.             newElement.SubstitutionGroup = copyElement.SubstitutionGroup;
  2333.             newElement.UnhandledAttributes = copyElement.UnhandledAttributes;
  2334.             if (copyElement.MinOccurs != Decimal.One && this.Occurrence == InferenceOption.Relaxed) {
  2335.                 newElement.MinOccurs = copyElement.MinOccurs;
  2336.             }
  2337.             if (copyElement.MaxOccurs != Decimal.One) {
  2338.                 newElement.MaxOccurs = copyElement.MaxOccurs;
  2339.             }
  2340.             return newElement;
  2341.         }
  2342.        
  2343.         private static int GetSchemaType(XmlQualifiedName qname)
  2344.         {
  2345.             if (qname == SimpleTypes[HC_ST_boolean]) {
  2346.                 return TF_boolean | TF_string;
  2347.             }
  2348.             if (qname == SimpleTypes[HC_ST_byte]) {
  2349.                 return TF_byte | TF_short | TF_int | TF_long | TF_integer | TF_decimal | TF_float | TF_double | TF_string;
  2350.             }
  2351.             if (qname == SimpleTypes[HC_ST_unsignedByte]) {
  2352.                 return TF_byte | TF_short | TF_int | TF_long | TF_integer | TF_decimal | TF_float | TF_double | TF_unsignedByte | TF_unsignedShort | TF_unsignedInt | TF_unsignedLong | TF_string;
  2353.             }
  2354.             if (qname == SimpleTypes[HC_ST_short]) {
  2355.                 return TF_short | TF_int | TF_long | TF_integer | TF_decimal | TF_float | TF_double | TF_string;
  2356.             }
  2357.             if (qname == SimpleTypes[HC_ST_unsignedShort]) {
  2358.                 return TF_short | TF_int | TF_long | TF_integer | TF_decimal | TF_float | TF_double | TF_unsignedShort | TF_unsignedInt | TF_unsignedLong | TF_string;
  2359.             }
  2360.             if (qname == SimpleTypes[HC_ST_int]) {
  2361.                 return TF_int | TF_long | TF_integer | TF_decimal | TF_float | TF_double | TF_string;
  2362.             }
  2363.             if (qname == SimpleTypes[HC_ST_unsignedInt]) {
  2364.                 return TF_int | TF_long | TF_integer | TF_decimal | TF_float | TF_double | TF_unsignedInt | TF_unsignedLong | TF_string;
  2365.             }
  2366.             if (qname == SimpleTypes[HC_ST_long]) {
  2367.                 return TF_long | TF_integer | TF_decimal | TF_float | TF_double | TF_string;
  2368.             }
  2369.             if (qname == SimpleTypes[HC_ST_unsignedLong]) {
  2370.                 return TF_long | TF_integer | TF_decimal | TF_float | TF_double | TF_unsignedLong | TF_string;
  2371.             }
  2372.             if (qname == SimpleTypes[HC_ST_integer]) {
  2373.                 return TF_integer | TF_decimal | TF_float | TF_double | TF_string;
  2374.             }
  2375.             if (qname == SimpleTypes[HC_ST_decimal]) {
  2376.                 return TF_decimal | TF_float | TF_double | TF_string;
  2377.             }
  2378.             if (qname == SimpleTypes[HC_ST_float]) {
  2379.                 return TF_float | TF_double | TF_string;
  2380.             }
  2381.             if (qname == SimpleTypes[HC_ST_double]) {
  2382.                 return TF_double | TF_string;
  2383.             }
  2384.             if (qname == SimpleTypes[HC_ST_duration]) {
  2385.                 return TF_duration | TF_string;
  2386.             }
  2387.             if (qname == SimpleTypes[HC_ST_dateTime]) {
  2388.                 return TF_dateTime | TF_string;
  2389.             }
  2390.             if (qname == SimpleTypes[HC_ST_time]) {
  2391.                 return TF_time | TF_string;
  2392.             }
  2393.             if (qname == SimpleTypes[HC_ST_date]) {
  2394.                 return TF_date;
  2395.             }
  2396.             if (qname == SimpleTypes[HC_ST_gYearMonth]) {
  2397.                 return TF_gYearMonth;
  2398.             }
  2399.             if (qname == SimpleTypes[HC_ST_string]) {
  2400.                 return TF_string;
  2401.             }
  2402.             if (qname == null || qname.IsEmpty) {
  2403.                 return -1;
  2404.             }
  2405.             throw new XmlSchemaInferenceException(Res.SchInf_schematype, 0, 0);
  2406.         }
  2407.        
  2408.         internal void SetMinMaxOccurs(XmlSchemaElement el, bool setMaxOccurs)
  2409.         {
  2410.             if (this.Occurrence == InferenceOption.Relaxed) {
  2411.                 if (setMaxOccurs || el.MaxOccurs > 1) {
  2412.                     el.MaxOccurs = decimal.MaxValue;
  2413.                     //set it to unbounded
  2414.                 }
  2415.                 el.MinOccurs = 0;
  2416.             }
  2417.             else if (el.MinOccurs > 1) {
  2418.                 el.MinOccurs = 1;
  2419.             }
  2420.         }
  2421.        
  2422.        
  2423.     }
  2424. }

Developer Fusion