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