Initial commit
[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">[....]</owner> 
6 // <owner current="false" primary="false">[....]</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 (s.Length==0) return TF_string;
1741                 int i = 0;
1742                 switch (s[i])
1743                 {
1744                     case 't':
1745                     case 'f':
1746                         if (s == "true")
1747                             return TF_boolean | TF_string;
1748                         else if (s == "false")
1749                             return TF_boolean | TF_string;
1750                         else
1751                             return TF_string;
1752                     case 'N':       //try to match "NaN"
1753                         if (s == "NaN")
1754                             return TF_float | TF_double | TF_string;
1755                         else
1756                             return TF_string;
1757                         //else 
1758                     case 'I':       //try to match "INF"
1759                         INF:
1760                             if (s.Substring(i) == "INF")
1761                                 return TF_float | TF_double | TF_string;
1762                             else return TF_string;
1763                     case '.':       //try to match ".9999"  decimal/float/double
1764                         FRACTION:
1765                             bNeedsRangeCheck = true;
1766                         i++;
1767                         if (i==s.Length)
1768                         {
1769                             if ((i==1) || (i==2 && (bPositive || bNegative)))   //"." "-." "+."
1770                                 return TF_string;
1771                             else
1772                                 return TF_decimal | TF_float | TF_double | TF_string;
1773                         }
1774                     switch (s[i])
1775                     {
1776                         case 'e':
1777                         case 'E':
1778                             goto EXPONENT;
1779                         default:
1780                             if (s[i]>='0' && s[i]<='9')
1781                                 goto DEC_PART;
1782                             else
1783                                 return TF_string;
1784                     }
1785                         DEC_PART:
1786                             i++; if (i==s.Length) return TF_decimal | TF_float | TF_double | TF_string; //"9999.9" was matched
1787                     switch (s[i])
1788                     {
1789                         case 'e':
1790                         case 'E':
1791                             goto EXPONENT;
1792                         default:
1793                             if (s[i]>='0' && s[i]<='9')
1794                                 goto DEC_PART;
1795                             else
1796                                 return TF_string;
1797                     }
1798                         EXPONENT:
1799                             i++; if (i==s.Length) return TF_string;
1800                     switch (s[i])
1801                     {
1802                         case '+':
1803                         case '-':
1804                             goto E1;
1805                         default:
1806                             if (s[i]>='0' && s[i]<='9')
1807                                 goto EXP_PART;
1808                             else
1809                                 return TF_string;
1810                     }
1811                         E1:
1812                             i++; if (i==s.Length) return TF_string; //".9999e+" was matched
1813                         if (s[i]>='0' && s[i]<='9')
1814                             goto EXP_PART;
1815                         else
1816                             return TF_string;   //".999e+X was matched
1817                         EXP_PART:
1818                             i++; if (i==s.Length) return TF_float | TF_double | TF_string;  //".9999e+99" was matched
1819                         if (s[i]>='0' && s[i]<='9') //".9999e+9
1820                             goto EXP_PART;
1821                         else
1822                             return TF_string;   //".9999e+999X" was matched
1823                     case '-':
1824                         bNegative = true;
1825                         i++; if (i==s.Length) return TF_string;
1826                     switch (s[i])
1827                     {
1828                         case 'I':   //try to match "-INF"
1829                             goto INF;
1830                         case '.':   //try to match "-.9999"
1831                             goto FRACTION;
1832                         case 'P':
1833                             goto DURATION;
1834                         default:
1835                             if (s[i]>='0' && s[i]<='9') //-9
1836                                 goto NUMBER;
1837                             else return TF_string;
1838                     }
1839                     case '+':
1840                         bPositive = true;
1841                         i++; if (i==s.Length) return TF_string;
1842                     switch (s[i])
1843                     {
1844                         case '.':   //try to match "+.9999"
1845                             goto FRACTION;
1846                         case 'P':
1847                             goto DURATION;
1848                         default:
1849                             if (s[i]>='0' && s[i]<='9') //"+9
1850                                 goto NUMBER;
1851                             else return TF_string;
1852                     }
1853                     case 'P':       //try to match duration
1854                         DURATION:
1855                             i++; if (i==s.Length) return TF_string;
1856                     switch (s[i])
1857                     {
1858                         case 'T':
1859                             goto D7;
1860                         default:
1861                             if (s[i]>='0' && s[i]<='9') //"P9"
1862                                 goto D1;
1863                             else return TF_string;
1864                     }
1865                         D1:
1866                             i++; if (i==s.Length) return TF_string; //"P999" was matched
1867                     switch (s[i])
1868                     {
1869                         case 'Y':
1870                             goto D2;
1871                         case 'M':
1872                             goto D4;
1873                         case 'D':
1874                             goto D6;
1875                         default:
1876                             if (s[i]>='0' && s[i]<='9')
1877                                 goto D1;
1878                             else
1879                                 return TF_string;
1880                     }
1881                         D2:
1882                             i++; 
1883                         if (i==s.Length)
1884                         {
1885                             bNeedsRangeCheck = true;
1886                             return TF_duration | TF_string; //"P999Y" was matched
1887                         }
1888                     switch (s[i])
1889                     {
1890                         case 'T':
1891                             goto D7;
1892                         default:
1893                             if (s[i]>='0' && s[i]<='9')
1894                                 goto D3;
1895                             else
1896                                 return TF_string;
1897                     }
1898                         D3:
1899                             i++; if (i==s.Length) return TF_string; //"P999Y9" was matched
1900                     switch (s[i])
1901                     {
1902                         case 'M':
1903                             goto D4;
1904                         case 'D':
1905                             goto D6;
1906                         default:
1907                             if (s[i]>='0' && s[i]<='9')
1908                                 goto D3;
1909                             else
1910                                 return TF_string;
1911                     }
1912                         D4:
1913                             i++;
1914                         if (i==s.Length)
1915                         {
1916                             bNeedsRangeCheck = true;
1917                             return TF_duration | TF_string; //"P999Y999M" was matched
1918                         }
1919                     switch (s[i])
1920                     {
1921                         case 'T':
1922                             goto D7;
1923                         default:
1924                             if (s[i]>='0' && s[i]<='9')
1925                                 goto D5;
1926                             else
1927                                 return TF_string;
1928                     }
1929                         D5:
1930                             i++; if (i==s.Length) return TF_string; //"P999Y999M9" was matched
1931                     switch (s[i])
1932                     {
1933                         case 'D':
1934                             goto D6;
1935                         default:
1936                             if (s[i]>='0' && s[i]<='9')
1937                                 goto D5;
1938                             else
1939                                 return TF_string;
1940                     }
1941                         D6:
1942                             i++;
1943                         if (i==s.Length)
1944                         {
1945                             bNeedsRangeCheck = true;
1946                             return TF_duration | TF_string; //"P999Y999M999D" was matched
1947                         }
1948                     switch (s[i])
1949                     {
1950                         case 'T':
1951                             goto D7;
1952                         default:
1953                             return TF_string;
1954                     }
1955                         D7:
1956                             i++; if (i==s.Length) return TF_string; //"P999Y999M9999DT" was matched
1957                         if (s[i]>='0' && s[i]<='9')
1958                             goto D8;
1959                         else
1960                             return TF_string;
1961                         D8:
1962                             i++; if (i==s.Length) return TF_string; //"___T9" was matched
1963                     switch (s[i])
1964                     {
1965                         case 'H':
1966                             goto D9;
1967                         case 'M':
1968                             goto D11;
1969                         case '.':
1970                             goto D13;
1971                         case 'S':
1972                             goto D15;
1973                         default:
1974                             if (s[i]>='0' && s[i]<='9')
1975                                 goto D8;
1976                             else
1977                                 return TF_string;
1978                     }
1979                         D9:
1980                             i++;
1981                         if (i==s.Length)
1982                         {
1983                             bNeedsRangeCheck = true;
1984                             return TF_duration | TF_string; //"___T999H" was matched
1985                         }
1986                         if (s[i]>='0' && s[i]<='9')
1987                             goto D10;
1988                         else
1989                             return TF_string;
1990                         D10:
1991                             i++; if (i==s.Length) return TF_string; //"___T999H9" was matched
1992                     switch (s[i])
1993                     {
1994                         case 'M':
1995                             goto D11;
1996                         case '.':
1997                             goto D13;
1998                         case 'S':
1999                             goto D15;
2000                         default:
2001                             if (s[i]>='0' && s[i]<='9')
2002                                 goto D10;
2003                             else
2004                                 return TF_string;
2005                     }
2006                         D11:
2007                             i++;
2008                         if (i==s.Length)
2009                         {
2010                             bNeedsRangeCheck = true;
2011                             return TF_duration | TF_string; //"___T999H999M" was matched
2012                         }
2013                         if (s[i]>='0' && s[i]<='9')
2014                             goto D12;
2015                         else
2016                             return TF_string;
2017                         D12:
2018                             i++; if (i==s.Length) return TF_string; //"___T999H999M9" was matched
2019                     switch (s[i])
2020                     {
2021                         case '.':
2022                             goto D13;
2023                         case 'S':
2024                             goto D15;
2025                         default:
2026                             if (s[i]>='0' && s[i]<='9')
2027                                 goto D12;
2028                             else
2029                                 return TF_string;
2030                     }
2031                         D13:
2032                             i++;
2033                         if (i==s.Length)
2034                         {
2035                             bNeedsRangeCheck = true;
2036                             return TF_duration | TF_string; //"___T999H999M999." was matched
2037                         }
2038                         if (s[i]>='0' && s[i]<='9')
2039                             goto D14;
2040                         else
2041                             return TF_string;
2042                         D14:
2043                             i++; if (i==s.Length) return TF_string; //"___T999H999M999.9" was matched
2044                     switch (s[i])
2045                     {
2046                         case 'S':
2047                             goto D15;
2048                         default:
2049                             if (s[i]>='0' && s[i]<='9')
2050                                 goto D14;
2051                             else
2052                                 return TF_string;
2053                     }
2054                         D15:
2055                             i++;
2056                         if (i==s.Length)
2057                         {
2058                             bNeedsRangeCheck = true;
2059                             return TF_duration | TF_string; //"___T999H999M999.999S" was matched
2060                         }
2061                         else return TF_string;
2062                     case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9':
2063                         NUMBER:
2064                             i++;
2065                         if (i==s.Length)
2066                         {
2067                             bNeedsRangeCheck = true;
2068                             if (bNegative || bPositive)
2069                                 return TF_byte | TF_short | TF_int | TF_long | TF_integer | TF_decimal | TF_float | TF_double | TF_string;  //"-9"
2070                             else
2071                             {
2072                                 if (s=="0" || s=="1")
2073                                     return TF_boolean | TF_byte | TF_short | TF_int | TF_long | TF_integer | TF_decimal | TF_float | TF_double |
2074                                         TF_unsignedByte | TF_unsignedShort | TF_unsignedInt | TF_unsignedLong | TF_string;
2075                                 else
2076                                     return TF_byte | TF_short | TF_int | TF_long | TF_integer | TF_decimal | TF_float | TF_double |
2077                                         TF_unsignedByte | TF_unsignedShort | TF_unsignedInt | TF_unsignedLong | TF_string;
2078                             }
2079                         }
2080                     switch (s[i])
2081                     {
2082                         case '.':
2083                             goto FRACTION;
2084                         case 'e':
2085                         case 'E':
2086                             bNeedsRangeCheck = true;
2087                             return TF_float | TF_double | TF_string;
2088                         default:
2089                             if (s[i]>='0' && s[i]<='9')
2090                                 goto N2;
2091                             else
2092                                 return TF_string;
2093                     }
2094                         N2:
2095                             i++;
2096                         if (i==s.Length)
2097                         {
2098                             bNeedsRangeCheck = true;
2099                             if (bNegative || bPositive)
2100                                 return TF_byte | TF_short | TF_int | TF_long | TF_integer | TF_decimal | TF_float | TF_double | TF_string;  //"-9"
2101                             else
2102                                 return TF_byte | TF_short | TF_int | TF_long | TF_integer | TF_decimal | TF_float | TF_double |
2103                                     TF_unsignedByte | TF_unsignedShort | TF_unsignedInt | TF_unsignedLong | TF_string;
2104                         }
2105                     switch (s[i])
2106                     {
2107                         case '.':
2108                             goto FRACTION;
2109                         case ':':
2110                             bTime = true;
2111                             goto MINUTE;
2112                         case 'e':
2113                         case 'E':
2114                             bNeedsRangeCheck = true;
2115                             return TF_float | TF_double | TF_string;
2116                         default:
2117                             if (s[i]>='0' && s[i]<='9')
2118                                 goto N3;
2119                             else
2120                                 return TF_string;
2121                     }
2122
2123                         N3:
2124                             i++;
2125                         if (i==s.Length)
2126                         {
2127                             bNeedsRangeCheck = true; //three digits may not fit byte and unsignedByte
2128                             if (bNegative || bPositive)
2129                                 return TF_byte | TF_short | TF_int | TF_long | TF_integer | TF_decimal | TF_float | TF_double | TF_string;  //"-9"
2130                             else
2131                                 return TF_byte | TF_short | TF_int | TF_long | TF_integer | TF_decimal | TF_float | TF_double |
2132                                     TF_unsignedByte | TF_unsignedShort | TF_unsignedInt | TF_unsignedLong | TF_string;
2133                         }
2134                     switch (s[i])
2135                     {
2136                         case '.':
2137                             goto FRACTION;
2138                         case 'e':
2139                         case 'E':
2140                             bNeedsRangeCheck = true;
2141                             return TF_float | TF_double | TF_string;
2142                         default:
2143                             if (s[i]>='0' && s[i]<='9')
2144                                 goto N4;
2145                             else
2146                                 return TF_string;
2147                     }
2148                         N4:
2149                             i++;
2150                         if (i==s.Length)
2151                         {
2152                             bNeedsRangeCheck = true;
2153                             if (bNegative || bPositive)
2154                                 return TF_byte | TF_short | TF_int | TF_long | TF_integer | TF_decimal | TF_float | TF_double | TF_string;  //"-9"
2155                             else
2156                                 return TF_byte | TF_short | TF_int | TF_long | TF_integer | TF_decimal | TF_float | TF_double |
2157                                     TF_unsignedByte | TF_unsignedShort | TF_unsignedInt | TF_unsignedLong | TF_string;
2158                         }
2159
2160                     switch (s[i])
2161                     {
2162                         case '-':
2163                             bDate = true;
2164                             goto DATE;
2165                         case '.':
2166                             goto FRACTION;
2167                         case 'e':
2168                         case 'E':
2169                             bNeedsRangeCheck = true;
2170                             return TF_float | TF_double | TF_string;
2171                         default:
2172                             if (s[i]>='0' && s[i]<='9')
2173                                 goto N4;
2174                             else
2175                                 return TF_string;
2176                     }
2177                         DATE:
2178                             i++; if (i==s.Length) return TF_string; //"9999-"
2179                         if (s[i]<'0' || s[i]>'9')
2180                             return TF_string;
2181                         i++; if (i==s.Length) return TF_string; //"9999-9"
2182                         if (s[i]<'0' || s[i]>'9')
2183                             return TF_string;
2184                         i++;
2185                         if (i==s.Length)
2186                         {
2187                             bNeedsRangeCheck = true;
2188                             return TF_gYearMonth | TF_string;   //"9999-99"
2189                         }
2190                     switch (s[i])
2191                     {
2192                         case '-':
2193                             goto DAY;
2194                         case 'Z':
2195                         case 'z':
2196                             bMissingDay = true;
2197                             goto ZULU;
2198                         case '+':
2199                             bMissingDay = true;
2200                             goto ZONE_SHIFT;
2201                         default:
2202                             return TF_string;
2203                     }
2204                         DAY:
2205                             i++; if (i==s.Length) return TF_string; //"9999-99-"
2206                         if (s[i]<'0' || s[i]>'9')
2207                             return TF_string;
2208                         i++; if (i==s.Length) return TF_string; //"9999-99-9"
2209                         if (s[i]<'0' || s[i]>'9')
2210                             return TF_string;
2211                         i++; if (i==s.Length) return DateTime(s, bDate, bTime); //"9999-99-99"
2212                     switch (s[i])
2213                     {
2214                         case 'Z':
2215                         case 'z':
2216                             goto ZULU;
2217                         case '+':
2218                         case '-':
2219                             goto ZONE_SHIFT;
2220                         case 'T':
2221                             bTime=true;
2222                             goto TIME;
2223                         case ':':
2224                             bMissingDay = true;
2225                             goto ZONE_SHIFT_MINUTE;
2226                         default:
2227                             return TF_string;
2228                     }
2229                         ZULU:   
2230                             i++; 
2231                         if (i==s.Length)
2232                         {
2233                             if (bMissingDay)
2234                             {
2235                                 bNeedsRangeCheck=true;
2236                                 return TF_gYearMonth | TF_string;
2237                             }
2238                             else
2239                             {
2240                                 return DateTime(s, bDate, bTime);
2241                             }
2242                         }
2243                         else
2244                             return TF_string;
2245                         ZONE_SHIFT:
2246                             i++; if (i==s.Length) return TF_string;
2247                         if (s[i]<'0' || s[i]>'9')
2248                             return TF_string;
2249                         i++; if (i==s.Length) return TF_string;
2250                         if (s[i]<'0' || s[i]>'9')
2251                             return TF_string;
2252                         i++; if (i==s.Length) return TF_string;
2253                         if (s[i] != ':')
2254                             return TF_string;
2255                         ZONE_SHIFT_MINUTE:
2256                             i++; if (i==s.Length) return TF_string;
2257                         if (s[i]<'0' || s[i]>'9')
2258                             return TF_string;
2259                         i++; if (i==s.Length) return TF_string;
2260                         if (s[i]<'0' || s[i]>'9')
2261                             return TF_string;
2262                         i++; 
2263                         if (i==s.Length)
2264                         {
2265                             if (bMissingDay)
2266                             {
2267                                 bNeedsRangeCheck=true;
2268                                 return TF_gYearMonth | TF_string;
2269                             }
2270                             else
2271                             {
2272                                 return DateTime(s, bDate, bTime);
2273                             }
2274                         }
2275                         else return TF_string;
2276                         TIME:
2277                             i++; if (i==s.Length) return TF_string;
2278                         if (s[i]<'0' || s[i]>'9')
2279                             return TF_string;
2280                         i++; if (i==s.Length) return TF_string;
2281                         if (s[i]<'0' || s[i]>'9')
2282                             return TF_string;
2283                         i++; if (i==s.Length) return TF_string;
2284                         if (s[i] != ':')
2285                             return TF_string;
2286                         MINUTE:
2287                             i++; if (i==s.Length) return TF_string;
2288                         if (s[i]<'0' || s[i]>'9')
2289                             return TF_string;
2290                         i++; if (i==s.Length) return TF_string;
2291                         if (s[i]<'0' || s[i]>'9')
2292                             return TF_string;
2293                         i++; if (i==s.Length) return TF_string;
2294                         if (s[i] != ':')
2295                             return TF_string;
2296                         i++; if (i==s.Length) return TF_string;
2297                         if (s[i]<'0' || s[i]>'9')
2298                             return TF_string;
2299                         i++; if (i==s.Length) return TF_string;
2300                         if (s[i]<'0' || s[i]>'9')
2301                             return TF_string;
2302                         i++; if (i==s.Length) return DateTime(s, bDate, bTime);
2303                     switch (s[i])
2304                     {
2305                         case 'Z':
2306                         case 'z':
2307                             goto ZULU;
2308                         case '+':
2309                         case '-':
2310                             goto ZONE_SHIFT;
2311                         case '.':
2312                             goto SECOND_FRACTION;
2313                         default:
2314                             return TF_string;
2315                     }
2316                         SECOND_FRACTION:
2317                             i++; if (i==s.Length) return TF_string;
2318                         if (s[i]<'0' || s[i]>'9')
2319                             return TF_string;
2320                         FRACT_DIGITS:
2321                             i++; if (i==s.Length) return DateTime(s, bDate, bTime);
2322                     switch (s[i])
2323                     {
2324                         case 'Z':
2325                         case 'z':
2326                             goto ZULU;
2327                         case '+':
2328                         case '-':
2329                             goto ZONE_SHIFT;
2330                         default:
2331                             if (s[i]>='0' && s[i]<='9')
2332                                 goto FRACT_DIGITS;
2333                             else
2334                                 return TF_string;
2335
2336                     }
2337                     default:
2338                         return TF_string;
2339                 }
2340             }
2341
2342             internal static int DateTime(string s, bool bDate, bool bTime)
2343             {
2344                 try
2345                 {
2346                     XmlConvert.ToDateTime(s, XmlDateTimeSerializationMode.RoundtripKind);
2347                 }
2348                 catch (FormatException)
2349                 {
2350                     return TF_string;
2351                 }
2352                 if (bDate && bTime)
2353                     return TF_dateTime | TF_string;
2354                 else if (bDate)
2355                     return TF_date | TF_string;
2356                 else if (bTime)
2357                     return TF_time | TF_string;
2358                 else
2359                 {
2360                     Debug.Assert(false, "Expected date, time or dateTime");
2361                     return TF_string;
2362                 }
2363             }
2364             XmlSchemaElement CreateNewElementforChoice(XmlSchemaElement copyElement) 
2365             {
2366                 XmlSchemaElement newElement = new XmlSchemaElement();
2367                 newElement.Annotation = copyElement.Annotation;
2368                 newElement.Block = copyElement.Block;
2369                 newElement.DefaultValue = copyElement.DefaultValue;
2370                 newElement.Final = copyElement.Final;
2371                 newElement.FixedValue = copyElement.FixedValue;
2372                 newElement.Form = copyElement.Form;
2373                 newElement.Id = copyElement.Id;
2374                 //                newElement.IsAbstract = copyElement.IsAbstract;
2375                 if (copyElement.IsNillable) 
2376                 {
2377                     newElement.IsNillable = copyElement.IsNillable;
2378                 }
2379                 newElement.LineNumber = copyElement.LineNumber;
2380                 newElement.LinePosition = copyElement.LinePosition;
2381                 newElement.Name = copyElement.Name;
2382                 newElement.Namespaces = copyElement.Namespaces;
2383                 newElement.RefName = copyElement.RefName;
2384                 newElement.SchemaType = copyElement.SchemaType;
2385                 newElement.SchemaTypeName = copyElement.SchemaTypeName;
2386                 newElement.SourceUri = copyElement.SourceUri;
2387                 newElement.SubstitutionGroup = copyElement.SubstitutionGroup;
2388                 newElement.UnhandledAttributes = copyElement.UnhandledAttributes;
2389                 if (copyElement.MinOccurs != Decimal.One && this.Occurrence == InferenceOption.Relaxed) 
2390                 {
2391                     newElement.MinOccurs = copyElement.MinOccurs;
2392                 }
2393                 if (copyElement.MaxOccurs != Decimal.One) {
2394                     newElement.MaxOccurs = copyElement.MaxOccurs;
2395                 }
2396                 return newElement;
2397             }
2398
2399             private static int GetSchemaType(XmlQualifiedName qname)
2400             {
2401                 if (qname == SimpleTypes[HC_ST_boolean])
2402                 {
2403                     return TF_boolean | TF_string;
2404                 }
2405                 if (qname == SimpleTypes[HC_ST_byte])
2406                 {
2407                     return TF_byte | TF_short | TF_int | TF_long | TF_integer | TF_decimal | TF_float | TF_double | TF_string;
2408                 }
2409                 if (qname == SimpleTypes[HC_ST_unsignedByte])
2410                 {
2411                     return TF_byte | TF_short | TF_int | TF_long | TF_integer | TF_decimal | TF_float | TF_double |
2412                                         TF_unsignedByte | TF_unsignedShort | TF_unsignedInt | TF_unsignedLong | TF_string;
2413                 }
2414                 if (qname == SimpleTypes[HC_ST_short])
2415                 {
2416                     return TF_short | TF_int | TF_long | TF_integer | TF_decimal | TF_float | TF_double | TF_string;
2417                 }
2418                 if (qname == SimpleTypes[HC_ST_unsignedShort])
2419                 {
2420                     return TF_short | TF_int | TF_long | TF_integer | TF_decimal | TF_float | TF_double |
2421                                          TF_unsignedShort | TF_unsignedInt | TF_unsignedLong | TF_string;
2422                 }
2423                 if (qname == SimpleTypes[HC_ST_int])
2424                 {
2425                     return TF_int | TF_long | TF_integer | TF_decimal | TF_float | TF_double | TF_string;
2426                 }
2427                 if (qname == SimpleTypes[HC_ST_unsignedInt])
2428                 {
2429                     return  TF_int | TF_long | TF_integer | TF_decimal | TF_float | TF_double |
2430                                           TF_unsignedInt | TF_unsignedLong | TF_string;
2431                 }
2432                 if (qname == SimpleTypes[HC_ST_long])
2433                 {
2434                     return TF_long | TF_integer | TF_decimal | TF_float | TF_double | TF_string;
2435                 }
2436                 if (qname == SimpleTypes[HC_ST_unsignedLong])
2437                 {
2438                     return TF_long | TF_integer | TF_decimal | TF_float | TF_double |
2439                                           TF_unsignedLong | TF_string;
2440                 }
2441                 if (qname == SimpleTypes[HC_ST_integer])
2442                 {
2443                     return TF_integer |TF_decimal | TF_float | TF_double | TF_string;
2444                 }
2445                 if (qname == SimpleTypes[HC_ST_decimal])
2446                 {
2447                     return TF_decimal | TF_float | TF_double | TF_string;
2448                 }
2449                 if (qname == SimpleTypes[HC_ST_float])
2450                 {
2451                     return TF_float | TF_double | TF_string;
2452                 }
2453                 if (qname == SimpleTypes[HC_ST_double])
2454                 {
2455                     return TF_double | TF_string;
2456                 }
2457                 if (qname == SimpleTypes[HC_ST_duration])
2458                 {
2459                     return TF_duration | TF_string;
2460                 }
2461                 if (qname == SimpleTypes[HC_ST_dateTime])
2462                 {
2463                     return TF_dateTime | TF_string;
2464                 }
2465                 if (qname == SimpleTypes[HC_ST_time])
2466                 {
2467                     return TF_time | TF_string;
2468                 }
2469                 if (qname == SimpleTypes[HC_ST_date])
2470                 {
2471                     return TF_date;
2472                 }
2473                 if (qname == SimpleTypes[HC_ST_gYearMonth])
2474                 {
2475                     return TF_gYearMonth;
2476                 }
2477                 if (qname == SimpleTypes[HC_ST_string])
2478                 {
2479                     return TF_string;
2480                 }
2481                 if (qname == null || qname.IsEmpty) {
2482                     return -1;
2483                 }
2484                 throw new XmlSchemaInferenceException(Res.SchInf_schematype, 0, 0);
2485             }
2486
2487             internal void SetMinMaxOccurs(XmlSchemaElement el, bool setMaxOccurs)
2488             {
2489                 if (this.Occurrence == InferenceOption.Relaxed)
2490                 {
2491                     if (setMaxOccurs || el.MaxOccurs > 1)
2492                     {
2493                         el.MaxOccurs = decimal.MaxValue;    //set it to unbounded
2494                     }
2495                     el.MinOccurs = 0;
2496                 }
2497                 else if (el.MinOccurs > 1)
2498                 {
2499                     el.MinOccurs = 1;
2500                 }
2501             }
2502
2503
2504         }
2505     }