Fix for the issue of getting occasional -5875 error on the server when
[mono.git] / mcs / class / System.XML / System.Xml.Schema / XmlSchemaComplexType.cs
1 //
2 // System.Xml.Schema.XmlSchemaComplexType.cs
3 //
4 // Authors:
5 //      Dwivedi, Ajay kumar  Adwiv@Yahoo.com
6 //      Enomoto, Atsushi     ginga@kit.hi-ho.ne.jp
7 //
8
9 //
10 // Permission is hereby granted, free of charge, to any person obtaining
11 // a copy of this software and associated documentation files (the
12 // "Software"), to deal in the Software without restriction, including
13 // without limitation the rights to use, copy, modify, merge, publish,
14 // distribute, sublicense, and/or sell copies of the Software, and to
15 // permit persons to whom the Software is furnished to do so, subject to
16 // the following conditions:
17 // 
18 // The above copyright notice and this permission notice shall be
19 // included in all copies or substantial portions of the Software.
20 // 
21 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
25 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
26 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
27 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28 //
29 using System;
30 using System.Collections;
31 using System.Xml;
32 using System.ComponentModel;
33 using System.Xml.Serialization;
34
35 namespace System.Xml.Schema
36 {
37         /// <summary>
38         /// Summary description for XmlSchemaComplexType.
39         /// </summary>
40         public class XmlSchemaComplexType : XmlSchemaType
41         {
42                 private XmlSchemaAnyAttribute anyAttribute;
43                 private XmlSchemaObjectCollection attributes;
44                 private XmlSchemaObjectTable attributeUses;
45                 private XmlSchemaAnyAttribute attributeWildcard;
46                 private XmlSchemaDerivationMethod block;
47                 private XmlSchemaDerivationMethod blockResolved;
48                 private XmlSchemaContentModel contentModel;
49                 private XmlSchemaParticle validatableParticle;
50                 private XmlSchemaParticle contentTypeParticle;
51                 private bool isAbstract;
52                 private bool isMixed;
53                 private XmlSchemaParticle particle;
54                 private XmlSchemaContentType resolvedContentType;
55
56                 internal bool ValidatedIsAbstract;
57                 internal bool ParentIsSchema {
58                         get { return Parent is XmlSchema; }
59                 }
60
61                 const string xmlname = "complexType";
62
63                 private static XmlSchemaComplexType anyType;
64
65                 internal static XmlSchemaComplexType AnyType {
66                         get {
67                                 if (anyType == null) {
68                                         anyType = new XmlSchemaComplexType ();
69                                         anyType.Name = "";      // In MS.NET, it is not "anyType"
70                                         anyType.QNameInternal = XmlQualifiedName.Empty; // Not xs:anyType as well.
71 #if BUGGY_MS_COMPLIANT
72                                         anyType.validatableParticle = XmlSchemaParticle.Empty; // This code makes validator handles these schemas incorrectly: particlesIb001, mgM013, mgH014, ctE004, ctD004
73 #else
74                                         anyType.validatableParticle = XmlSchemaAny.AnyTypeContent;
75 #endif
76                                         anyType.contentTypeParticle = anyType.validatableParticle;
77                                         anyType.DatatypeInternal = XmlSchemaSimpleType.AnySimpleType;
78                                         anyType.isMixed = true;
79                                         anyType.resolvedContentType = XmlSchemaContentType.Mixed;
80                                 }
81                                 return anyType;
82                         }
83                 }
84
85                 internal static readonly XmlQualifiedName AnyTypeName = new XmlQualifiedName ("anyType", XmlSchema.Namespace);
86
87                 public XmlSchemaComplexType ()
88                 {
89                         attributes = new XmlSchemaObjectCollection();
90                         block = XmlSchemaDerivationMethod.None;
91                         attributeUses = new XmlSchemaObjectTable();
92                         validatableParticle = XmlSchemaParticle.Empty;
93                         contentTypeParticle = validatableParticle;
94                 }
95
96                 #region Attributes
97
98                 [DefaultValue(false)]
99                 [System.Xml.Serialization.XmlAttribute("abstract")]
100                 public bool IsAbstract 
101                 {
102                         get{ return  isAbstract; }
103                         set{ isAbstract = value; }
104                 }
105                 [DefaultValue(XmlSchemaDerivationMethod.None)]
106                 [System.Xml.Serialization.XmlAttribute("block")]
107                 public XmlSchemaDerivationMethod Block
108                 {
109                         get{ return  block; }
110                         set{ block = value; }
111                 }
112                 [DefaultValue(false)]
113                 [System.Xml.Serialization.XmlAttribute("mixed")]
114                 public override bool IsMixed
115                 {
116                         get{ return  isMixed; }
117                         set{ isMixed = value; }
118                 }
119                 
120                 #endregion
121                 
122                 #region Elements
123                                 
124                 [XmlElement("simpleContent",typeof(XmlSchemaSimpleContent))]
125                 [XmlElement("complexContent",typeof(XmlSchemaComplexContent))]
126                 public XmlSchemaContentModel ContentModel 
127                 {
128                         get{ return  contentModel; } 
129                         set{ contentModel = value; }
130                 }
131
132                 //LAMESPEC: The default value for particle in Schema is of Type EmptyParticle (internal?)
133                 [XmlElement("group",typeof(XmlSchemaGroupRef))]
134                 [XmlElement("all",typeof(XmlSchemaAll))]
135                 [XmlElement("choice",typeof(XmlSchemaChoice))]
136                 [XmlElement("sequence",typeof(XmlSchemaSequence))]
137                 public XmlSchemaParticle Particle 
138                 {
139                         get{ return  particle; } 
140                         set{ particle = value; }
141                 }
142
143                 [XmlElement("attribute",typeof(XmlSchemaAttribute))]
144                 [XmlElement("attributeGroup",typeof(XmlSchemaAttributeGroupRef))]
145                 public XmlSchemaObjectCollection Attributes 
146                 {
147                         get{ return attributes; }
148                 }
149
150                 [XmlElement("anyAttribute")]
151                 public XmlSchemaAnyAttribute AnyAttribute 
152                 {
153                         get{ return  anyAttribute; }
154                         set{ anyAttribute = value; }
155                 }
156                 #endregion
157
158                 #region XmlIgnore
159                 [XmlIgnore]
160                 public XmlSchemaContentType ContentType 
161                 {
162                         get{ return resolvedContentType; }
163                 }
164                 [XmlIgnore]
165                 public XmlSchemaParticle ContentTypeParticle 
166                 {
167                         get{ return contentTypeParticle; }
168                 }
169                 [XmlIgnore]
170                 public XmlSchemaDerivationMethod BlockResolved 
171                 {
172                         get{ return blockResolved; }
173                 }
174                 [XmlIgnore]
175                 public XmlSchemaObjectTable AttributeUses 
176                 {
177                         get{ return attributeUses; }
178                 }
179                 [XmlIgnore]
180                 public XmlSchemaAnyAttribute AttributeWildcard 
181                 {
182                         get{ return attributeWildcard; }
183                 }
184
185                 #endregion
186
187                 internal XmlSchemaParticle ValidatableParticle 
188                 {
189                         get{ return contentTypeParticle; }
190                 }
191
192                 internal override void SetParent (XmlSchemaObject parent)
193                 {
194                         base.SetParent (parent);
195                         if (ContentModel != null)
196                                 ContentModel.SetParent (this);
197                         if (Particle != null)
198                                 Particle.SetParent (this);
199                         if (AnyAttribute != null)
200                                 AnyAttribute.SetParent (this);
201                         foreach (XmlSchemaObject obj in Attributes)
202                                 obj.SetParent (this);
203                 }
204
205                 /// <remarks>
206                 /// 1. If ContentModel is present, neither particle nor Attributes nor AnyAttribute can be present.
207                 /// 2. If particle is present, 
208                 /// a. For a topLevelComplexType
209                 ///             1. name must be present and type NCName
210                 ///             2. if block is #all, blockdefault is #all, else List of (extension | restriction)
211                 ///             3. if final is #all, finaldefault is #all, else List of (extension | restriction)
212                 ///     b. For a local Complex type 
213                 ///             1. abstract must be false
214                 ///             2. Name must be absent
215                 ///             3. final must be absent
216                 ///             4. block must be absent
217                 ///             
218                 /// </remarks>
219                 internal override int Compile (ValidationEventHandler h, XmlSchema schema)
220                 {
221                         // If this is already compiled this time, simply skip.
222                         if (CompilationId == schema.CompilationId)
223                                 return errorCount;
224
225                         ValidatedIsAbstract = isAbstract;
226
227                         if (isRedefinedComponent) {
228                                 if (Annotation != null)
229                                         Annotation.isRedefinedComponent = true;
230                                 if (AnyAttribute != null)
231                                         AnyAttribute.isRedefinedComponent = true;
232                                 foreach (XmlSchemaObject obj in Attributes)
233                                         obj.isRedefinedComponent = true;
234                                 if (ContentModel != null)
235                                         ContentModel.isRedefinedComponent = true;
236                                 if (Particle != null)
237                                         Particle.isRedefinedComponent = true;
238                         }
239
240                         // block/final resolution
241                         if(ParentIsSchema || isRedefineChild)
242                         {
243                                 if(this.Name == null || this.Name == string.Empty)
244                                         error(h,"name must be present in a top level complex type");
245                                 else if(!XmlSchemaUtil.CheckNCName(Name))
246                                         error(h,"name must be a NCName");
247                                 else
248                                         this.QNameInternal = new XmlQualifiedName(Name, AncestorSchema.TargetNamespace);
249                                 
250                                 if(Block != XmlSchemaDerivationMethod.None)
251                                 {
252                                         if(Block == XmlSchemaDerivationMethod.All)
253                                         {
254                                                 blockResolved = XmlSchemaDerivationMethod.All;
255                                         }
256                                         else
257                                         {
258                                                 if ((Block & XmlSchemaUtil.ComplexTypeBlockAllowed) != Block)
259                                                         error (h, "Invalid block specification.");
260                                                 blockResolved = Block & XmlSchemaUtil.ComplexTypeBlockAllowed;
261                                         }
262                                 }
263                                 else
264                                 {
265                                         switch (schema.BlockDefault) {
266                                         case XmlSchemaDerivationMethod.All:
267                                                 blockResolved = XmlSchemaDerivationMethod.All;
268                                                 break;
269                                         case XmlSchemaDerivationMethod.None:
270                                                 blockResolved = XmlSchemaDerivationMethod.Empty;
271                                                 break;
272                                         default:
273                                                 blockResolved = schema.BlockDefault & XmlSchemaUtil.ComplexTypeBlockAllowed;
274                                                 break;
275                                         }
276                                 }
277
278                                 if(Final != XmlSchemaDerivationMethod.None)
279                                 {
280                                         if(Final == XmlSchemaDerivationMethod.All)
281                                                 finalResolved = XmlSchemaDerivationMethod.All;
282                                         else if ((Final & XmlSchemaUtil.FinalAllowed) != Final)
283                                                 error (h, "Invalid final specification.");
284                                         else
285                                                 finalResolved = Final;
286                                 }
287                                 else
288                                 {
289                                         switch (schema.FinalDefault) {
290                                         case XmlSchemaDerivationMethod.All:
291                                                 finalResolved = XmlSchemaDerivationMethod.All;
292                                                 break;
293                                         case XmlSchemaDerivationMethod.None:
294                                                 finalResolved = XmlSchemaDerivationMethod.Empty;
295                                                 break;
296                                         default:
297                                                 finalResolved = schema.FinalDefault & XmlSchemaUtil.FinalAllowed;
298                                                 break;
299                                         }
300                                 }
301                         }
302                         else // Not Top Level
303                         {
304                                 if(isAbstract)
305                                         error(h,"abstract must be false in a local complex type");
306                                 if(Name != null)
307                                         error(h,"name must be absent in a local complex type");
308                                 if(Final != XmlSchemaDerivationMethod.None)
309                                         error(h,"final must be absent in a local complex type");
310                                 if(block != XmlSchemaDerivationMethod.None)
311                                         error(h,"block must be absent in a local complex type");
312                         }
313
314                         // Process contents and BaseSchemaType
315                         if(contentModel != null)
316                         {
317                                 if(anyAttribute != null || Attributes.Count != 0 || Particle != null)
318                                         error(h,"attributes, particles or anyattribute is not allowed if ContentModel is present");
319                                 errorCount += contentModel.Compile (h, schema);
320
321                                 XmlSchemaSimpleContent smodel = ContentModel as XmlSchemaSimpleContent;
322                                 if(smodel != null)
323                                 {
324                                         XmlSchemaSimpleContentExtension sscx = smodel.Content as XmlSchemaSimpleContentExtension;
325                                         if (sscx == null) {
326                                                 XmlSchemaSimpleContentRestriction sscr = smodel.Content as XmlSchemaSimpleContentRestriction;
327                                                 if (sscr != null) {
328                                                         if (sscr.BaseType != null) {
329                                                                 sscr.BaseType.Compile (h, schema);
330                                                                 BaseXmlSchemaTypeInternal = sscr.BaseType;
331                                                         }
332                                                 }
333                                         }
334                                 }
335                         }
336                         else
337                         {
338                                 if (Particle != null)
339                                         errorCount += Particle.Compile (h, schema);
340
341                                 if(this.anyAttribute != null)
342                                 {
343                                         AnyAttribute.Compile(h,schema);
344                                 }
345                                 foreach(XmlSchemaObject obj in Attributes)
346                                 {
347                                         if(obj is XmlSchemaAttribute)
348                                         {
349                                                 XmlSchemaAttribute attr = (XmlSchemaAttribute) obj;
350                                                 errorCount += attr.Compile(h,schema);
351                                         }
352                                         else if(obj is XmlSchemaAttributeGroupRef)
353                                         {
354                                                 XmlSchemaAttributeGroupRef atgrp = (XmlSchemaAttributeGroupRef) obj;
355                                                 errorCount += atgrp.Compile(h,schema);
356                                         }
357                                         else
358                                                 error(h,obj.GetType() +" is not valid in this place::ComplexType");
359                                 }
360                         }
361
362                         XmlSchemaUtil.CompileID(Id, this, schema.IDCollection, h);
363                         this.CompilationId = schema.CompilationId;
364                         return errorCount;
365                 }
366
367                 Guid CollectProcessId;
368
369                 private void CollectSchemaComponent (ValidationEventHandler h, XmlSchema schema)
370                 {
371                         if (CollectProcessId == schema.CompilationId)
372                                 return;
373                         // Below are already contributed by Compile():
374                         // {name}, {namespace} => QualifiedName, QNameInternal
375                         // {abstract} => ValidatedIsAbstract
376                         // {prohibited substitutions} => BlockResolved
377                         // {final} => FinalResolved
378                         // {annotations} => Annotation (XmlSchemaAnnotated)
379
380                         // Below are different properties depending on simpleContent | complexContent.
381                         // {base type definition}
382                         // {derivation method}
383                         // {attribute uses} => AttributeUses (later)
384                         // {attribute wildcard} => AttributeWildcard (later)
385                         // {content type}
386
387
388                         // {base type definition} => baseSchemaTypeInternal (later)
389                         if (contentModel != null) {
390                                 BaseSchemaTypeName = contentModel.Content != null ? contentModel.Content.GetBaseTypeName () : XmlQualifiedName.Empty;
391
392                                 BaseXmlSchemaTypeInternal = schema.FindSchemaType(BaseSchemaTypeName);
393                         }
394                         // Resolve redefine.
395                         if (this.isRedefineChild && BaseXmlSchemaType != null && this.QualifiedName == BaseSchemaTypeName) {
396                                 XmlSchemaType redType = (XmlSchemaType) redefinedObject;
397                                 if (redType == null)
398                                         error (h, "Redefinition base type was not found.");
399                                 else
400                                         BaseXmlSchemaTypeInternal = redType;
401                         }
402
403                         // {derivation method} => resolvedDerivedBy
404                         if (contentModel != null && contentModel.Content != null) {
405                                 resolvedDerivedBy =
406                                         contentModel.Content.IsExtension ?
407                                         XmlSchemaDerivationMethod.Extension :
408                                         XmlSchemaDerivationMethod.Restriction;
409                         }
410                         else
411                                 resolvedDerivedBy = XmlSchemaDerivationMethod.Empty;
412                 }
413
414                 void FillContentTypeParticle (ValidationEventHandler h, XmlSchema schema)
415                 {
416                         // {content type} => ContentType and ContentTypeParticle (later)
417                         if (ContentModel != null) {
418                                 CollectContentTypeFromContentModel (h, schema);
419                         } else
420                                 CollectContentTypeFromImmediateContent ();
421
422                         contentTypeParticle = validatableParticle.GetOptimizedParticle (true);
423                         if (contentTypeParticle == XmlSchemaParticle.Empty && resolvedContentType == XmlSchemaContentType.ElementOnly)
424                                 resolvedContentType = XmlSchemaContentType.Empty;
425
426                         CollectProcessId = schema.CompilationId;
427                 }
428
429                 #region {content type}
430                 private void CollectContentTypeFromImmediateContent ()
431                 {
432                         // leave resolvedDerivedBy as Empty
433                         if (Particle != null)
434                                 validatableParticle = Particle;
435                         if (this == AnyType) {
436                                 resolvedContentType = XmlSchemaContentType.Mixed;
437                                 return;
438                         }
439
440                         if (validatableParticle == XmlSchemaParticle.Empty) {
441                                 // note that this covers "Particle == null" case
442                                 if (this.IsMixed)
443                                         resolvedContentType = XmlSchemaContentType.TextOnly;
444                                 else
445                                         resolvedContentType = XmlSchemaContentType.Empty;
446                         } else {
447                                 if (this.IsMixed)
448                                         resolvedContentType = XmlSchemaContentType.Mixed;
449                                 else
450                                         resolvedContentType = XmlSchemaContentType.ElementOnly;
451                         }
452                         if (this != AnyType)
453                                 BaseXmlSchemaTypeInternal = XmlSchemaComplexType.AnyType;
454                 }
455
456                 private void CollectContentTypeFromContentModel (ValidationEventHandler h, XmlSchema schema)
457                 {
458                         if (ContentModel.Content == null) {
459                                 // basically it is error. Recover by specifying empty content.
460                                 validatableParticle = XmlSchemaParticle.Empty;
461                                 resolvedContentType = XmlSchemaContentType.Empty;
462                                 return;
463                         }
464
465                         if (ContentModel.Content is XmlSchemaComplexContentExtension)
466                                 CollectContentTypeFromComplexExtension (h, schema);
467                         if (ContentModel.Content is XmlSchemaComplexContentRestriction)
468                                 CollectContentTypeFromComplexRestriction ();
469                 }
470
471                 private void CollectContentTypeFromComplexExtension (ValidationEventHandler h, XmlSchema schema)
472                 {
473                         XmlSchemaComplexContentExtension cce = (XmlSchemaComplexContentExtension) ContentModel.Content;
474                         XmlSchemaComplexType baseComplexType = this.BaseXmlSchemaType as XmlSchemaComplexType;
475                         if (baseComplexType != null)
476                                 baseComplexType.CollectSchemaComponent (h ,schema);
477
478                         // It must exist, but consider validation error case.
479                         if (BaseSchemaTypeName == XmlSchemaComplexType.AnyTypeName)
480                                 baseComplexType = XmlSchemaComplexType.AnyType;
481
482                         // On error case, it simple reject any contents
483                         if (baseComplexType == null) {
484                                 validatableParticle = XmlSchemaParticle.Empty;
485                                 resolvedContentType = XmlSchemaContentType.Empty;
486                                 return;
487                         }
488
489                         // 3.4.2 complex content {content type}
490                         if (cce.Particle == null || cce.Particle == XmlSchemaParticle.Empty) {
491                                 // - 2.1
492                                 if (baseComplexType == null) {
493                                         // Basically it is an error. Considering ValidationEventHandler.
494                                         validatableParticle = XmlSchemaParticle.Empty;
495                                         resolvedContentType = XmlSchemaContentType.Empty;
496                                 } else {
497                                         validatableParticle = baseComplexType.ValidatableParticle;
498                                         resolvedContentType = baseComplexType.resolvedContentType;
499                                 }
500                         } else if (baseComplexType.validatableParticle == XmlSchemaParticle.Empty
501                                 || baseComplexType == XmlSchemaComplexType.AnyType) {
502                                 // - 2.2
503                                 validatableParticle = cce.Particle;
504                                 resolvedContentType = GetComplexContentType (contentModel);
505                         } else {
506                                 // - 2.3 : create a new sequences that merges both contents.
507                                 XmlSchemaSequence seq = new XmlSchemaSequence ();
508                                 this.CopyInfo (seq);
509                                 seq.Items.Add (baseComplexType.validatableParticle);
510                                 seq.Items.Add (cce.Particle);
511                                 seq.Compile (h, schema);
512                                 seq.Validate (h, schema);
513                                 validatableParticle = seq;
514                                 resolvedContentType = GetComplexContentType (contentModel);
515                         }
516                         if (validatableParticle == null)
517                                 validatableParticle = XmlSchemaParticle.Empty;
518                 }
519
520                 private void CollectContentTypeFromComplexRestriction ()
521                 {
522                         XmlSchemaComplexContentRestriction ccr = (XmlSchemaComplexContentRestriction) ContentModel.Content;
523                         // 3.4.2 complex content schema component {content type}
524                         // - 1.1.1
525                         bool isEmptyParticle = false;
526                         if (ccr.Particle == null) 
527                                 isEmptyParticle = true;
528                         else {
529                                 XmlSchemaGroupBase gb = ccr.Particle as XmlSchemaGroupBase;
530                                 if (gb != null) {
531                                         // - 1.1.2
532                                         if (!(gb is XmlSchemaChoice) && gb.Items.Count == 0)
533                                                 isEmptyParticle = true;
534                                         // - 1.1.3
535                                         else if (gb is XmlSchemaChoice && gb.Items.Count == 0 && gb.ValidatedMinOccurs == 0)
536                                                 isEmptyParticle = true;
537                                 }
538                         }
539                         if (isEmptyParticle) {
540                                 resolvedContentType = XmlSchemaContentType.Empty;
541                                 validatableParticle = XmlSchemaParticle.Empty;
542                         } else {
543                                 // - 1.2.1
544                                 resolvedContentType = GetComplexContentType (contentModel);
545                                 // - 1.2.2
546                                 validatableParticle = ccr.Particle;
547                         }
548                 }
549
550                 // 3.4.2 Complex Content Schema Component {content type} 1.2.1
551                 private XmlSchemaContentType GetComplexContentType (XmlSchemaContentModel content)
552                 {
553                         if (this.IsMixed || ((XmlSchemaComplexContent) content).IsMixed)
554                                 return XmlSchemaContentType.Mixed;
555                         else
556                                 return XmlSchemaContentType.ElementOnly;
557                 }
558                 #endregion
559
560                 //
561                 // We have to validate:
562                 //
563                 //      - 3.4.3 Complex Type Definition Representation OK
564                 //      - 3.4.6 Type Definition Properties Correct
565                 //      - 3.4.6 Derivation Valid (Extension)
566                 //      - 3.4.6 Derivation Valid (Restriction, Complex)
567                 //
568                 // There are many schema errata:
569                 // http://www.w3.org/2001/05/xmlschema-errata#Errata1
570                 //
571                 // E1-43 Derivation Valid (Restriction, Complex) 5.
572                 // E1-21 Derivation Valid (Restriction, Complex) 4.3.
573                 // E1-17 Type Derivation OK (Complex) 2.1.
574                 //
575                 // And E1-38, E1-37, E1-30, E1-27
576                 //
577                 internal override int Validate (ValidationEventHandler h, XmlSchema schema)
578                 {
579                         if (IsValidated (schema.ValidationId))
580                                 return errorCount;
581                         // FIXME: omitting it causes StackOverflowException
582                         // among the compilation of element and types, but
583                         // it may result in insufficient results.
584                         ValidationId = schema.ValidationId;
585
586                         CollectSchemaComponent (h, schema);
587
588                         ValidateContentFirstPass (h, schema);
589
590                         FillContentTypeParticle (h, schema);
591
592                         // 3.4.6: Properties Correct
593                         // Term. 1 => 3.4.1 already done by CollectSchemaComponent()
594                         //            except for {attribute uses} and {attribute wildcard}
595                         // Term. 2, 3 and 4 goes to ValidateContentModel().
596                         // Term. 5 follows in this method.
597                         //
598                         if (ContentModel != null)
599                                 ValidateContentModel (h, schema);
600                         else
601                                 ValidateImmediateAttributes (h, schema);
602
603                         // Additional support for 3.8.6 All Group Limited
604                         if (ContentTypeParticle != null) {
605                                 XmlSchemaAll termAll = contentTypeParticle.GetOptimizedParticle (true) as XmlSchemaAll;
606                                 if (termAll != null && (termAll.ValidatedMaxOccurs != 1 || contentTypeParticle.ValidatedMaxOccurs != 1)) // here contentTypeParticle is used to check occurence.
607                                         error (h, "Particle whose term is -all- and consists of complex type content particle must have maxOccurs = 1.");
608                         }
609
610 #if NET_2_0
611                         if (schema.Schemas.CompilationSettings != null &&
612                                 schema.Schemas.CompilationSettings.EnableUpaCheck)
613 #endif
614                         // This check is optional only after 2.0
615                         contentTypeParticle.ValidateUniqueParticleAttribution (new XmlSchemaObjectTable (),
616                                 new ArrayList (), h, schema);
617                         contentTypeParticle.ValidateUniqueTypeAttribution (
618                                 new XmlSchemaObjectTable (), h, schema);
619
620                         // 3.4.6 Properties Correct :: 5 (Two distinct ID attributes)
621                         XmlSchemaAttribute idAttr = null;
622                         foreach (DictionaryEntry entry in attributeUses) {
623                                 XmlSchemaAttribute attr = (XmlSchemaAttribute) entry.Value;
624                                 XmlSchemaDatatype dt = attr.AttributeType as XmlSchemaDatatype;
625                                 if (dt != null && dt.TokenizedType != XmlTokenizedType.ID)
626                                         continue;
627                                 if (dt == null)
628                                         dt = ((XmlSchemaSimpleType) attr.AttributeType).Datatype;
629                                 if (dt != null && dt.TokenizedType == XmlTokenizedType.ID) {
630                                         if (idAttr != null)
631                                                 error (h, "Two or more ID typed attribute declarations in a complex type are found.");
632                                         else
633                                                 idAttr = attr;
634                                 }
635                         }
636
637                         ValidationId = schema.ValidationId;
638                         return errorCount;
639                 }
640
641                 private void ValidateImmediateAttributes (ValidationEventHandler h, XmlSchema schema)
642                 {
643                         // {attribute uses}
644                         // also checks 3.4.6 Properties Correct :: 4 (Distinct attributes)
645                         attributeUses = new XmlSchemaObjectTable ();
646                         XmlSchemaUtil.ValidateAttributesResolved (attributeUses,
647                                 h, schema, attributes, anyAttribute, ref attributeWildcard, null, false);
648                 }
649
650                 private void ValidateContentFirstPass (ValidationEventHandler h, XmlSchema schema)
651                 {
652                         if (ContentModel != null) {
653                                 errorCount += contentModel.Validate (h, schema);
654                                 if (BaseXmlSchemaTypeInternal != null)
655                                         errorCount += BaseXmlSchemaTypeInternal.Validate (h, schema);
656                         }
657                         else if (Particle != null) {
658                                 errorCount += particle.Validate (h, schema);
659                                 XmlSchemaGroupRef pgrp = Particle as XmlSchemaGroupRef;
660                                 if (pgrp != null) {
661                                         if (pgrp.TargetGroup != null)
662                                                 errorCount += pgrp.TargetGroup.Validate (h,schema);
663                                         // otherwise, it might be missing sub components.
664                                         else if (!schema.IsNamespaceAbsent (pgrp.RefName.Namespace))
665                                                 error (h, "Referenced group " + pgrp.RefName + " was not found in the corresponding schema.");
666                                 }
667                         }
668                 }
669
670                 private void ValidateContentModel (ValidationEventHandler h, XmlSchema schema)
671                 {
672                         XmlSchemaType baseType = BaseXmlSchemaTypeInternal;
673
674                         // Here we check 3.4.6 Properties Correct :: 2. and 3.
675                         XmlSchemaComplexContentExtension cce = contentModel.Content as XmlSchemaComplexContentExtension;
676                         XmlSchemaComplexContentRestriction ccr = contentModel.Content as XmlSchemaComplexContentRestriction;
677                         XmlSchemaSimpleContentExtension sce = contentModel.Content as XmlSchemaSimpleContentExtension;
678                         XmlSchemaSimpleContentRestriction scr = contentModel.Content as XmlSchemaSimpleContentRestriction;
679
680                         XmlSchemaAnyAttribute localAnyAttribute = null;
681                         XmlSchemaAnyAttribute baseAnyAttribute = null;
682
683                         // 3.4.6 Properties Correct :: 3. Circular definition prohibited.
684                         if (ValidateRecursionCheck ())
685                                 error (h, "Circular definition of schema types was found.");
686                         if (baseType != null) {
687                                 // Fill "Datatype" property.
688                                 this.DatatypeInternal = baseType.Datatype;
689                         } else if (BaseSchemaTypeName == XmlSchemaComplexType.AnyTypeName)
690                                 DatatypeInternal = XmlSchemaSimpleType.AnySimpleType;
691                         else if (XmlSchemaUtil.IsBuiltInDatatypeName (BaseSchemaTypeName)) {
692                                 DatatypeInternal = XmlSchemaDatatype.FromName (BaseSchemaTypeName);
693                         }
694
695                         XmlSchemaComplexType baseComplexType = baseType as XmlSchemaComplexType;
696                         XmlSchemaSimpleType baseSimpleType = baseType as XmlSchemaSimpleType;
697
698                         // 3.4.6 Derivation Valid (common to Extension and Restriction, Complex) :: 1.
699                         if (baseType != null && (baseType.FinalResolved & resolvedDerivedBy) != 0)
700                                         error (h, "Specified derivation is specified as final by derived schema type.");
701
702                         // 3.4.6 Properties Correct :: 2.
703                         // Simple {base type definition} and restriction {derivation method} not allowed.
704                         if (baseSimpleType != null && resolvedDerivedBy == XmlSchemaDerivationMethod.Restriction)
705                                 error (h, "If the base schema type is a simple type, then this type must be extension.");
706
707                         // Common to complexContent
708                         if (cce != null || ccr != null) {
709                                 // 3.4.3 Complex Type Definition Representation OK :: 1.
710                                 // base
711                                 if (BaseSchemaTypeName == XmlSchemaComplexType.AnyTypeName)
712                                         baseComplexType = XmlSchemaComplexType.AnyType;
713                                 else if (XmlSchemaUtil.IsBuiltInDatatypeName (BaseSchemaTypeName))
714                                         error (h, "Referenced base schema type is XML Schema datatype.");
715                                 else if (baseComplexType == null && !schema.IsNamespaceAbsent (BaseSchemaTypeName.Namespace))
716                                         error (h, "Referenced base schema type " + BaseSchemaTypeName + " was not complex type or not found in the corresponding schema.");
717                         }
718                         // Common to simpleContent 
719                         else {
720                                 // ContentType of {content type}
721                                 resolvedContentType = XmlSchemaContentType.TextOnly;
722
723                                 // 3.4.3 Complex Type Definition Representation OK :: 1.
724                                 // base
725                                 if (BaseSchemaTypeName == XmlSchemaComplexType.AnyTypeName)
726                                         baseComplexType = XmlSchemaComplexType.AnyType;
727
728                                 if (baseComplexType != null && baseComplexType.ContentType != XmlSchemaContentType.TextOnly) {
729                                         error (h, "Base schema complex type of a simple content must be simple content type. Base type is " + BaseSchemaTypeName);
730                                 } else if (sce == null && (baseSimpleType != null && BaseSchemaTypeName.Namespace != XmlSchema.Namespace)) {
731                                         error (h, "If a simple content is not an extension, base schema type must be complex type. Base type is " + BaseSchemaTypeName);
732                                 } else if (XmlSchemaUtil.IsBuiltInDatatypeName (BaseSchemaTypeName)) {
733                                         // do nothing for particle.
734                                 }
735                                 // otherwise, it might be missing sub components.
736                                 else if (baseType == null && !schema.IsNamespaceAbsent (BaseSchemaTypeName.Namespace))
737                                         error (h, "Referenced base schema type " + BaseSchemaTypeName + " was not found in the corresponding schema.");
738
739                                 // 3.4.3 Complex Type Definition Representation OK :: 2.
740                                 // Note that baseSimpleType is also allowed as to Errata E1-27 (http://www.w3.org/2001/05/xmlschema-errata)
741                                 if (baseComplexType != null) {
742                                         if (baseComplexType.ContentType == XmlSchemaContentType.TextOnly) {
743                                                 // 2.1.1
744                                         // Here "baseComplexType.Particle != null" is required for error-ignorant case
745                                         } else if (scr != null && baseComplexType.ContentType == XmlSchemaContentType.Mixed && baseComplexType.Particle != null && baseComplexType.Particle.ValidateIsEmptiable () && scr.BaseType != null) {
746                                                 // 2.1.2 && 2.2: OK
747                                         }
748                                         else
749                                                 error (h, "Base complex type of a simple content restriction must be text only.");
750                                 } else {
751                                         if (sce != null && baseComplexType == null) {
752                                                 // 2.1.3 : OK
753                                         }
754                                         else
755                                                 error (h, "Not allowed base type of a simple content restriction.");
756                                 }
757                         }
758
759                         // complexType/complexContent/extension
760                         if (cce != null) {
761                                 // I don't think 3.4.6 Derivation Valid (Extension) :: 1.2
762                                 // is constraining anything here, since 3.4.2 {attribute uses}
763                                 // defines as to include base type's attribute uses.
764                                 localAnyAttribute = cce.AnyAttribute;
765                                 if (baseComplexType != null) {
766                                         foreach (DictionaryEntry entry in baseComplexType.AttributeUses) {
767                                                 XmlSchemaAttribute attr = (XmlSchemaAttribute) entry.Value;
768                                                 XmlSchemaUtil.AddToTable (attributeUses, attr, attr.QualifiedName, h);
769                                         }
770                                         baseAnyAttribute = baseComplexType.AttributeWildcard;
771                                 }
772                                 // attributes
773                                 errorCount += XmlSchemaUtil.ValidateAttributesResolved (
774                                         this.attributeUses, h, schema, cce.Attributes, 
775                                         cce.AnyAttribute , ref attributeWildcard, null, true);
776
777                                 // After adding them, test extension validity.
778                                 if (baseComplexType != null)
779                                         this.ValidateComplexBaseDerivationValidExtension (baseComplexType, h, schema);
780                                 else if (baseSimpleType != null)
781                                         this.ValidateSimpleBaseDerivationValidExtension (baseSimpleType, h, schema);
782                         }
783                         // complexType/complexContent/restriction
784                         if (ccr != null) {
785                                 // For ValidationEventHandler.
786                                 if (baseComplexType == null)
787                                         baseComplexType = XmlSchemaComplexType.AnyType;
788
789                                 // attributes
790                                 localAnyAttribute = ccr.AnyAttribute;
791                                 this.attributeWildcard = localAnyAttribute;
792                                 if (baseComplexType != null)
793                                         baseAnyAttribute = baseComplexType.AttributeWildcard;
794                                 if (baseAnyAttribute != null && localAnyAttribute != null)
795                                         // 1.3 attribute wildcard subset. (=> 3.10.6)
796                                         localAnyAttribute.ValidateWildcardSubset (baseAnyAttribute, h, schema);
797
798                                 // 3.4.2 Complex Type Definition with complex content Schema Component
799                                 // and its {attribute uses} and {attribute wildcard} are done here (descendantly)
800                                 errorCount += XmlSchemaUtil.ValidateAttributesResolved (
801                                         this.attributeUses, h, schema, ccr.Attributes, 
802                                         ccr.AnyAttribute, ref attributeWildcard, null, false);
803                                 foreach (DictionaryEntry entry in baseComplexType.AttributeUses) {
804                                         XmlSchemaAttribute attr = (XmlSchemaAttribute) entry.Value;
805                                         if (attributeUses [attr.QualifiedName] == null)
806                                                 XmlSchemaUtil.AddToTable (attributeUses, attr, attr.QualifiedName, h);
807                                 }
808
809                                 // Derivation Valid (Restriction, Complex) :: 5.
810                                 // Also see E1-15 of http://www.w3.org/2001/05/xmlschema-errata#Errata1
811                                 // 5.1 shouled be in scr (XmlSchemaSimpleContentRestriction)
812                                 this.ValidateDerivationValidRestriction (baseComplexType, h, schema);
813                         }
814                         // complexType/simpleContent/extension
815                         if (sce != null) {
816                                 errorCount += XmlSchemaUtil.ValidateAttributesResolved (
817                                         this.attributeUses, h, schema, sce.Attributes, 
818                                         sce.AnyAttribute, ref attributeWildcard, null, true);
819
820                                 // Attributes
821                                 // I don't think 3.4.6 Derivation Valid (Extension) :: 1.2
822                                 // is constraining anything here, since 3.4.2 {attribute uses}
823                                 // defines as to include base type's attribute uses.
824                                 localAnyAttribute = sce.AnyAttribute;
825
826                                 if (baseComplexType != null) {
827                                         baseAnyAttribute = baseComplexType.AttributeWildcard;
828
829                                         foreach (DictionaryEntry entry in baseComplexType.AttributeUses) {
830                                                 XmlSchemaAttribute attr = (XmlSchemaAttribute) entry.Value;
831 #if BUGGY_MS_COMPLIANT
832                                                 if (attr.Use != XmlSchemaUse.Prohibited)
833                                                         XmlSchemaUtil.AddToTable (attributeUses, attr, attr.QualifiedName, h);
834 #endif
835                                                 XmlSchemaUtil.AddToTable (attributeUses, attr, attr.QualifiedName, h);
836                                         }
837                                 }
838                                 if (baseAnyAttribute != null && localAnyAttribute != null)
839                                         // 1.3 attribute wildcard subset. (=> 3.10.6)
840                                         localAnyAttribute.ValidateWildcardSubset (baseAnyAttribute, h, schema);
841                         }
842                         // complexType/simpleContent/restriction
843                         if (scr != null) {
844                                 // Attributes
845                                 baseAnyAttribute = baseComplexType != null ? baseComplexType.AttributeWildcard : null;
846
847                                 localAnyAttribute = scr.AnyAttribute;
848                                 if (localAnyAttribute != null && baseAnyAttribute != null)
849                                         // 1.3 attribute wildcard subset. (=> 3.10.6)
850                                         localAnyAttribute.ValidateWildcardSubset (baseAnyAttribute, h, schema);
851                                 // 3.4.6 :: 5.1. Beware that There is an errata for 5.1!!
852                                 // http://www.w3.org/2001/05/xmlschema-errata#Errata1
853
854                                 // 3.4.2 Complex Type Definition with simple content Schema Component
855                                 // and its {attribute uses} and {attribute wildcard} are done here (descendantly)
856                                 errorCount += XmlSchemaUtil.ValidateAttributesResolved (
857                                         this.attributeUses, h, schema, scr.Attributes, 
858                                         scr.AnyAttribute, ref attributeWildcard, null, false);
859                         }
860
861                         // Common process of AttributeWildcard.
862                         if (localAnyAttribute != null) {
863                                 this.attributeWildcard = localAnyAttribute;
864                         }
865                         else
866                                 this.attributeWildcard = baseAnyAttribute;
867                 }
868
869                 // 3.4.6 Type Derivation OK (Complex)
870                 internal void ValidateTypeDerivationOK (object b, ValidationEventHandler h, XmlSchema schema)
871                 {
872                         // AnyType derives from AnyType itself.
873                         if (this == XmlSchemaComplexType.AnyType && BaseXmlSchemaType == this)
874                                 return;
875
876                         XmlSchemaType bst = b as XmlSchemaType;
877                         if (b == this)  // 1 and 2.1
878                                 return;
879                         if (bst != null && (resolvedDerivedBy & bst.FinalResolved) != 0) // 1.
880                                 error (h, "Derivation type " + resolvedDerivedBy + " is prohibited by the base type.");
881                         // FIXME: here BaseSchemaType should be 
882                         // BaseXmlSchemaType, however for some case it 
883                         // seems not working.
884                         if (BaseSchemaType == b) // 2.2
885                                 return;
886                         if (BaseSchemaType == null || BaseXmlSchemaType == XmlSchemaComplexType.AnyType) { // 2.3.1
887                                 error (h, "Derived type's base schema type is anyType.");
888                                 return;
889                         }
890                         // 2.3.2.1
891                         XmlSchemaComplexType dbct = BaseXmlSchemaType as XmlSchemaComplexType;
892                         if (dbct != null) {
893                                 dbct.ValidateTypeDerivationOK (b, h, schema);
894                                 return;
895                         }
896                         // 2.3.2.2
897                         XmlSchemaSimpleType dbst = BaseXmlSchemaType as XmlSchemaSimpleType;
898                         if (dbst != null) {
899                                 dbst.ValidateTypeDerivationOK (b, h, schema, true);
900                                 return;
901                         }
902                 }
903
904                 // 3.4.6 Derivation Valid (Extension) - Term. 1 (Complex Type)
905                 internal void ValidateComplexBaseDerivationValidExtension (XmlSchemaComplexType baseComplexType,
906                         ValidationEventHandler h, XmlSchema schema)
907                 {
908                         // 1.1
909                         if ((baseComplexType.FinalResolved & XmlSchemaDerivationMethod.Extension) != 0)
910                                 error (h, "Derivation by extension is prohibited.");
911                         // 1.2
912                         foreach (DictionaryEntry entry in baseComplexType.AttributeUses) {
913                                 XmlSchemaAttribute ba = (XmlSchemaAttribute) entry.Value;
914                                 XmlSchemaAttribute da = AttributeUses [ba.QualifiedName] as XmlSchemaAttribute;
915                                 if (da == null)
916                                         error (h, "Invalid complex type derivation by extension was found. Missing attribute was found: " + ba.QualifiedName + " .");
917                         }
918                         // 1.3 -> 3.10.6 Wildcard Subset.
919                         if (AnyAttribute != null) {
920                                 if (baseComplexType.AnyAttribute == null)
921                                         error (h, "Invalid complex type derivation by extension was found. Base complex type does not have an attribute wildcard.");
922                                 else
923                                         baseComplexType.AnyAttribute.ValidateWildcardSubset (AnyAttribute, h, schema);
924                         }
925
926                         // 1.4 => 1.4.2 (1.4.1 would be included in SimpleContentExtention).
927                         // 1.4.2.1
928 //                      if (contentTypeParticle == null)
929 //                              error (h, "Extended complex type's content type must not be empty.");
930                         // 1.4.2.2.1
931                         if (baseComplexType.ContentType != XmlSchemaContentType.Empty) {
932                                 // 1.4.2.2.2.1
933                                 if (this.ContentType != baseComplexType.ContentType)
934 //                              if (this.GetContentType (false) != baseComplexType.GetContentType (false))
935                                         error (h, "Base complex type has different content type " + baseComplexType.ContentType + ".");
936                                 // 1.4.2.2.2.2 => 3.9.6 Particle Valid (Extension)
937                                 else if (this.contentTypeParticle == null ||
938                                         !this.contentTypeParticle.ParticleEquals (baseComplexType.ContentTypeParticle)) {
939                                         XmlSchemaSequence seq = contentTypeParticle as XmlSchemaSequence;
940                                         if (contentTypeParticle != XmlSchemaParticle.Empty && (seq == null || contentTypeParticle.ValidatedMinOccurs != 1 || contentTypeParticle.ValidatedMaxOccurs != 1))
941                                                 error (h, "Invalid complex content extension was found.");
942                                         else {
943                                                 // Identical sequence item should be checked, but
944                                                 // I think it is naturally achieved as coded above.
945                                         }
946                                 }
947                         }
948                 }
949
950                 // 3.4.6 Derivation Valid (Extension) - Term. 2 (Simple Type)
951                 internal void ValidateSimpleBaseDerivationValidExtension (object baseType,
952                         ValidationEventHandler h, XmlSchema schema)
953                 {
954                         XmlSchemaSimpleType st = baseType as XmlSchemaSimpleType;
955                         if (st != null && (st.FinalResolved & XmlSchemaDerivationMethod.Extension) != 0)
956                                 error (h, "Extension is prohibited by the base type.");
957
958                         XmlSchemaDatatype dt = baseType as XmlSchemaDatatype;
959                         if (dt == null)
960                                 dt = st.Datatype;
961                         if (dt != this.Datatype)
962                                 error (h, "To extend simple type, a complex type must have the same content type as the base type.");
963                 }
964
965                 internal void ValidateDerivationValidRestriction (XmlSchemaComplexType baseType,
966                         ValidationEventHandler h, XmlSchema schema)
967                 {
968                         // 1.
969                         if (baseType == null) {
970                                 error (h, "Base schema type is not a complex type.");
971                                 return;
972                         }
973                         if ((baseType.FinalResolved & XmlSchemaDerivationMethod.Restriction) != 0) {
974                                 error (h, "Prohibited derivation by restriction by base schema type.");
975                                 return;
976                         }
977
978                         // 2.
979                         foreach (DictionaryEntry entry in this.AttributeUses) {
980                                 XmlSchemaAttribute attr = (XmlSchemaAttribute) entry.Value;
981                                 XmlSchemaAttribute baseAttr = baseType.AttributeUses [attr.QualifiedName] as XmlSchemaAttribute;
982                                 if (baseAttr != null) {
983                                         // 2.1
984                                         // 2.1.1
985                                         if (baseAttr.ValidatedUse != XmlSchemaUse.Optional && attr.ValidatedUse != XmlSchemaUse.Required)
986                                                 error (h, "Invalid attribute derivation by restriction was found for " + attr.QualifiedName + " .");
987                                         // 2.1.2
988                                         XmlSchemaSimpleType attrSimpleType = attr.AttributeType as XmlSchemaSimpleType;
989                                         XmlSchemaSimpleType baseAttrSimpleType = baseAttr.AttributeType as XmlSchemaSimpleType;
990                                         bool typeError = false;
991                                         if (attrSimpleType != null)
992                                                 attrSimpleType.ValidateDerivationValid (baseAttrSimpleType, null, h, schema);
993                                         else if (attrSimpleType == null && baseAttrSimpleType != null)
994                                                 typeError = true;
995                                         else {
996                                                 Type t1 = attr.AttributeType.GetType ();
997                                                 Type t2 = baseAttr.AttributeType.GetType ();
998                                                 if (t1 != t2 && t1.IsSubclassOf (t2))
999                                                         typeError = true;
1000                                         }
1001                                         if (typeError)
1002                                                 error (h, "Invalid attribute derivation by restriction because of its type: " + attr.QualifiedName + " .");
1003                                         // 2.1.3
1004                                         if (baseAttr.ValidatedFixedValue != null && attr.ValidatedFixedValue != baseAttr.ValidatedFixedValue)
1005                                                 error (h, "Invalid attribute derivation by restriction because of its fixed value constraint: " + attr.QualifiedName + " .");
1006                                 } else {
1007                                         // 2.2
1008                                         if (baseType.AttributeWildcard != null)
1009                                                 if (!baseType.AttributeWildcard.ValidateWildcardAllowsNamespaceName (
1010                                                         attr.QualifiedName.Namespace, schema) &&
1011                                                         !schema.IsNamespaceAbsent (attr.QualifiedName.Namespace))
1012                                                         error (h, "Invalid attribute derivation by restriction was found for " + attr.QualifiedName + " .");
1013                                 }
1014                         }
1015                         // I think 3. is considered in 2.
1016                         // 4.
1017                         if (this.AttributeWildcard != null && baseType != XmlSchemaComplexType.AnyType) {
1018                                 if (baseType.AttributeWildcard == null)
1019                                         error (h, "Invalid attribute derivation by restriction because of attribute wildcard.");
1020                                 else
1021                                         AttributeWildcard.ValidateWildcardSubset (baseType.AttributeWildcard, h, schema);
1022                         }
1023
1024                         // 5.
1025                         if (this == AnyType)
1026                                 return;
1027                         if (contentTypeParticle == XmlSchemaParticle.Empty) {
1028                                 // 5.1
1029                                 if (ContentType != XmlSchemaContentType.Empty) {
1030                                         // TODO: 5.1.1
1031 //                                      XmlSchemaSimpleType baseST = baseType as XmlSchemaSimpleType;
1032                                         // 5.1.2
1033                                         if (baseType.ContentType == XmlSchemaContentType.Mixed && !baseType.ContentTypeParticle.ValidateIsEmptiable ())
1034                                                 error (h, "Invalid content type derivation.");
1035
1036                                 } else {
1037                                         // 5.2
1038                                         if (baseType.ContentTypeParticle != XmlSchemaParticle.Empty &&
1039                                                 !baseType.ContentTypeParticle.ValidateIsEmptiable ())
1040                                                 error (h, "Invalid content type derivation.");
1041                                 }
1042                         } else {
1043                                 // 5.3 => 3.9.6 Particle Valid (Restriction)
1044                                 if (baseType.ContentTypeParticle != null) {
1045                                         // 3.9.6 - 1 : same particle.
1046                                         // 3.9.6 - 2 is covered by using ActualParticle.
1047                                         if (!contentTypeParticle.ParticleEquals (baseType.ContentTypeParticle))
1048                                                 contentTypeParticle.ValidateDerivationByRestriction (baseType.ContentTypeParticle, h, schema, true);
1049                                 }
1050                         }
1051                 }
1052
1053 #region Read
1054                 //<complexType
1055                 //  abstract = boolean : false
1056                 //  block = (#all | List of (extension | restriction)) 
1057                 //  final = (#all | List of (extension | restriction)) 
1058                 //  id = ID
1059                 //  mixed = boolean : false
1060                 //  name = NCName
1061                 //  {any attributes with non-schema namespace . . .}>
1062                 //  Content: (annotation?, (simpleContent | complexContent | ((group | all | choice | sequence)?, ((attribute | attributeGroup)*, anyAttribute?))))
1063                 //</complexType>
1064                 internal static XmlSchemaComplexType Read(XmlSchemaReader reader, ValidationEventHandler h)
1065                 {
1066                         XmlSchemaComplexType ctype = new XmlSchemaComplexType();
1067                         reader.MoveToElement();
1068                         Exception innerex;
1069
1070                         if(reader.NamespaceURI != XmlSchema.Namespace || reader.LocalName != xmlname)
1071                         {
1072                                 error(h,"Should not happen :1: XmlSchemaComplexType.Read, name="+reader.Name,null);
1073                                 reader.SkipToEnd();
1074                                 return null;
1075                         }
1076
1077                         ctype.LineNumber = reader.LineNumber;
1078                         ctype.LinePosition = reader.LinePosition;
1079                         ctype.SourceUri = reader.BaseURI;
1080
1081                         while(reader.MoveToNextAttribute())
1082                         {
1083                                 if(reader.Name == "abstract")
1084                                 {
1085                                         ctype.IsAbstract = XmlSchemaUtil.ReadBoolAttribute(reader,out innerex);
1086                                         if(innerex != null)
1087                                                 error(h,reader.Value + " is invalid value for abstract",innerex);
1088                                 }
1089                                 else if(reader.Name == "block")
1090                                 {
1091                                         ctype.block = XmlSchemaUtil.ReadDerivationAttribute(reader,out innerex, "block",
1092                                                 XmlSchemaUtil.ComplexTypeBlockAllowed);
1093                                         if(innerex != null)
1094                                                 error (h,"some invalid values for block attribute were found",innerex);
1095                                 }
1096                                 else if(reader.Name == "final")
1097                                 {
1098                                         ctype.Final = XmlSchemaUtil.ReadDerivationAttribute(reader,out innerex, "final",
1099                                                 XmlSchemaUtil.FinalAllowed);
1100                                         if(innerex != null)
1101                                                 error (h,"some invalid values for final attribute were found",innerex);
1102                                 }
1103                                 else if(reader.Name == "id")
1104                                 {
1105                                         ctype.Id = reader.Value;
1106                                 }
1107                                 else if(reader.Name == "mixed")
1108                                 {
1109                                         ctype.isMixed = XmlSchemaUtil.ReadBoolAttribute(reader,out innerex);
1110                                         if(innerex != null)
1111                                                 error(h,reader.Value + " is invalid value for mixed",innerex);
1112                                 }
1113                                 else if(reader.Name == "name")
1114                                 {
1115                                         ctype.Name = reader.Value;
1116                                 }
1117                                 else if((reader.NamespaceURI == "" && reader.Name != "xmlns") || reader.NamespaceURI == XmlSchema.Namespace)
1118                                 {
1119                                         error(h,reader.Name + " is not a valid attribute for complexType",null);
1120                                 }
1121                                 else
1122                                 {
1123                                         XmlSchemaUtil.ReadUnhandledAttribute(reader,ctype);
1124                                 }
1125                         }
1126                         
1127                         reader.MoveToElement();
1128                         if(reader.IsEmptyElement)
1129                                 return ctype;
1130
1131                         //Content: 1. annotation?, 
1132                         //                 2. simpleContent | 2. complexContent | 
1133                         //                      (3.(group | all | choice | sequence)?, (4.(attribute | attributeGroup)*, 5.anyAttribute?)))
1134                         int level = 1;
1135                         while(reader.ReadNextElement())
1136                         {
1137                                 if(reader.NodeType == XmlNodeType.EndElement)
1138                                 {
1139                                         if(reader.LocalName != xmlname)
1140                                                 error(h,"Should not happen :2: XmlSchemaComplexType.Read, name="+reader.Name,null);
1141                                         break;
1142                                 }
1143                                 if(level <= 1 && reader.LocalName == "annotation")
1144                                 {
1145                                         level = 2; //Only one annotation
1146                                         XmlSchemaAnnotation annotation = XmlSchemaAnnotation.Read(reader,h);
1147                                         if(annotation != null)
1148                                                 ctype.Annotation = annotation;
1149                                         continue;
1150                                 }
1151                                 if(level <=2)
1152                                 {
1153                                         if(reader.LocalName == "simpleContent")
1154                                         {
1155                                                 level = 6;
1156                                                 XmlSchemaSimpleContent simple = XmlSchemaSimpleContent.Read(reader,h);
1157                                                 if(simple != null)
1158                                                         ctype.ContentModel = simple;
1159                                                 continue;
1160                                         }
1161                                         if(reader.LocalName == "complexContent")
1162                                         {
1163                                                 level = 6;
1164                                                 XmlSchemaComplexContent complex = XmlSchemaComplexContent.Read(reader,h);
1165                                                 if(complex != null)
1166                                                         ctype.contentModel = complex;
1167                                                 continue;
1168                                         }
1169                                 }
1170                                 if(level <= 3)
1171                                 {
1172                                         if(reader.LocalName == "group")
1173                                         {
1174                                                 level = 4;
1175                                                 XmlSchemaGroupRef group = XmlSchemaGroupRef.Read(reader,h);
1176                                                 if(group != null)
1177                                                         ctype.particle = group;
1178                                                 continue;
1179                                         }
1180                                         if(reader.LocalName == "all")
1181                                         {
1182                                                 level = 4;
1183                                                 XmlSchemaAll all = XmlSchemaAll.Read(reader,h);
1184                                                 if(all != null)
1185                                                         ctype.particle = all;
1186                                                 continue;
1187                                         }
1188                                         if(reader.LocalName == "choice")
1189                                         {
1190                                                 level = 4;
1191                                                 XmlSchemaChoice choice = XmlSchemaChoice.Read(reader,h);
1192                                                 if(choice != null)
1193                                                         ctype.particle = choice;
1194                                                 continue;
1195                                         }
1196                                         if(reader.LocalName == "sequence")
1197                                         {
1198                                                 level = 4;
1199                                                 XmlSchemaSequence sequence = XmlSchemaSequence.Read(reader,h);
1200                                                 if(sequence != null)
1201                                                         ctype.particle = sequence;
1202                                                 continue;
1203                                         }
1204                                 }
1205                                 if(level <= 4)
1206                                 {
1207                                         if(reader.LocalName == "attribute")
1208                                         {
1209                                                 level = 4;
1210                                                 XmlSchemaAttribute attr = XmlSchemaAttribute.Read(reader,h);
1211                                                 if(attr != null)
1212                                                         ctype.Attributes.Add(attr);
1213                                                 continue;
1214                                         }
1215                                         if(reader.LocalName == "attributeGroup")
1216                                         {
1217                                                 level = 4;
1218                                                 XmlSchemaAttributeGroupRef attr = XmlSchemaAttributeGroupRef.Read(reader,h);
1219                                                 if(attr != null)
1220                                                         ctype.attributes.Add(attr);
1221                                                 continue;
1222                                         }
1223                                 }
1224                                 if(level <= 5 && reader.LocalName == "anyAttribute")
1225                                 {
1226                                         level = 6;
1227                                         XmlSchemaAnyAttribute anyattr = XmlSchemaAnyAttribute.Read(reader,h);
1228                                         if(anyattr != null)
1229                                                 ctype.AnyAttribute = anyattr;
1230                                         continue;
1231                                 }
1232                                 reader.RaiseInvalidElementError();
1233                         }
1234                         return ctype;
1235                 }
1236 #endregion
1237         }
1238 }