infer.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ DotNET / DotNET / 8.0 / untmp / whidbey / REDBITS / ndp / fx / src / Xml / System / Xml / schema / Inference / infer.cs / 1 / infer.cs

                            //------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// [....] 
// [....]
//----------------------------------------------------------------------------- 
 
using System;
using System.IO; 
using System.Xml;
using System.Collections;
using System.Diagnostics;
using System.Globalization; 
using System.Security.Permissions;
 
 

 
namespace System.Xml.Schema

{
        ///  
        /// 
        /// Infer class serves for infering XML Schema from given XML instance document. 
        ///  
        public sealed class XmlSchemaInference
        { 
            internal static XmlQualifiedName ST_boolean = new XmlQualifiedName("boolean", XmlSchema.Namespace);
            internal static XmlQualifiedName ST_byte = new XmlQualifiedName("byte", XmlSchema.Namespace);
            internal static XmlQualifiedName ST_unsignedByte = new XmlQualifiedName("unsignedByte", XmlSchema.Namespace);
            internal static XmlQualifiedName ST_short = new XmlQualifiedName("short", XmlSchema.Namespace); 
            internal static XmlQualifiedName ST_unsignedShort = new XmlQualifiedName("unsignedShort", XmlSchema.Namespace);
            internal static XmlQualifiedName ST_int = new XmlQualifiedName("int", XmlSchema.Namespace); 
            internal static XmlQualifiedName ST_unsignedInt = new XmlQualifiedName("unsignedInt", XmlSchema.Namespace); 
            internal static XmlQualifiedName ST_long = new XmlQualifiedName("long", XmlSchema.Namespace);
            internal static XmlQualifiedName ST_unsignedLong = new XmlQualifiedName("unsignedLong", XmlSchema.Namespace); 
            internal static XmlQualifiedName ST_integer = new XmlQualifiedName("integer", XmlSchema.Namespace);
            internal static XmlQualifiedName ST_decimal = new XmlQualifiedName("decimal", XmlSchema.Namespace);
            internal static XmlQualifiedName ST_float = new XmlQualifiedName("float", XmlSchema.Namespace);
            internal static XmlQualifiedName ST_double = new XmlQualifiedName("double", XmlSchema.Namespace); 
            internal static XmlQualifiedName ST_duration = new XmlQualifiedName("duration", XmlSchema.Namespace);
            internal static XmlQualifiedName ST_dateTime = new XmlQualifiedName("dateTime", XmlSchema.Namespace); 
            internal static XmlQualifiedName ST_time = new XmlQualifiedName("time", XmlSchema.Namespace); 
            internal static XmlQualifiedName ST_date = new XmlQualifiedName("date", XmlSchema.Namespace);
            internal static XmlQualifiedName ST_gYearMonth = new XmlQualifiedName("gYearMonth", XmlSchema.Namespace); 
            internal static XmlQualifiedName ST_string = new XmlQualifiedName("string", XmlSchema.Namespace);
            internal static XmlQualifiedName ST_anySimpleType = new XmlQualifiedName("anySimpleType", XmlSchema.Namespace);

            internal static XmlQualifiedName[] SimpleTypes = 
            {
                ST_boolean, 
                ST_byte, 
                ST_unsignedByte,
                ST_short, 
                ST_unsignedShort,
                ST_int,
                ST_unsignedInt,
                ST_long, 
                ST_unsignedLong,
                ST_integer, 
                ST_decimal, 
                ST_float,
                ST_double, 
                ST_duration,
                ST_dateTime,
                ST_time,
                ST_date, 
                ST_gYearMonth,
                ST_string 
            }; 

            internal const short HC_ST_boolean = 0; 
            internal const short HC_ST_byte = 1;
            internal const short HC_ST_unsignedByte = 2;
            internal const short HC_ST_short = 3;
            internal const short HC_ST_unsignedShort = 4; 
            internal const short HC_ST_int = 5;
            internal const short HC_ST_unsignedInt = 6; 
            internal const short HC_ST_long = 7; 
            internal const short HC_ST_unsignedLong = 8;
            internal const short HC_ST_integer = 9; 
            internal const short HC_ST_decimal = 10;
            internal const short HC_ST_float = 11;
            internal const short HC_ST_double = 12;
            internal const short HC_ST_duration = 13; 
            internal const short HC_ST_dateTime = 14;
            internal const short HC_ST_time = 15; 
            internal const short HC_ST_date = 16; 
            internal const short HC_ST_gYearMonth = 17;
            internal const short HC_ST_string = 18; 
            internal const short HC_ST_Count = HC_ST_string +1;


            internal const int TF_boolean = 1<
            public enum InferenceOption 
            {
                ///  
                Restricted, 
                /// 
                Relaxed 
            };

            /// 
            public InferenceOption Occurrence 
            {
                set 
                { 
                    this.occurrence = value;
                } 
                get
                {
                    return this.occurrence;
                } 
            }
 
            ///  
            public InferenceOption TypeInference
            { 
                set
                {
                    this.typeInference = value;
                } 
                get
                { 
                    return this.typeInference; 
                }
            } 

            /// 
            public XmlSchemaInference()
            { 
                this.nametable = new NameTable();
                this.NamespaceManager = new XmlNamespaceManager(nametable); 
                this.NamespaceManager.AddNamespace("xs", XmlSchema.Namespace); 
                this.schemaList = new ArrayList();
            } 

            /// 
            public XmlSchemaSet InferSchema(XmlReader instanceDocument)
            { 
                return InferSchema1(instanceDocument, new XmlSchemaSet(nametable));
            } 
 
            /// 
            public XmlSchemaSet InferSchema(XmlReader instanceDocument, XmlSchemaSet schemas) 
            {
                if (schemas == null)
                {
                    schemas = new XmlSchemaSet(nametable); 
                }
                return InferSchema1(instanceDocument, schemas); 
            } 
            internal XmlSchemaSet InferSchema1(XmlReader instanceDocument, XmlSchemaSet schemas)
            { 
                if (instanceDocument == null)
                {
                    throw new ArgumentNullException("instanceDocument");
                } 
                this.rootSchema = null;
                xtr = instanceDocument; 
                schemas.Compile(); 
                this.schemaSet = schemas;
                //schemas = new Hashtable(); 
                //while(xtr.Read())

                while (xtr.NodeType != XmlNodeType.Element && xtr.Read()) ;
 

                if (xtr.NodeType == XmlNodeType.Element) 
                { 
                    //Create and process the root element
                    TargetNamespace = xtr.NamespaceURI; 
                    if ( xtr.NamespaceURI == XmlSchema.Namespace)
                    {
                        throw new XmlSchemaInferenceException(Res.SchInf_schema, 0, 0);
                    } 
                    XmlSchemaElement xse = null;
                    foreach (XmlSchemaElement elem in schemas.GlobalElements.Values) 
                    { 
                        if (elem.Name == xtr.LocalName && elem.QualifiedName.Namespace == xtr.NamespaceURI)
                        { 
                            rootSchema = elem.Parent as XmlSchema;
                            xse = elem;
                            break;
                        } 
                    }
 
                    if (rootSchema == null) 
                    {
                        //rootSchema = CreateXmlSchema(xtr.NamespaceURI); 
                        xse = AddElement(xtr.LocalName, xtr.Prefix, xtr.NamespaceURI, null, null, -1);
                    }
                    else
                    { 
                        //bRefine = true;
                        InferElement(xse, false, rootSchema); 
                    } 

                  /*  foreach (ReplaceList listItem in schemaList) 
                    {
                        if (listItem.position < listItem.col.Count)
                        {
                            XmlSchemaElement particle = listItem.col[listItem.position] as XmlSchemaElement; 
                            if (particle != null && (particle.RefName.Namespace == XmlSchema.Namespace))
                            { 
                                XmlSchemaAny any = new XmlSchemaAny(); 
                                if (particle.MaxOccurs != 1)
                                { 
                                    any.MaxOccurs = particle.MaxOccurs;
                                }
                                if (particle.MinOccurs != 1)
                                { 
                                    any.MinOccurs = particle.MinOccurs;
                                } 
                                any.ProcessContents = XmlSchemaContentProcessing.Skip; 
                                any.MinOccurs = decimal.Zero;
                                any.Namespace = particle.RefName.Namespace; 
                                listItem.col[listItem.position] = any;
                            }
                        }
                    }*/ 
                    foreach(String prefix in this.NamespaceManager)
                    { 
                        if (!prefix.Equals("xml") && !prefix.Equals("xmlns")) 
                        {
                            String ns = this.NamespaceManager.LookupNamespace(this.nametable.Get(prefix)); 
                            if (ns.Length != 0) { //Do not add xmlns=""
                                rootSchema.Namespaces.Add(prefix, ns);
                            }
                        } 
                    }
                    Debug.Assert(this.rootSchema != null, "rootSchema is null"); 
                    schemas.Reprocess(rootSchema); 
                    schemas.Compile();
                    //break; 
                }
                else
                {
                    throw new XmlSchemaInferenceException(Res.SchInf_NoElement, 0, 0); 
                }
                return schemas; 
            } 

            private XmlSchemaAttribute AddAttribute(string localName, string prefix, string childURI, string attrValue, bool bCreatingNewType, XmlSchema parentSchema, XmlSchemaObjectCollection addLocation, XmlSchemaObjectTable compiledAttributes) 
            {
                if (childURI == XmlSchema.Namespace)
                {
                    throw new XmlSchemaInferenceException(Res.SchInf_schema, 0, 0); 
                }
 
                XmlSchemaAttribute xsa = null; 
                int AttributeType = -1;
                XmlSchemaAttribute returnedAttribute = null;    //this value will change to attributeReference if childURI!= parentURI 
                XmlSchema xs = null;
                bool add = true;

                Debug.Assert(compiledAttributes != null); //AttributeUses is never null 
                ICollection searchCollection;
                if (compiledAttributes.Count > 0) { 
                    searchCollection = compiledAttributes.Values; 
                }
                else { 
                    searchCollection = addLocation;
                }
                if (childURI == "http://www.w3.org/XML/1998/namespace")
                { 
                    XmlSchemaAttribute attributeReference = null;
                    //see if the reference exists 
                    attributeReference = FindAttributeRef(searchCollection, localName, childURI); 
                    if (attributeReference == null)
                    { 
                        attributeReference = new XmlSchemaAttribute();
                        attributeReference.RefName = new XmlQualifiedName(localName, childURI);
                        if (bCreatingNewType && this.Occurrence == InferenceOption.Restricted)
                        { 
                            attributeReference.Use = XmlSchemaUse.Required;
                        } 
                        else 
                        {
                            attributeReference.Use = XmlSchemaUse.Optional; 
                        }

                        addLocation.Add(attributeReference);
                    } 
                    returnedAttribute = attributeReference;
                } 
                else 
                {
                    if (childURI.Length == 0) 
                    {
                        xs = parentSchema;
                        add = false;
                    } 
                    else if (childURI != null && !schemaSet.Contains(childURI))
                    { 
                        /*if (parentSchema.AttributeFormDefault = XmlSchemaForm.Unqualified && childURI.Length == 0) 
                    {
                        xs = parentSchema; 
                        add = false;
                        break;
                    }*/
                        xs = new XmlSchema(); 
                        xs.AttributeFormDefault = XmlSchemaForm.Unqualified;
                        xs.ElementFormDefault = XmlSchemaForm.Qualified; 
                        if (childURI.Length != 0) 
                            xs.TargetNamespace = childURI;
                        //schemas.Add(childURI, xs); 
                        this.schemaSet.Add(xs);
                        if (prefix.Length != 0 && String.Compare(prefix, "xml", StringComparison.OrdinalIgnoreCase) != 0)
                            NamespaceManager.AddNamespace(prefix, childURI);
                    } 
                    else
                    { 
                        ArrayList col = this.schemaSet.Schemas(childURI) as ArrayList; 
                        if (col != null && col.Count > 0)
                        { 
                            xs = col[0] as XmlSchema;
                        }

                    } 
                    if (childURI.Length != 0) //
                    { 
                        XmlSchemaAttribute attributeReference = null; 
                        //see if the reference exists
                        attributeReference = FindAttributeRef(searchCollection, localName, childURI); 
                        if (attributeReference == null)
                        {
                            attributeReference = new XmlSchemaAttribute();
                            attributeReference.RefName = new XmlQualifiedName(localName, childURI); 
                            if (bCreatingNewType && this.Occurrence == InferenceOption.Restricted)
                            { 
                                attributeReference.Use = XmlSchemaUse.Required; 
                            }
                            else 
                            {
                                attributeReference.Use = XmlSchemaUse.Optional;
                            }
 
                            addLocation.Add(attributeReference);
                        } 
                        returnedAttribute = attributeReference; 

                        //see if the attribute exists on the global level 
                        xsa = FindAttribute(xs.Items, localName);
                        if (xsa == null)
                        {
                            xsa = new XmlSchemaAttribute(); 
                            xsa.Name = localName;
                            xsa.SchemaTypeName = RefineSimpleType(attrValue, ref AttributeType); 
                            xsa.LineNumber = AttributeType; //we use LineNumber to store flags of valid types 
                            xs.Items.Add(xsa);
 
                        }
                        else
                        {
                            if (xsa.Parent == null) 
                            {
                                AttributeType = xsa.LineNumber; // we use LineNumber to store flags of valid types 
                            } 
                            else
                            { 
                                AttributeType = GetSchemaType(xsa.SchemaTypeName);
                                xsa.Parent = null;
                            }
                            xsa.SchemaTypeName = RefineSimpleType(attrValue, ref AttributeType); 
                            xsa.LineNumber = AttributeType; // we use LineNumber to store flags of valid types
                        } 
                    } 
                    else
                    { 
                        xsa = FindAttribute(searchCollection, localName);
                        if (xsa == null)
                        {
                            xsa = new XmlSchemaAttribute(); 
                            xsa.Name = localName;
                            xsa.SchemaTypeName = RefineSimpleType(attrValue, ref AttributeType); 
                            xsa.LineNumber = AttributeType; // we use LineNumber to store flags of valid types 
                            if (bCreatingNewType && this.Occurrence == InferenceOption.Restricted)
                                xsa.Use = XmlSchemaUse.Required; 
                            else
                                xsa.Use = XmlSchemaUse.Optional;
                            addLocation.Add(xsa);
                            if (xs.AttributeFormDefault != XmlSchemaForm.Unqualified) 
                            {
                                xsa.Form = XmlSchemaForm.Unqualified; 
                            } 
                        }
                        else 
                        {
                            if (xsa.Parent == null)
                            {
                                AttributeType = xsa.LineNumber; // we use LineNumber to store flags of valid types 
                            }
                            else 
                            { 
                                AttributeType = GetSchemaType(xsa.SchemaTypeName);
                                xsa.Parent = null; 
                            }
                            xsa.SchemaTypeName = RefineSimpleType(attrValue, ref AttributeType);
                            xsa.LineNumber = AttributeType; // we use LineNumber to store flags of valid types
                        } 
                        returnedAttribute = xsa;
                    } 
                } 
                string nullString = null;
                if (add && childURI != parentSchema.TargetNamespace) 
                {
                    foreach (XmlSchemaExternal external in parentSchema.Includes)
                    {
                        XmlSchemaImport import = external as XmlSchemaImport; 
                        if (import == null)
                        { 
                            continue; 
                        }
                        if (import.Namespace == childURI) 
                        {
                            add = false;
                        }
                    } 
                    if (add)
                    { 
                        XmlSchemaImport import = new XmlSchemaImport(); 
                        import.Schema = xs;
                        if (childURI.Length != 0) 
                        {
                            nullString = childURI;
                        }
                        import.Namespace = nullString; 
                        parentSchema.Includes.Add(import);
                    } 
                } 

 
                return returnedAttribute;
            }

            private XmlSchema CreateXmlSchema(string targetNS) 
            {
                Debug.Assert(targetNS == null || targetNS.Length > 0 , "targetns for schema is empty"); 
                XmlSchema xs = new XmlSchema(); 
                xs.AttributeFormDefault = XmlSchemaForm.Unqualified;
                xs.ElementFormDefault = XmlSchemaForm.Qualified; 
                xs.TargetNamespace = targetNS;
                this.schemaSet.Add(xs);
                return xs;
            } 

            private XmlSchemaElement AddElement(string localName, string prefix, string childURI, XmlSchema parentSchema, XmlSchemaObjectCollection addLocation, int positionWithinCollection) 
            { 
                if (childURI == XmlSchema.Namespace)
                { 
                    throw new XmlSchemaInferenceException(Res.SchInf_schema, 0, 0);
                }

                XmlSchemaElement xse = null; 
                XmlSchemaElement returnedElement = xse; //this value will change to elementReference if childURI!= parentURI
                XmlSchema xs = null; 
                bool bCreatingNewType = true; 
                if (childURI == String.Empty)
                { 
                    childURI = null;
                }
                // The new element belongs to the same ns as parent and addlocation is not null
                if (parentSchema != null && childURI == parentSchema.TargetNamespace) 
                {
                    xse = new XmlSchemaElement(); 
                    xse.Name = localName; 
                    xs = parentSchema;
                    if (xs.ElementFormDefault != XmlSchemaForm.Qualified && addLocation != null) 
                    {
                        xse.Form = XmlSchemaForm.Qualified;
                    }
                } 
                else if (schemaSet.Contains(childURI))
                { 
                    xse = this.FindGlobalElement(childURI, localName, out xs); 
                    if (xse == null)
                    { 
                        ArrayList col = this.schemaSet.Schemas(childURI)as ArrayList;
                        if (col != null && col.Count > 0 )
                        {
                            xs = col[0] as XmlSchema; 
                        }
                        xse = new XmlSchemaElement(); 
                        xse.Name = localName; 
                        xs.Items.Add(xse);
                    } 
                    else
                        bCreatingNewType = false;

                } 
                else
                { 
                    xs = CreateXmlSchema(childURI); 
                    if (prefix.Length!=0)
                        NamespaceManager.AddNamespace(prefix, childURI); 
                    xse=new XmlSchemaElement();
                    xse.Name = localName;
                    xs.Items.Add(xse);  //add global element declaration only when creating new schema
                } 
                if (parentSchema == null)
                { 
                    parentSchema = xs; 
                    this.rootSchema = parentSchema;
                } 

                if (childURI != parentSchema.TargetNamespace )
                {
                    bool add = true; 

                    foreach(XmlSchemaExternal external in parentSchema.Includes) 
                    { 
                        XmlSchemaImport import = external as XmlSchemaImport;
                        if (import == null) 
                        {
                            continue;
                        }
                        //Debug.WriteLine(import.Schema.TargetNamespace); 

                        if (import.Namespace == childURI) 
                        { 
                            add = false;
                        } 
                    }
                    if (add)
                    {
                        XmlSchemaImport import = new XmlSchemaImport(); 
                        import.Schema = xs;
                        import.Namespace = childURI; 
                        parentSchema.Includes.Add(import); 
                    }
                } 
                returnedElement = xse;
                if (addLocation != null)
                {
                    if (childURI == parentSchema.TargetNamespace ) 
                    {
                        if (this.Occurrence == InferenceOption.Relaxed /*&& parentSchema.Items != addLocation*/) 
                        { 
                            xse.MinOccurs = 0;
                        } 
                        if (positionWithinCollection == -1)
                        {
                            positionWithinCollection = addLocation.Add(xse);
                        } 
                        else
                        { 
                            addLocation.Insert(positionWithinCollection, xse); 
                        }
                    } 
                    else
                    {
                        XmlSchemaElement elementReference = new XmlSchemaElement();
                        elementReference.RefName = new XmlQualifiedName(localName, childURI); 
                        if (this.Occurrence == InferenceOption.Relaxed)
                        { 
                            elementReference.MinOccurs = 0; 
                        }
                        if (positionWithinCollection == -1) 
                        {
                            positionWithinCollection = addLocation.Add(elementReference);
                        }
                        else 
                        {
                            addLocation.Insert(positionWithinCollection, elementReference); 
                        } 
                        returnedElement = elementReference;
                       /* if (childURI == XmlSchema.Namespace) 
                        {
                            schemaList.Add(new ReplaceList(addLocation, positionWithinCollection));
                        }*/
                    } 
                }
 
 
                InferElement(xse, bCreatingNewType, xs);
 
                return returnedElement;
            }

            ///  
            /// Sets type of the xse based on the currently read element.
            /// If the type is already set, verifies that it matches the instance and if not, updates the type to validate the instance. 
            ///  
            /// XmlSchemaElement corresponding to the element just read by the xtr XmlTextReader
            /// true if the type is newly created, false if the type already existed and matches the current element name 
            /// namespaceURI of the parent element. Used to distinguish if ref= should be used when parent is in different ns than child.
            internal void InferElement(XmlSchemaElement xse, bool bCreatingNewType, XmlSchema parentSchema)
            {
 
                bool bEmptyElement = xtr.IsEmptyElement;
                int lastUsedSeqItem = -1; 
 
                Hashtable table = new Hashtable();
                XmlSchemaType schemaType = GetEffectiveSchemaType(xse, bCreatingNewType); 
                XmlSchemaComplexType ct = schemaType as XmlSchemaComplexType;

                //infer type based on content of the current element
                if (xtr.MoveToFirstAttribute()) 
                {
                    ProcessAttributes(ref xse, schemaType, bCreatingNewType, parentSchema); 
                } 
                else
                { 
                    if (!bCreatingNewType && ct != null)
                    {   //if type already exists and can potentially have attributes
                        MakeExistingAttributesOptional(ct, null);
                    } 
                }
                if (ct == null || ct == XmlSchemaComplexType.AnyType) { //It was null or simple type, after processing attributes, this might have been set 
                    ct = xse.SchemaType as XmlSchemaComplexType; 
                }
                //xse's type is set either to complex type if attributes exist or null 
                if (bEmptyElement)  //
                {
                    if (!bCreatingNewType)
                    { 
                        if (null != ct)
                        { 
                            if (null!= ct.Particle ) 

                            { 
                                ct.Particle.MinOccurs = 0;
                            }
                            else if (null != ct.ContentModel)
                            { 
                                XmlSchemaSimpleContentExtension sce = CheckSimpleContentExtension(ct);
                                sce.BaseTypeName = ST_string; 
                                sce.LineNumber = TF_string; 
                            }
                        } 
                        else if (!xse.SchemaTypeName.IsEmpty)
                        {
                            xse.LineNumber = TF_string;
                            xse.SchemaTypeName = ST_string; 
                        }
                    } 
                    else 
                    {
                        xse.LineNumber = TF_string; 
                        //xse.SchemaTypeName = ST_string; //My change
                    }
                    return; //We are done processing this element - all attributes are already added
                } 
                bool bWhiteSpace = false;
                do 
                { 
                    xtr.Read();
                    if (xtr.NodeType == XmlNodeType.Whitespace) 
                    {
                        bWhiteSpace = true;
                    }
                    if (xtr.NodeType == XmlNodeType.EntityReference) 
                    {
                        throw new XmlSchemaInferenceException(Res.SchInf_entity, 0, 0); 
                    } 
                } while( (!xtr.EOF) && (xtr.NodeType != XmlNodeType.EndElement) && (xtr.NodeType != XmlNodeType.CDATA)&&(xtr.NodeType != XmlNodeType.Element)&&(xtr.NodeType != XmlNodeType.Text) );
 
                if (xtr.NodeType == XmlNodeType.EndElement)
                {
                    if (bWhiteSpace) {
                        if (ct != null) 
                        {
                            if (null != ct.ContentModel) 
                            { 
                                XmlSchemaSimpleContentExtension sce = CheckSimpleContentExtension(ct);
                                sce.BaseTypeName = ST_string; 
                                sce.LineNumber = TF_string;
                            }
                            else if (bCreatingNewType)
                            { 
                                //attributes exist, but both Particle and ContentModel == null - this must be complex type with simpleContent extension
                                XmlSchemaSimpleContent sc = new XmlSchemaSimpleContent(); 
                                ct.ContentModel = sc; 
                                XmlSchemaSimpleContentExtension sce = new XmlSchemaSimpleContentExtension();
                                sc.Content = sce; 

                                MoveAttributes(ct, sce, bCreatingNewType);

                                sce.BaseTypeName = ST_string; 
                                sce.LineNumber = TF_string;
                            } 
                            else 
                                ct.IsMixed = true;
                        } 
                        else
                        {
                            xse.SchemaTypeName = ST_string;
                            xse.LineNumber = TF_string; 
                        }
                    } 
                    if (bCreatingNewType) 
                    {
                        xse.LineNumber = TF_string; 
                        //xse.SchemaTypeName = ST_string; //my change
                    }
                    else
                    { 
                        if (null != ct)
                        { 
                            if (null!= ct.Particle) 
                            {
                                ct.Particle.MinOccurs = 0; 
                            }
                            else if (null != ct.ContentModel)
                            {
                                XmlSchemaSimpleContentExtension sce = CheckSimpleContentExtension(ct); 
                                sce.BaseTypeName = ST_string;
                                sce.LineNumber = TF_string; 
                            } 
                        }
                        else if (!xse.SchemaTypeName.IsEmpty) 
                        {
                            xse.LineNumber = TF_string;
                            xse.SchemaTypeName = ST_string;
                        } 
                    }
 
                    return; // 
                }
                int iChildNumber = 0; 
                bool bCreatingNewSequence = false;
                while (!xtr.EOF && (xtr.NodeType != XmlNodeType.EndElement))
                {
                    bool bNextNodeAlreadyRead = false;  //In some cases we have to look ahead one node. If true means that we did look ahead. 
                    iChildNumber++;
                    if ((xtr.NodeType == XmlNodeType.Text) || (xtr.NodeType == XmlNodeType.CDATA) ) //node can be simple type, complex with simple content or complex with mixed content 
                    { 
                        if (null != ct)
                        { 
                            if (null != ct.Particle)
                            {
                                ct.IsMixed = true;
                                if (iChildNumber==1) 
                                {
                                    //if this is the only child and other elements do not follow, we must set particle minOccurs="0" 
                                    do{ xtr.Read();} 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))); 
                                    bNextNodeAlreadyRead = true;
                                    if (xtr.NodeType == XmlNodeType.EndElement) 
                                        ct.Particle.MinOccurs=decimal.Zero;
                                }
                            }
                            else if (null!=ct.ContentModel) 
                            {   //complexType with simpleContent
                                XmlSchemaSimpleContentExtension sce = CheckSimpleContentExtension(ct); 
                                if ((xtr.NodeType == XmlNodeType.Text) && (iChildNumber==1)) 
                                {
                                    int SimpleType = -1; 
                                    if (xse.Parent == null)
                                    {
                                        SimpleType = sce.LineNumber; // we use LineNumber to represent valid type flags
                                    } 
                                    else
                                    { 
                                        SimpleType = GetSchemaType(sce.BaseTypeName); 
                                        xse.Parent = null;
                                    } 
                                    sce.BaseTypeName = RefineSimpleType(xtr.Value, ref SimpleType);
                                    sce.LineNumber = SimpleType; // we use LineNumber to represent valid type flags
                                }
                                else 
                                {
                                    sce.BaseTypeName = ST_string; 
                                    sce.LineNumber = TF_string; 
                                }
                            } 
                            else
                            {
                                //attributes exist, but both Particle and ContentModel == null - this must be complex type with simpleContent extension
                                XmlSchemaSimpleContent sc = new XmlSchemaSimpleContent(); 
                                ct.ContentModel = sc;
                                XmlSchemaSimpleContentExtension sce = new XmlSchemaSimpleContentExtension(); 
                                sc.Content = sce; 

                                MoveAttributes(ct, sce, bCreatingNewType); 

                                if (xtr.NodeType == XmlNodeType.Text)
                                {
                                    int TypeFlags; 
                                    if(!bCreatingNewType)
                                        //previously this was empty element 
                                        TypeFlags=TF_string; 
                                    else
                                        TypeFlags = -1; 
                                    sce.BaseTypeName = RefineSimpleType(xtr.Value, ref TypeFlags);
                                    sce.LineNumber = TypeFlags; // we use LineNumber to store flags of valid types
                                }
                                else 
                                {
                                    sce.BaseTypeName = ST_string; 
                                    sce.LineNumber = TF_string; 
                                }
 
                            }
                        }
                        else
                        {   //node is currently empty or with SimpleType 
                            //node will become simple type
                            if (iChildNumber>1) 
                            { 
                                //more than one consecutive text nodes probably with PI in between
                                xse.SchemaTypeName = ST_string; 
                                xse.LineNumber = TF_string;// we use LineNumber to store flags of valid types
                            }
                            else
                            { 
                                int TypeFlags = -1;
                                if (bCreatingNewType) 
                                    if (xtr.NodeType == XmlNodeType.Text) 
                                    {
                                        xse.SchemaTypeName = RefineSimpleType(xtr.Value, ref TypeFlags); 
                                        xse.LineNumber = TypeFlags; // we use LineNumber to store flags of valid types
                                    }
                                    else
                                    { 
                                        xse.SchemaTypeName = ST_string;
                                        xse.LineNumber = TF_string;// we use LineNumber to store flags of valid types 
                                    } 
                                else if (xtr.NodeType == XmlNodeType.Text)
                                { 
                                    if (xse.Parent == null)
                                    {
                                        TypeFlags = xse.LineNumber;
                                    } 
                                    else
                                    { 
                                        TypeFlags = GetSchemaType(xse.SchemaTypeName); 
                                        if (TypeFlags == -1 && xse.LineNumber == TF_string) { //Since schemaTypeName is not set for empty elements ()
                                            TypeFlags = TF_string; 
                                        }
                                        xse.Parent = null;
                                    }
                                    xse.SchemaTypeName = RefineSimpleType(xtr.Value, ref TypeFlags);    //simple type 
                                    xse.LineNumber = TypeFlags; // we use LineNumber to store flags of valid types
                                } 
                                else 
                                {
                                    xse.SchemaTypeName = ST_string; 
                                    xse.LineNumber = TF_string;// we use LineNumber to store flags of valid types
                                }
                            }
                        } 
                    }
                    else if (xtr.NodeType == XmlNodeType.Element) 
                    { 
                        XmlQualifiedName qname = new XmlQualifiedName(xtr.LocalName, xtr.NamespaceURI);
                        bool Maxoccursflag = false; 
                        if (table.Contains(qname))
                        {
                            Maxoccursflag = true;
                        } 
                        else
                        { 
                            table.Add(qname, null); 
                        }
                        if (ct==null) 
                        { //untill now the element was empty or SimpleType - it now becomes complex type
                            ct = new XmlSchemaComplexType();
                            xse.SchemaType = ct;
                            if (!xse.SchemaTypeName.IsEmpty) // 
                            {
                                ct.IsMixed=true; 
                                xse.SchemaTypeName = XmlQualifiedName.Empty; 
                            }
                        } 
                        if (ct.ContentModel !=null)
                        {   //type was previously identified as simple content extension - we need to convert it to sequence
                            XmlSchemaSimpleContentExtension sce = CheckSimpleContentExtension(ct);
                            MoveAttributes(sce, ct); 
                            ct.ContentModel = null;
                            ct.IsMixed = true; 
                            if (ct.Particle != null) 
                                throw new XmlSchemaInferenceException(Res.SchInf_particle, 0, 0);
                            ct.Particle = new XmlSchemaSequence(); 
                            bCreatingNewSequence = true;
                            XmlSchemaElement subelement = AddElement(xtr.LocalName, xtr.Prefix, xtr.NamespaceURI, parentSchema,((XmlSchemaSequence)ct.Particle).Items, -1);
                            lastUsedSeqItem = 0;
                            if (!bCreatingNewType) 
                                ct.Particle.MinOccurs=0;    //previously this was simple type so subelements did not exist
                        } 
                        else if (ct.Particle == null) 
                        {
                            ct.Particle = new XmlSchemaSequence(); 
                            bCreatingNewSequence = true;
                            XmlSchemaElement subelement = AddElement(xtr.LocalName, xtr.Prefix, xtr.NamespaceURI, parentSchema,((XmlSchemaSequence)ct.Particle).Items, -1);
                            if (!bCreatingNewType)
                            { 
                                ((XmlSchemaSequence)ct.Particle).MinOccurs = decimal.Zero;
                                //  subelement.MinOccurs = decimal.Zero; 
                            } 

                            lastUsedSeqItem = 0; 
                        }
                        else
                        {
                            bool bParticleChanged = false; 
                            XmlSchemaElement subelement = FindMatchingElement(bCreatingNewType || bCreatingNewSequence, xtr, ct, ref lastUsedSeqItem, ref bParticleChanged, parentSchema, Maxoccursflag);
                        } 
                    } 
                    else if (xtr.NodeType == XmlNodeType.Text)
                    { 
                        if (ct==null)
                            throw new XmlSchemaInferenceException(Res.SchInf_ct, 0, 0);
                        ct.IsMixed = true;
                    } 
                    do
                    { 
                        if (xtr.NodeType == XmlNodeType.EntityReference) 
                        {
                            throw new XmlSchemaInferenceException(Res.SchInf_entity, 0, 0); 

                        }
                        if (!bNextNodeAlreadyRead)
                        { 
                            xtr.Read();
                        } 
                        else 
                        {
                            bNextNodeAlreadyRead = false; 
                        }
                    } while( (!xtr.EOF) && (xtr.NodeType != XmlNodeType.EndElement) && (xtr.NodeType != XmlNodeType.CDATA)&&(xtr.NodeType != XmlNodeType.Element)&&(xtr.NodeType != XmlNodeType.Text));
                }
                if (lastUsedSeqItem != -1) 
                {
                    //Verify if all elements in a sequence exist, if not set MinOccurs=0 
                    while (++lastUsedSeqItem < ((XmlSchemaSequence)ct.Particle).Items.Count) 
                    {
                        if (((XmlSchemaSequence)ct.Particle).Items[lastUsedSeqItem].GetType() != typeof (XmlSchemaElement)) 
                            throw new XmlSchemaInferenceException(Res.SchInf_seq, 0 , 0);
                        XmlSchemaElement subElement = (XmlSchemaElement) ((XmlSchemaSequence)ct.Particle).Items[lastUsedSeqItem];
                        subElement.MinOccurs = 0;
                    } 
                }
 
            } 

            private XmlSchemaSimpleContentExtension CheckSimpleContentExtension(XmlSchemaComplexType ct) { 
                XmlSchemaSimpleContent sc = ct.ContentModel as XmlSchemaSimpleContent;
                if (sc == null) {
                    throw new XmlSchemaInferenceException(Res.SchInf_simplecontent, 0, 0);
                } 
                XmlSchemaSimpleContentExtension sce = sc.Content as XmlSchemaSimpleContentExtension;
                if (sce == null) { 
                    throw new XmlSchemaInferenceException(Res.SchInf_extension, 0, 0); 
                }
                return sce; 
            }

            private XmlSchemaType GetEffectiveSchemaType(XmlSchemaElement elem, bool bCreatingNewType) {
                XmlSchemaType effectiveSchemaType = null; 
                if (!bCreatingNewType && elem.ElementSchemaType != null) {
                    effectiveSchemaType = elem.ElementSchemaType; 
                } 
                else { //creating new type, hence look up pre-compiled info
                    Debug.Assert(elem.ElementDecl == null); 
                    if (elem.SchemaType != null) {
                        effectiveSchemaType = elem.SchemaType;
                    }
                    else if (elem.SchemaTypeName != XmlQualifiedName.Empty) { 
                        effectiveSchemaType = schemaSet.GlobalTypes[elem.SchemaTypeName] as XmlSchemaType;
                        if (effectiveSchemaType == null) { 
                            effectiveSchemaType = XmlSchemaType.GetBuiltInSimpleType(elem.SchemaTypeName); 
                        }
                        if (effectiveSchemaType == null) { 
                            effectiveSchemaType = XmlSchemaType.GetBuiltInComplexType(elem.SchemaTypeName);
                        }
                    }
                } 
                return effectiveSchemaType;
            } 
            ///  
            /// Verifies that the current element has its corresponding element in the sequence and order is the same.
            /// If the order is not the same, it changes the particle from Sequence to Sequence with Choice. 
            /// If there is more elements of the same kind in the sequence, sets maxOccurs to unbounded
            /// 
            /// True if this is a new type. This is important for setting minOccurs=0 for elements that did not exist in a particle.
            /// text reader positioned to the current element 
            /// complex type with Sequence or Choice Particle
            /// ordinal number in the sequence to indicate current sequence position 
            /// 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. 
            /// This indicates to the caller if Sequence was changed to Choice
            internal XmlSchemaElement FindMatchingElement(bool bCreatingNewType, XmlReader xtr,XmlSchemaComplexType ct, ref int lastUsedSeqItem, ref bool bParticleChanged, XmlSchema parentSchema, bool setMaxoccurs) 
            {
                if (xtr.NamespaceURI == XmlSchema.Namespace)
                {
                    throw new XmlSchemaInferenceException(Res.SchInf_schema, 0, 0); 
                }
 
                bool bItemNotUsedYet = ((lastUsedSeqItem == -1)? true: false); 
                XmlSchemaObjectCollection minOccursCandidates = new XmlSchemaObjectCollection(); //elements that are skipped in the sequence and need minOccurs modified.
                if (ct.Particle.GetType() == typeof (XmlSchemaSequence)) 
                {
                    string childURI = xtr.NamespaceURI;
                    if (childURI.Length == 0)
                    { 
                        childURI = null;
                    } 
                    XmlSchemaSequence xss = (XmlSchemaSequence) ct.Particle; 
                    if (xss.Items.Count < 1 && !bCreatingNewType)
                    { 
                        lastUsedSeqItem = 0;
                        XmlSchemaElement e = AddElement(xtr.LocalName, xtr.Prefix, xtr.NamespaceURI, parentSchema, xss.Items,-1);
                        e.MinOccurs = 0;
                        return e; 
                    }
                    if (xss.Items[0].GetType() == typeof (XmlSchemaChoice)) 
                    {   // ... 
                        XmlSchemaChoice xsch = (XmlSchemaChoice) xss.Items[0];
                        foreach(XmlSchemaParticle particle in xsch.Items) 
                        {
                            XmlSchemaElement el = particle as XmlSchemaElement;
                            if (el == null)
                            { 
                                throw new XmlSchemaInferenceException(Res.SchInf_UnknownParticle, 0, 0);
                            } 
                            if ((el.Name == xtr.LocalName) &&( parentSchema.TargetNamespace == childURI)) 
                            {   // element is in the same namespace
                                InferElement(el, false, parentSchema); 
                                SetMinMaxOccurs(el, setMaxoccurs);
                                return el;
                            }
                            else if ((el.RefName.Name == xtr.LocalName) && (el.RefName.Namespace == xtr.NamespaceURI)) 
                            {
                                XmlSchemaElement referencedElement = FindGlobalElement(childURI, xtr.LocalName, out parentSchema); 
                                InferElement(referencedElement, false, parentSchema); 
                                SetMinMaxOccurs(el, setMaxoccurs);
                                return referencedElement; 
                            }
                        }
                        XmlSchemaElement subElement = AddElement(xtr.LocalName, xtr.Prefix, xtr.NamespaceURI, parentSchema, xsch.Items,-1);
                        return subElement; 
                    }
                    else 
                    {   //this should be sequence of elements 
                        int iSeqItem = 0;   //iterator through schema sequence items
                        if (lastUsedSeqItem >= 0) 
                            iSeqItem = lastUsedSeqItem;
                        XmlSchemaParticle particle = xss.Items[iSeqItem] as XmlSchemaParticle;
                        XmlSchemaElement el = particle as XmlSchemaElement;
                        if (el == null) 
                        {
                            throw new XmlSchemaInferenceException(Res.SchInf_UnknownParticle, 0, 0); 
                        } 
                        if (el.Name == xtr.LocalName && parentSchema.TargetNamespace == childURI)
                        { 
                            if (!bItemNotUsedYet)   //read: if item was already used one or more times
                                el.MaxOccurs = decimal.MaxValue;    //set it to unbounded
                            lastUsedSeqItem = iSeqItem;
                            InferElement(el, false, parentSchema); 
                            SetMinMaxOccurs(el, false);
                            return el; 
                        } 
                        else if (el.RefName.Name == xtr.LocalName && el.RefName.Namespace == xtr.NamespaceURI)
                        { 
                            if (!bItemNotUsedYet)   //read: if item was already used one or more times
                                el.MaxOccurs = decimal.MaxValue;    //set it to unbounded
                            lastUsedSeqItem = iSeqItem;
                            XmlSchemaElement referencedElement = FindGlobalElement(childURI, xtr.LocalName, out parentSchema); 
                            InferElement(referencedElement, false, parentSchema);
                            SetMinMaxOccurs(el, false); 
                            return el; 
                        }
                        if (bItemNotUsedYet && el.MinOccurs!=decimal.Zero) 
                            minOccursCandidates.Add(el);
                        iSeqItem++;
                        while (iSeqItem < xss.Items.Count)
                        { 
                            particle = xss.Items[iSeqItem] as XmlSchemaParticle;
                            el = particle as XmlSchemaElement; 
                            if (el == null) 
                            {
                                throw new XmlSchemaInferenceException(Res.SchInf_UnknownParticle, 0, 0); 
                            }
                            if (el.Name == xtr.LocalName && parentSchema.TargetNamespace == childURI)
                            {
                                lastUsedSeqItem = iSeqItem; 
                                foreach (XmlSchemaElement minOccursElement in minOccursCandidates)
                                    minOccursElement.MinOccurs = decimal.Zero; 
                                InferElement(el, false, parentSchema); 
                                SetMinMaxOccurs(el, setMaxoccurs);
                                return el; 
                            }
                            else if (el.RefName.Name == xtr.LocalName && el.RefName.Namespace == xtr.NamespaceURI)
                            {
                                lastUsedSeqItem = iSeqItem; 
                                foreach (XmlSchemaElement minOccursElement in minOccursCandidates)
                                    minOccursElement.MinOccurs = decimal.Zero; 
                                XmlSchemaElement referencedElement = FindGlobalElement(childURI, xtr.LocalName, out parentSchema); 
                                InferElement(referencedElement, false, parentSchema);
                                SetMinMaxOccurs(el, setMaxoccurs); 
                                return referencedElement;
                            }

 
                            minOccursCandidates.Add(el);
                            iSeqItem++; 
                        } 

                        //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 
                        XmlSchemaElement subElement = null;
                        XmlSchemaElement actualElement = null;
                        //
 
                        if (parentSchema.TargetNamespace == childURI)
                        { 
                            subElement = FindElement(xss.Items, xtr.LocalName); 
                            actualElement = subElement;
                        } 
                        else
                        {
                            subElement = FindElementRef(xss.Items, xtr.LocalName, xtr.NamespaceURI);
                            if (subElement != null) 
                            {
                                actualElement = FindGlobalElement(childURI, xtr.LocalName, out parentSchema); 
                            } 
                        }
                        if (null != subElement) 
                        {
                            XmlSchemaChoice xsc = new XmlSchemaChoice();
                            xsc.MaxOccurs = decimal.MaxValue;
                            SetMinMaxOccurs(subElement, setMaxoccurs); 
                            InferElement(actualElement, false, parentSchema);
                            foreach(XmlSchemaElement copyElement in xss.Items) 
                            { 
                                xsc.Items.Add(CreateNewElementforChoice(copyElement));
                            } 
                            xss.Items.Clear();
                            xss.Items.Add(xsc);
                            return subElement;
                        } 
                        else
                        { 
                            subElement = AddElement(xtr.LocalName, xtr.Prefix, xtr.NamespaceURI, parentSchema, xss.Items, ++lastUsedSeqItem); 
                            if (!bCreatingNewType)
                                subElement.MinOccurs = decimal.Zero; 
                            return subElement;
                        }
                    }
                } 
                else
                { 
                    throw new XmlSchemaInferenceException(Res.SchInf_noseq, 0, 0); 
                }
 
            }
            internal void ProcessAttributes(ref XmlSchemaElement xse, XmlSchemaType effectiveSchemaType, bool bCreatingNewType, XmlSchema parentSchema)
            {
                XmlSchemaObjectCollection attributesSeen = new XmlSchemaObjectCollection(); 
                XmlSchemaComplexType ct = effectiveSchemaType as XmlSchemaComplexType;
 
                Debug.Assert(xtr.NodeType == XmlNodeType.Attribute); 
                do
                { 
                    if (xtr.NamespaceURI == XmlSchema.Namespace)
                    {
                        throw new XmlSchemaInferenceException(Res.SchInf_schema, 0, 0);
                    } 

                    if (xtr.NamespaceURI == "http://www.w3.org/2000/xmlns/") 
                    { 
                        if (xtr.Prefix=="xmlns")
                            NamespaceManager.AddNamespace(xtr.LocalName, xtr.Value); 
                    }
                    else if (xtr.NamespaceURI == "http://www.w3.org/2001/XMLSchema-instance")
                    {
                        string localName = xtr.LocalName; 
                        if (localName == "nil")
                        { 
                            xse.IsNillable = true; 
                        }
                        else if (localName != "type" && localName != "schemaLocation" && localName != "noNamespaceSchemaLocation") 
                        {
                            throw new XmlSchemaInferenceException(Res.Sch_NotXsiAttribute,localName);
                        }
                    } 
                    else
                    { 
                        if (ct == null || ct == XmlSchemaComplexType.AnyType) 
                        {
                            ct = new XmlSchemaComplexType(); 
                            xse.SchemaType = ct;
                        }

                        XmlSchemaAttribute xsa=null; 
                        //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
                        //Check that it is a simple type by checking typeCode 
                        //Switch to complex type simple content extension 
                        if (effectiveSchemaType != null && effectiveSchemaType.Datatype != null && !xse.SchemaTypeName.IsEmpty)
                        { 
                            //type was previously simple type, now it will become complex with simple type extension
                            Debug.Assert(ct != null);
                            XmlSchemaSimpleContent sc = new XmlSchemaSimpleContent();
                            ct.ContentModel = sc; 
                            XmlSchemaSimpleContentExtension sce = new XmlSchemaSimpleContentExtension();
                            sc.Content = sce; 
                            sce.BaseTypeName = xse.SchemaTypeName; 
                            sce.LineNumber = xse.LineNumber;
                            xse.LineNumber = 0; 
                            xse.SchemaTypeName = XmlQualifiedName.Empty; //re-set the name
                        }

                        Debug.Assert(ct != null); //either the user-defined type itself is a complex type or we switched from a simple type to a complex type 
                        if (ct.ContentModel != null)
                        { 
                            XmlSchemaSimpleContentExtension sce = CheckSimpleContentExtension(ct); 
                            Debug.Assert(sce != null);
                            xsa = AddAttribute(xtr.LocalName, xtr.Prefix, xtr.NamespaceURI, xtr.Value, bCreatingNewType, parentSchema, sce.Attributes, ct.AttributeUses); 
                        }
                        else //add atributes directly to complex type
                        {
                            xsa = AddAttribute(xtr.LocalName, xtr.Prefix, xtr.NamespaceURI, xtr.Value, bCreatingNewType, parentSchema, ct.Attributes, ct.AttributeUses); 
                        }
                        if (xsa != null) { 
                            attributesSeen.Add(xsa); 
                        }
                    } 

                } while (xtr.MoveToNextAttribute());
                if (!bCreatingNewType)
                { 
                    //make attributes that did not appear this time optional
                    if (ct!=null) { 
                        MakeExistingAttributesOptional(ct, attributesSeen); 
                    }
                } 
            }

            private void MoveAttributes(XmlSchemaSimpleContentExtension scExtension,  XmlSchemaComplexType ct) {
                //copy all attributes from the simple content to the complex type 
                //This is ok since when we move from complex type to simple content extension we copy from AttributeUses property
                foreach (XmlSchemaAttribute attr in scExtension.Attributes) { //since simpleContent is being cleared 
                    ct.Attributes.Add(attr); 
                }
            } 

            private void MoveAttributes(XmlSchemaComplexType ct, XmlSchemaSimpleContentExtension simpleContentExtension, bool bCreatingNewType) {
                //copy all attributes from the complex type to the simple content
 
                ICollection sourceCollection;
                if (!bCreatingNewType && ct.AttributeUses.Count > 0) { 
                    sourceCollection = ct.AttributeUses.Values; 
                }
                else { 
                    sourceCollection = ct.Attributes;
                }

                foreach (XmlSchemaAttribute attr in sourceCollection) { 
                    simpleContentExtension.Attributes.Add(attr);
                } 
                ct.Attributes.Clear(); //Clear from pre-compiled property, post compiled will be cleared on Re-process and Compile() 
            }
 
            internal XmlSchemaAttribute FindAttribute(ICollection attributes, string attrName)
            {
                foreach(XmlSchemaObject xsa in attributes)
                { 
                    XmlSchemaAttribute schemaAttribute = xsa as XmlSchemaAttribute;
                    if (schemaAttribute != null) 
                    { 
                        if (schemaAttribute.Name == attrName)
                        { 
                            return schemaAttribute;
                        }

                    } 
                }
                return null; 
            } 

            internal XmlSchemaElement FindGlobalElement(string namespaceURI, string localName, out XmlSchema parentSchema) 
            {
                ICollection col = this.schemaSet.Schemas(namespaceURI);
                XmlSchemaElement xse = null;
                parentSchema = null; 
                foreach(XmlSchema schema in col)
                { 
                    xse = FindElement(schema.Items, localName); 
                    if (xse != null)
                    { 
                        parentSchema = schema;
                        return xse;
                    }
                } 
                return null;
            } 
 

            internal XmlSchemaElement FindElement(XmlSchemaObjectCollection elements, string elementName) 
            {
                foreach(XmlSchemaObject obj in elements)
                {
                    XmlSchemaElement xse = obj as XmlSchemaElement; 
                    if (xse != null && xse.RefName != null)
                    { 
                        if (xse.Name == elementName) 
                        {
                            return xse; 
                        }
                    }
                }
                return null; 
            }
 
            internal XmlSchemaAttribute FindAttributeRef(ICollection attributes, string attributeName, string nsURI) 
            {
                foreach(XmlSchemaObject xsa in attributes) 
                {
                    XmlSchemaAttribute schemaAttribute = xsa as XmlSchemaAttribute;
                    if (schemaAttribute != null)
                    { 
                        if (schemaAttribute.RefName.Name == attributeName && schemaAttribute.RefName.Namespace == nsURI) {
                            return schemaAttribute; 
                        } 

                    } 
                }
                return null;
            }
 
            internal XmlSchemaElement FindElementRef(XmlSchemaObjectCollection elements, string elementName, string nsURI)
            { 
                foreach (XmlSchemaObject obj in elements) 
                {
                    XmlSchemaElement xse = obj as XmlSchemaElement; 
                    if (xse != null && xse.RefName != null)
                    {
                        if (xse.RefName.Name == elementName && xse.RefName.Namespace == nsURI)
                        { 
                            return xse;
                        } 
                    } 
                }
                return null; 
            }

            internal void MakeExistingAttributesOptional(XmlSchemaComplexType ct, XmlSchemaObjectCollection attributesInInstance) {
                if (ct == null)  { 
                    throw new XmlSchemaInferenceException(Res.SchInf_noct, 0, 0);
                } 
                if (ct.ContentModel != null) { 
                    XmlSchemaSimpleContentExtension xssce = CheckSimpleContentExtension(ct);
                    SwitchUseToOptional(xssce.Attributes, attributesInInstance); 
                }
                else { //either  as child of xs:complexType or the attributes are within the content model
                    SwitchUseToOptional(ct.Attributes, attributesInInstance);
                } 
            }
 
            private void SwitchUseToOptional(XmlSchemaObjectCollection attributes, XmlSchemaObjectCollection attributesInInstance) { 
                foreach (XmlSchemaObject attrObj in attributes) {
                    if (attrObj is XmlSchemaAttribute) { 
                        XmlSchemaAttribute attr = attrObj as XmlSchemaAttribute;
                        if (attributesInInstance != null) {
                            if (attr.RefName.Name.Length == 0) { //If the attribute is not present in this instance, make it optional
                                if (null == FindAttribute(attributesInInstance, attr.Name)) { 
                                    attr.Use = XmlSchemaUse.Optional;
                                } 
                            } 
                            else {
                                if (null == FindAttributeRef(attributesInInstance, attr.RefName.Name, attr.RefName.Namespace)) { 
                                    attr.Use = XmlSchemaUse.Optional;
                                }
                            }
                        } 
                        else {
                            attr.Use = XmlSchemaUse.Optional; 
                        } 
                    }
                } 
            }

            internal XmlQualifiedName RefineSimpleType(string s, ref int iTypeFlags)
            { 
                bool bNeedsRangeCheck = false;
                s = s.Trim(); 
                if (iTypeFlags == TF_string || this.typeInference == InferenceOption.Relaxed) 
                    return ST_string;
                iTypeFlags &= InferSimpleType(s, ref bNeedsRangeCheck); 
                if (iTypeFlags == TF_string)
                    return ST_string;
                if (bNeedsRangeCheck)
                { 
                    if ((iTypeFlags & TF_byte) != 0)
                    { 
                        try 
                        {
                            XmlConvert.ToSByte(s); 
                            //sbyte.Parse(s);
                            if ((iTypeFlags & TF_unsignedByte) != 0)
                                return ST_unsignedByte; //number is positive and fits byte -> it also fits unsignedByte
                            else 
                                return ST_byte;
                        } 
                        catch (FormatException) 
                        {}
                        catch (OverflowException) 
                        {}
                        iTypeFlags &= (~TF_byte);
                    }
                    if ((iTypeFlags & TF_unsignedByte) != 0) 
                    {
                        try 
                        { 
                            XmlConvert.ToByte(s);
                            //byte.Parse(s); 
                            return ST_unsignedByte;
                        }
                        catch (FormatException)
                        {} 
                        catch (OverflowException)
                        {} 
                        iTypeFlags &= (~TF_unsignedByte); 
                    }
                    if ((iTypeFlags & TF_short) != 0) 
                    {
                        try
                        {
                            XmlConvert.ToInt16(s); 
                            //short.Parse(s);
                            if ((iTypeFlags & TF_unsignedShort) != 0) 
                                return ST_unsignedShort;    //number is positive and fits short -> it also fits unsignedShort 
                            else
                                return ST_short; 
                        }
                        catch (FormatException)
                        {}
                        catch (OverflowException) 
                        {}
                        iTypeFlags &= (~TF_short); 
                    } 
                    if ((iTypeFlags & TF_unsignedShort) != 0)
                    { 
                        try
                        {
                            XmlConvert.ToUInt16(s);
                            //ushort.Parse(s); 
                            return ST_unsignedShort;
                        } 
                        catch (FormatException) 
                        {}
                        catch (OverflowException) 
                        {}
                        iTypeFlags &= (~TF_unsignedShort);
                    }
                    if ((iTypeFlags & TF_int) != 0) 
                    {
                        try 
                        { 
                            XmlConvert.ToInt32(s);
                            //int.Parse(s); 
                            if ((iTypeFlags & TF_unsignedInt) != 0)
                                return ST_unsignedInt;  //number is positive and fits int -> it also fits unsignedInt
                            else
                                return ST_int; 
                        }
                        catch (FormatException) 
                        {} 
                        catch (OverflowException)
                        {} 
                        iTypeFlags &= (~TF_int);
                    }
                    if ((iTypeFlags & TF_unsignedInt) != 0)
                    { 
                        try
                        { 
                            XmlConvert.ToUInt32(s); 
                            //uint.Parse(s);
                            return ST_unsignedInt; 
                        }
                        catch (FormatException)
                        {}
                        catch (OverflowException) 
                        {}
                        iTypeFlags &= (~TF_unsignedInt); 
                    } 
                    if ((iTypeFlags & TF_long) != 0)
                    { 
                        try
                        {
                            XmlConvert.ToInt64(s);
                            //long.Parse(s); 
                            if ((iTypeFlags & TF_unsignedLong) != 0)
                                return ST_unsignedLong; //number is positive and fits long -> it also fits unsignedLong 
                            else 
                                return ST_long;
                        } 
                        catch (FormatException)
                        {}
                        catch (OverflowException)
                        {} 
                        iTypeFlags &= (~TF_long);
                    } 
                    if ((iTypeFlags & TF_unsignedLong) != 0) 
                    {
                        try 
                        {
                            XmlConvert.ToUInt64(s);
                            //ulong.Parse(s);
                            return ST_unsignedLong; 
                        }
                        catch (FormatException) 
                        {} 
                        catch (OverflowException)
                        {} 
                        iTypeFlags &= (~TF_unsignedLong);
                    }
                    if ((iTypeFlags & TF_float) != 0)
                    { 
                        try
                        { 
                            XmlConvert.ToSingle(s); 
                            if ((iTypeFlags & TF_integer) != 0)
                                return ST_integer; 
                            else if ((iTypeFlags & TF_decimal) != 0)
                                return ST_decimal;
                            else
                                return ST_float; 
                        }
                        catch (FormatException) 
                        {} 
                        catch (OverflowException)
                        {} 
                        iTypeFlags &= (~TF_float);
                    }
                    if ((iTypeFlags & TF_double) != 0)
                    { 
                        try
                        { 
                            XmlConvert.ToDouble(s); 
                            if ((iTypeFlags & TF_integer) != 0)
                                return ST_integer; 
                            else if ((iTypeFlags & TF_decimal) != 0)
                                return ST_decimal;
                            else
                                return ST_double; 
                        }
                        catch (FormatException) 
                        {} 
                        catch (OverflowException)
                        {} 
                        iTypeFlags &= (~TF_double);
                    }
                    if ((iTypeFlags & TF_integer) != 0)
                        return ST_integer; 
                    else if ((iTypeFlags & TF_decimal) != 0)
                        return ST_decimal; 
                    else if (iTypeFlags == (TF_gYearMonth | TF_string) ) 
                    {
                        try 
                        {
                            XmlConvert.ToDateTime(s, XmlDateTimeSerializationMode.RoundtripKind);
                            return ST_gYearMonth;
                        } 
                        catch (FormatException)
                        {} 
                        catch (OverflowException) 
                        {}
                        iTypeFlags = TF_string; 
                        return ST_string;
                    }
                    else if (iTypeFlags == (TF_duration | TF_string) )
                    { 
                        try
                        { 
                            XmlConvert.ToTimeSpan(s); 
                            return ST_duration;
                        } 
                        catch (FormatException)
                        {}
                        catch (OverflowException)
                        {} 
                        iTypeFlags = TF_string;
                        return ST_string; 
                    } 
                    else if (iTypeFlags == (TF_boolean | TF_string))
                    { 
                        return ST_boolean;
                    }

                } 

                    switch (iTypeFlags) 
                    { 
                        case TF_string:
                            return ST_string; 
                        case TF_boolean:
                            return ST_boolean;
                        case TF_byte:
                            return ST_byte; 
                        case TF_unsignedByte:
                            return ST_unsignedByte; 
                        case TF_short: 
                            return ST_short;
                        case TF_unsignedShort: 
                            return ST_unsignedShort;
                        case TF_int:
                            return ST_int;
                        case TF_unsignedInt: 
                            return ST_unsignedInt;
                        case TF_long: 
                            return ST_long; 
                        case TF_unsignedLong:
                            return ST_unsignedLong; 
                        case TF_integer:
                            return ST_integer;
                        case TF_decimal:
                            return ST_decimal; 
                        case TF_float:
                            return ST_float; 
                        case TF_double: 
                            return ST_double;
                        case TF_duration: 
                            return ST_duration;
                        case TF_dateTime:
                            return ST_dateTime;
                        case TF_time: 
                            return ST_time;
                        case TF_date: 
                            return ST_date; 
                        case TF_gYearMonth:
                            return ST_gYearMonth; 

                        case TF_boolean | TF_string:
                            return ST_boolean;
                        case TF_dateTime | TF_string: 
                            return ST_dateTime;
                        case TF_date | TF_string: 
                            return ST_date; 
                        case TF_time | TF_string:
                            return ST_time; 
                        case TF_float | TF_double | TF_string:
                            return ST_float;
                        case TF_double | TF_string:
                            return ST_double; 

                        default: 
                            Debug.Assert(false, "Expected type not matched"); 
                            return ST_string;
                    } 
                /*          if (currentType == null)
                                return SimpleTypes[newType];
                            else
                                return SimpleTypes[ST_Map[newType,(short) ST_Codes[currentType]]]; 
                                */
            } 
 
            internal static int InferSimpleType(string s, ref bool bNeedsRangeCheck)
            { 
                bool bNegative = false;
                bool bPositive = false;
                bool bDate = false;
                bool bTime = false; 
                bool bMissingDay = false;
 
                if (s.Length==0) return TF_string; 
                int i = 0;
                switch (s[i]) 
                {
                    case 't':
                    case 'f':
                        if (s == "true") 
                            return TF_boolean | TF_string;
                        else if (s == "false") 
                            return TF_boolean | TF_string; 
                        else
                            return TF_string; 
                    case 'N':       //try to match "NaN"
                        if (s == "NaN")
                            return TF_float | TF_double | TF_string;
                        else 
                            return TF_string;
                        //else 
                    case 'I':       //try to match "INF" 
                        INF:
                            if (s.Substring(i) == "INF") 
                                return TF_float | TF_double | TF_string;
                            else return TF_string;
                    case '.':       //try to match ".9999"  decimal/float/double
                        FRACTION: 
                            bNeedsRangeCheck = true;
                        i++; 
                        if (i==s.Length) 
                        {
                            if ((i==1) || (i==2 && (bPositive || bNegative)))   //"." "-." "+." 
                                return TF_string;
                            else
                                return TF_decimal | TF_float | TF_double | TF_string;
                        } 
                    switch (s[i])
                    { 
                        case 'e': 
                        case 'E':
                            goto EXPONENT; 
                        default:
                            if (s[i]>='0' && s[i]<='9')
                                goto DEC_PART;
                            else 
                                return TF_string;
                    } 
                        DEC_PART: 
                            i++; if (i==s.Length) return TF_decimal | TF_float | TF_double | TF_string; //"9999.9" was matched
                    switch (s[i]) 
                    {
                        case 'e':
                        case 'E':
                            goto EXPONENT; 
                        default:
                            if (s[i]>='0' && s[i]<='9') 
                                goto DEC_PART; 
                            else
                                return TF_string; 
                    }
                        EXPONENT:
                            i++; if (i==s.Length) return TF_string;
                    switch (s[i]) 
                    {
                        case '+': 
                        case '-': 
                            goto E1;
                        default: 
                            if (s[i]>='0' && s[i]<='9')
                                goto EXP_PART;
                            else
                                return TF_string; 
                    }
                        E1: 
                            i++; if (i==s.Length) return TF_string; //".9999e+" was matched 
                        if (s[i]>='0' && s[i]<='9')
                            goto EXP_PART; 
                        else
                            return TF_string;   //".999e+X was matched
                        EXP_PART:
                            i++; if (i==s.Length) return TF_float | TF_double | TF_string;  //".9999e+99" was matched 
                        if (s[i]>='0' && s[i]<='9') //".9999e+9
                            goto EXP_PART; 
                        else 
                            return TF_string;   //".9999e+999X" was matched
                    case '-': 
                        bNegative = true;
                        i++; if (i==s.Length) return TF_string;
                    switch (s[i])
                    { 
                        case 'I':   //try to match "-INF"
                            goto INF; 
                        case '.':   //try to match "-.9999" 
                            goto FRACTION;
                        case 'P': 
                            goto DURATION;
                        default:
                            if (s[i]>='0' && s[i]<='9') //-9
                                goto NUMBER; 
                            else return TF_string;
                    } 
                    case '+': 
                        bPositive = true;
                        i++; if (i==s.Length) return TF_string; 
                    switch (s[i])
                    {
                        case '.':   //try to match "+.9999"
                            goto FRACTION; 
                        case 'P':
                            goto DURATION; 
                        default: 
                            if (s[i]>='0' && s[i]<='9') //"+9
                                goto NUMBER; 
                            else return TF_string;
                    }
                    case 'P':       //try to match duration
                        DURATION: 
                            i++; if (i==s.Length) return TF_string;
                    switch (s[i]) 
                    { 
                        case 'T':
                            goto D7; 
                        default:
                            if (s[i]>='0' && s[i]<='9') //"P9"
                                goto D1;
                            else return TF_string; 
                    }
                        D1: 
                            i++; if (i==s.Length) return TF_string; //"P999" was matched 
                    switch (s[i])
                    { 
                        case 'Y':
                            goto D2;
                        case 'M':
                            goto D4; 
                        case 'D':
                            goto D6; 
                        default: 
                            if (s[i]>='0' && s[i]<='9')
                                goto D1; 
                            else
                                return TF_string;
                    }
                        D2: 
                            i++;
                        if (i==s.Length) 
                        { 
                            bNeedsRangeCheck = true;
                            return TF_duration | TF_string; //"P999Y" was matched 
                        }
                    switch (s[i])
                    {
                        case 'T': 
                            goto D7;
                        default: 
                            if (s[i]>='0' && s[i]<='9') 
                                goto D3;
                            else 
                                return TF_string;
                    }
                        D3:
                            i++; if (i==s.Length) return TF_string; //"P999Y9" was matched 
                    switch (s[i])
                    { 
                        case 'M': 
                            goto D4;
                        case 'D': 
                            goto D6;
                        default:
                            if (s[i]>='0' && s[i]<='9')
                                goto D3; 
                            else
                                return TF_string; 
                    } 
                        D4:
                            i++; 
                        if (i==s.Length)
                        {
                            bNeedsRangeCheck = true;
                            return TF_duration | TF_string; //"P999Y999M" was matched 
                        }
                    switch (s[i]) 
                    { 
                        case 'T':
                            goto D7; 
                        default:
                            if (s[i]>='0' && s[i]<='9')
                                goto D5;
                            else 
                                return TF_string;
                    } 
                        D5: 
                            i++; if (i==s.Length) return TF_string; //"P999Y999M9" was matched
                    switch (s[i]) 
                    {
                        case 'D':
                            goto D6;
                        default: 
                            if (s[i]>='0' && s[i]<='9')
                                goto D5; 
                            else 
                                return TF_string;
                    } 
                        D6:
                            i++;
                        if (i==s.Length)
                        { 
                            bNeedsRangeCheck = true;
                            return TF_duration | TF_string; //"P999Y999M999D" was matched 
                        } 
                    switch (s[i])
                    { 
                        case 'T':
                            goto D7;
                        default:
                            return TF_string; 
                    }
                        D7: 
                            i++; if (i==s.Length) return TF_string; //"P999Y999M9999DT" was matched 
                        if (s[i]>='0' && s[i]<='9')
                            goto D8; 
                        else
                            return TF_string;
                        D8:
                            i++; if (i==s.Length) return TF_string; //"___T9" was matched 
                    switch (s[i])
                    { 
                        case 'H': 
                            goto D9;
                        case 'M': 
                            goto D11;
                        case '.':
                            goto D13;
                        case 'S': 
                            goto D15;
                        default: 
                            if (s[i]>='0' && s[i]<='9') 
                                goto D8;
                            else 
                                return TF_string;
                    }
                        D9:
                            i++; 
                        if (i==s.Length)
                        { 
                            bNeedsRangeCheck = true; 
                            return TF_duration | TF_string; //"___T999H" was matched
                        } 
                        if (s[i]>='0' && s[i]<='9')
                            goto D10;
                        else
                            return TF_string; 
                        D10:
                            i++; if (i==s.Length) return TF_string; //"___T999H9" was matched 
                    switch (s[i]) 
                    {
                        case 'M': 
                            goto D11;
                        case '.':
                            goto D13;
                        case 'S': 
                            goto D15;
                        default: 
                            if (s[i]>='0' && s[i]<='9') 
                                goto D10;
                            else 
                                return TF_string;
                    }
                        D11:
                            i++; 
                        if (i==s.Length)
                        { 
                            bNeedsRangeCheck = true; 
                            return TF_duration | TF_string; //"___T999H999M" was matched
                        } 
                        if (s[i]>='0' && s[i]<='9')
                            goto D12;
                        else
                            return TF_string; 
                        D12:
                            i++; if (i==s.Length) return TF_string; //"___T999H999M9" was matched 
                    switch (s[i]) 
                    {
                        case '.': 
                            goto D13;
                        case 'S':
                            goto D15;
                        default: 
                            if (s[i]>='0' && s[i]<='9')
                                goto D12; 
                            else 
                                return TF_string;
                    } 
                        D13:
                            i++;
                        if (i==s.Length)
                        { 
                            bNeedsRangeCheck = true;
                            return TF_duration | TF_string; //"___T999H999M999." was matched 
                        } 
                        if (s[i]>='0' && s[i]<='9')
                            goto D14; 
                        else
                            return TF_string;
                        D14:
                            i++; if (i==s.Length) return TF_string; //"___T999H999M999.9" was matched 
                    switch (s[i])
                    { 
                        case 'S': 
                            goto D15;
                        default: 
                            if (s[i]>='0' && s[i]<='9')
                                goto D14;
                            else
                                return TF_string; 
                    }
                        D15: 
                            i++; 
                        if (i==s.Length)
                        { 
                            bNeedsRangeCheck = true;
                            return TF_duration | TF_string; //"___T999H999M999.999S" was matched
                        }
                        else return TF_string; 
                    case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9':
                        NUMBER: 
                            i++; 
                        if (i==s.Length)
                        { 
                            bNeedsRangeCheck = true;
                            if (bNegative || bPositive)
                                return TF_byte | TF_short | TF_int | TF_long | TF_integer | TF_decimal | TF_float | TF_double | TF_string;  //"-9"
                            else 
                            {
                                if (s=="0" || s=="1") 
                                    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;
                                else 
                                    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;
                            }
                        } 
                    switch (s[i])
                    { 
                        case '.': 
                            goto FRACTION;
                        case 'e': 
                        case 'E':
                            bNeedsRangeCheck = true;
                            return TF_float | TF_double | TF_string;
                        default: 
                            if (s[i]>='0' && s[i]<='9')
                                goto N2; 
                            else 
                                return TF_string;
                    } 
                        N2:
                            i++;
                        if (i==s.Length)
                        { 
                            bNeedsRangeCheck = true;
                            if (bNegative || bPositive) 
                                return TF_byte | TF_short | TF_int | TF_long | TF_integer | TF_decimal | TF_float | TF_double | TF_string;  //"-9" 
                            else
                                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;
                        }
                    switch (s[i])
                    { 
                        case '.':
                            goto FRACTION; 
                        case ':': 
                            bTime = true;
                            goto MINUTE; 
                        case 'e':
                        case 'E':
                            bNeedsRangeCheck = true;
                            return TF_float | TF_double | TF_string; 
                        default:
                            if (s[i]>='0' && s[i]<='9') 
                                goto N3; 
                            else
                                return TF_string; 
                    }

                        N3:
                            i++; 
                        if (i==s.Length)
                        { 
                            bNeedsRangeCheck = true; //three digits may not fit byte and unsignedByte 
                            if (bNegative || bPositive)
                                return TF_byte | TF_short | TF_int | TF_long | TF_integer | TF_decimal | TF_float | TF_double | TF_string;  //"-9" 
                            else
                                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;
                        } 
                    switch (s[i])
                    { 
                        case '.': 
                            goto FRACTION;
                        case 'e': 
                        case 'E':
                            bNeedsRangeCheck = true;
                            return TF_float | TF_double | TF_string;
                        default: 
                            if (s[i]>='0' && s[i]<='9')
                                goto N4; 
                            else 
                                return TF_string;
                    } 
                        N4:
                            i++;
                        if (i==s.Length)
                        { 
                            bNeedsRangeCheck = true;
                            if (bNegative || bPositive) 
                                return TF_byte | TF_short | TF_int | TF_long | TF_integer | TF_decimal | TF_float | TF_double | TF_string;  //"-9" 
                            else
                                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;
                        }

                    switch (s[i]) 
                    {
                        case '-': 
                            bDate = true; 
                            goto DATE;
                        case '.': 
                            goto FRACTION;
                        case 'e':
                        case 'E':
                            bNeedsRangeCheck = true; 
                            return TF_float | TF_double | TF_string;
                        default: 
                            if (s[i]>='0' && s[i]<='9') 
                                goto N4;
                            else 
                                return TF_string;
                    }
                        DATE:
                            i++; if (i==s.Length) return TF_string; //"9999-" 
                        if (s[i]<'0' || s[i]>'9')
                            return TF_string; 
                        i++; if (i==s.Length) return TF_string; //"9999-9" 
                        if (s[i]<'0' || s[i]>'9')
                            return TF_string; 
                        i++;
                        if (i==s.Length)
                        {
                            bNeedsRangeCheck = true; 
                            return TF_gYearMonth | TF_string;   //"9999-99"
                        } 
                    switch (s[i]) 
                    {
                        case '-': 
                            goto DAY;
                        case 'Z':
                        case 'z':
                            bMissingDay = true; 
                            goto ZULU;
                        case '+': 
                            bMissingDay = true; 
                            goto ZONE_SHIFT;
                        default: 
                            return TF_string;
                    }
                        DAY:
                            i++; if (i==s.Length) return TF_string; //"9999-99-" 
                        if (s[i]<'0' || s[i]>'9')
                            return TF_string; 
                        i++; if (i==s.Length) return TF_string; //"9999-99-9" 
                        if (s[i]<'0' || s[i]>'9')
                            return TF_string; 
                        i++; if (i==s.Length) return DateTime(s, bDate, bTime); //"9999-99-99"
                    switch (s[i])
                    {
                        case 'Z': 
                        case 'z':
                            goto ZULU; 
                        case '+': 
                        case '-':
                            goto ZONE_SHIFT; 
                        case 'T':
                            bTime=true;
                            goto TIME;
                        case ':': 
                            bMissingDay = true;
                            goto ZONE_SHIFT_MINUTE; 
                        default: 
                            return TF_string;
                    } 
                        ZULU:
                            i++;
                        if (i==s.Length)
                        { 
                            if (bMissingDay)
                            { 
                                bNeedsRangeCheck=true; 
                                return TF_gYearMonth | TF_string;
                            } 
                            else
                            {
                                return DateTime(s, bDate, bTime);
                            } 
                        }
                        else 
                            return TF_string; 
                        ZONE_SHIFT:
                            i++; if (i==s.Length) return TF_string; 
                        if (s[i]<'0' || s[i]>'9')
                            return TF_string;
                        i++; if (i==s.Length) return TF_string;
                        if (s[i]<'0' || s[i]>'9') 
                            return TF_string;
                        i++; if (i==s.Length) return TF_string; 
                        if (s[i] != ':') 
                            return TF_string;
                        ZONE_SHIFT_MINUTE: 
                            i++; if (i==s.Length) return TF_string;
                        if (s[i]<'0' || s[i]>'9')
                            return TF_string;
                        i++; if (i==s.Length) return TF_string; 
                        if (s[i]<'0' || s[i]>'9')
                            return TF_string; 
                        i++; 
                        if (i==s.Length)
                        { 
                            if (bMissingDay)
                            {
                                bNeedsRangeCheck=true;
                                return TF_gYearMonth | TF_string; 
                            }
                            else 
                            { 
                                return DateTime(s, bDate, bTime);
                            } 
                        }
                        else return TF_string;
                        TIME:
                            i++; if (i==s.Length) return TF_string; 
                        if (s[i]<'0' || s[i]>'9')
                            return TF_string; 
                        i++; if (i==s.Length) return TF_string; 
                        if (s[i]<'0' || s[i]>'9')
                            return TF_string; 
                        i++; if (i==s.Length) return TF_string;
                        if (s[i] != ':')
                            return TF_string;
                        MINUTE: 
                            i++; if (i==s.Length) return TF_string;
                        if (s[i]<'0' || s[i]>'9') 
                            return TF_string; 
                        i++; if (i==s.Length) return TF_string;
                        if (s[i]<'0' || s[i]>'9') 
                            return TF_string;
                        i++; if (i==s.Length) return TF_string;
                        if (s[i] != ':')
                            return TF_string; 
                        i++; if (i==s.Length) return TF_string;
                        if (s[i]<'0' || s[i]>'9') 
                            return TF_string; 
                        i++; if (i==s.Length) return TF_string;
                        if (s[i]<'0' || s[i]>'9') 
                            return TF_string;
                        i++; if (i==s.Length) return DateTime(s, bDate, bTime);
                    switch (s[i])
                    { 
                        case 'Z':
                        case 'z': 
                            goto ZULU; 
                        case '+':
                        case '-': 
                            goto ZONE_SHIFT;
                        case '.':
                            goto SECOND_FRACTION;
                        default: 
                            return TF_string;
                    } 
                        SECOND_FRACTION: 
                            i++; if (i==s.Length) return TF_string;
                        if (s[i]<'0' || s[i]>'9') 
                            return TF_string;
                        FRACT_DIGITS:
                            i++; if (i==s.Length) return DateTime(s, bDate, bTime);
                    switch (s[i]) 
                    {
                        case 'Z': 
                        case 'z': 
                            goto ZULU;
                        case '+': 
                        case '-':
                            goto ZONE_SHIFT;
                        default:
                            if (s[i]>='0' && s[i]<='9') 
                                goto FRACT_DIGITS;
                            else 
                                return TF_string; 

                    } 
                    default:
                        return TF_string;
                }
            } 

            internal static int DateTime(string s, bool bDate, bool bTime) 
            { 
                try
                { 
                    XmlConvert.ToDateTime(s, XmlDateTimeSerializationMode.RoundtripKind);
                }
                catch (FormatException)
                { 
                    return TF_string;
                } 
                if (bDate && bTime) 
                    return TF_dateTime | TF_string;
                else if (bDate) 
                    return TF_date | TF_string;
                else if (bTime)
                    return TF_time | TF_string;
                else 
                {
                    Debug.Assert(false, "Expected date, time or dateTime"); 
                    return TF_string; 
                }
            } 
            XmlSchemaElement CreateNewElementforChoice(XmlSchemaElement copyElement)
            {
                XmlSchemaElement newElement = new XmlSchemaElement();
                newElement.Annotation = copyElement.Annotation; 
                newElement.Block = copyElement.Block;
                newElement.DefaultValue = copyElement.DefaultValue; 
                newElement.Final = copyElement.Final; 
                newElement.FixedValue = copyElement.FixedValue;
                newElement.Form = copyElement.Form; 
                newElement.Id = copyElement.Id;
                //                newElement.IsAbstract = copyElement.IsAbstract;
                if (copyElement.IsNillable)
                { 
                    newElement.IsNillable = copyElement.IsNillable;
                } 
                newElement.LineNumber = copyElement.LineNumber; 
                newElement.LinePosition = copyElement.LinePosition;
                newElement.Name = copyElement.Name; 
                newElement.Namespaces = copyElement.Namespaces;
                newElement.RefName = copyElement.RefName;
                newElement.SchemaType = copyElement.SchemaType;
                newElement.SchemaTypeName = copyElement.SchemaTypeName; 
                newElement.SourceUri = copyElement.SourceUri;
                newElement.SubstitutionGroup = copyElement.SubstitutionGroup; 
                newElement.UnhandledAttributes = copyElement.UnhandledAttributes; 
                if (copyElement.MinOccurs != Decimal.One && this.Occurrence == InferenceOption.Relaxed)
                { 
                    newElement.MinOccurs = copyElement.MinOccurs;
                }
                if (copyElement.MaxOccurs != Decimal.One) {
                    newElement.MaxOccurs = copyElement.MaxOccurs; 
                }
                return newElement; 
            } 

            private static int GetSchemaType(XmlQualifiedName qname) 
            {
                if (qname == SimpleTypes[HC_ST_boolean])
                {
                    return TF_boolean | TF_string; 
                }
                if (qname == SimpleTypes[HC_ST_byte]) 
                { 
                    return TF_byte | TF_short | TF_int | TF_long | TF_integer | TF_decimal | TF_float | TF_double | TF_string;
                } 
                if (qname == SimpleTypes[HC_ST_unsignedByte])
                {
                    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; 
                }
                if (qname == SimpleTypes[HC_ST_short]) 
                { 
                    return TF_short | TF_int | TF_long | TF_integer | TF_decimal | TF_float | TF_double | TF_string;
                } 
                if (qname == SimpleTypes[HC_ST_unsignedShort])
                {
                    return TF_short | TF_int | TF_long | TF_integer | TF_decimal | TF_float | TF_double |
                                         TF_unsignedShort | TF_unsignedInt | TF_unsignedLong | TF_string; 
                }
                if (qname == SimpleTypes[HC_ST_int]) 
                { 
                    return TF_int | TF_long | TF_integer | TF_decimal | TF_float | TF_double | TF_string;
                } 
                if (qname == SimpleTypes[HC_ST_unsignedInt])
                {
                    return  TF_int | TF_long | TF_integer | TF_decimal | TF_float | TF_double |
                                          TF_unsignedInt | TF_unsignedLong | TF_string; 
                }
                if (qname == SimpleTypes[HC_ST_long]) 
                { 
                    return TF_long | TF_integer | TF_decimal | TF_float | TF_double | TF_string;
                } 
                if (qname == SimpleTypes[HC_ST_unsignedLong])
                {
                    return TF_long | TF_integer | TF_decimal | TF_float | TF_double |
                                          TF_unsignedLong | TF_string; 
                }
                if (qname == SimpleTypes[HC_ST_integer]) 
                { 
                    return TF_integer |TF_decimal | TF_float | TF_double | TF_string;
                } 
                if (qname == SimpleTypes[HC_ST_decimal])
                {
                    return TF_decimal | TF_float | TF_double | TF_string;
                } 
                if (qname == SimpleTypes[HC_ST_float])
                { 
                    return TF_float | TF_double | TF_string; 
                }
                if (qname == SimpleTypes[HC_ST_double]) 
                {
                    return TF_double | TF_string;
                }
                if (qname == SimpleTypes[HC_ST_duration]) 
                {
                    return TF_duration | TF_string; 
                } 
                if (qname == SimpleTypes[HC_ST_dateTime])
                { 
                    return TF_dateTime | TF_string;
                }
                if (qname == SimpleTypes[HC_ST_time])
                { 
                    return TF_time | TF_string;
                } 
                if (qname == SimpleTypes[HC_ST_date]) 
                {
                    return TF_date; 
                }
                if (qname == SimpleTypes[HC_ST_gYearMonth])
                {
                    return TF_gYearMonth; 
                }
                if (qname == SimpleTypes[HC_ST_string]) 
                { 
                    return TF_string;
                } 
                if (qname == null || qname.IsEmpty) {
                    return -1;
                }
                throw new XmlSchemaInferenceException(Res.SchInf_schematype, 0, 0); 
            }
 
            internal void SetMinMaxOccurs(XmlSchemaElement el, bool setMaxOccurs) 
            {
                if (this.Occurrence == InferenceOption.Relaxed) 
                {
                    if (setMaxOccurs || el.MaxOccurs > 1)
                    {
                        el.MaxOccurs = decimal.MaxValue;    //set it to unbounded 
                    }
                    el.MinOccurs = 0; 
                } 
                else if (el.MinOccurs > 1)
                { 
                    el.MinOccurs = 1;
                }
            }
 

        } 
    } 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.


                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK