New tests.
[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 = "anyType";
70                                         anyType.QNameInternal = new XmlQualifiedName ("anyType", XmlSchema.Namespace);
71                                         if (XmlSchemaUtil.StrictMsCompliant)
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
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                         attributeUses.Clear();
227
228                         if (isRedefinedComponent) {
229                                 if (Annotation != null)
230                                         Annotation.isRedefinedComponent = true;
231                                 if (AnyAttribute != null)
232                                         AnyAttribute.isRedefinedComponent = true;
233                                 foreach (XmlSchemaObject obj in Attributes)
234                                         obj.isRedefinedComponent = true;
235                                 if (ContentModel != null)
236                                         ContentModel.isRedefinedComponent = true;
237                                 if (Particle != null)
238                                         Particle.isRedefinedComponent = true;
239                         }
240
241                         // block/final resolution
242                         if(ParentIsSchema || isRedefineChild)
243                         {
244                                 if(this.Name == null || this.Name == string.Empty)
245                                         error(h,"name must be present in a top level complex type");
246                                 else if(!XmlSchemaUtil.CheckNCName(Name))
247                                         error(h,"name must be a NCName");
248                                 else
249                                         this.QNameInternal = new XmlQualifiedName(Name, AncestorSchema.TargetNamespace);
250                                 
251                                 if(Block != XmlSchemaDerivationMethod.None)
252                                 {
253                                         if(Block == XmlSchemaDerivationMethod.All)
254                                         {
255                                                 blockResolved = XmlSchemaDerivationMethod.All;
256                                         }
257                                         else
258                                         {
259                                                 if ((Block & XmlSchemaUtil.ComplexTypeBlockAllowed) != Block)
260                                                         error (h, "Invalid block specification.");
261                                                 blockResolved = Block & XmlSchemaUtil.ComplexTypeBlockAllowed;
262                                         }
263                                 }
264                                 else
265                                 {
266                                         switch (schema.BlockDefault) {
267                                         case XmlSchemaDerivationMethod.All:
268                                                 blockResolved = XmlSchemaDerivationMethod.All;
269                                                 break;
270                                         case XmlSchemaDerivationMethod.None:
271                                                 blockResolved = XmlSchemaDerivationMethod.Empty;
272                                                 break;
273                                         default:
274                                                 blockResolved = schema.BlockDefault & XmlSchemaUtil.ComplexTypeBlockAllowed;
275                                                 break;
276                                         }
277                                 }
278
279                                 if(Final != XmlSchemaDerivationMethod.None)
280                                 {
281                                         if(Final == XmlSchemaDerivationMethod.All)
282                                                 finalResolved = XmlSchemaDerivationMethod.All;
283                                         else if ((Final & XmlSchemaUtil.FinalAllowed) != Final)
284                                                 error (h, "Invalid final specification.");
285                                         else
286                                                 finalResolved = Final;
287                                 }
288                                 else
289                                 {
290                                         switch (schema.FinalDefault) {
291                                         case XmlSchemaDerivationMethod.All:
292                                                 finalResolved = XmlSchemaDerivationMethod.All;
293                                                 break;
294                                         case XmlSchemaDerivationMethod.None:
295                                                 finalResolved = XmlSchemaDerivationMethod.Empty;
296                                                 break;
297                                         default:
298                                                 finalResolved = schema.FinalDefault & XmlSchemaUtil.FinalAllowed;
299                                                 break;
300                                         }
301                                 }
302                         }
303                         else // Not Top Level
304                         {
305                                 if(isAbstract)
306                                         error(h,"abstract must be false in a local complex type");
307                                 if(Name != null)
308                                         error(h,"name must be absent in a local complex type");
309                                 if(Final != XmlSchemaDerivationMethod.None)
310                                         error(h,"final must be absent in a local complex type");
311                                 if(block != XmlSchemaDerivationMethod.None)
312                                         error(h,"block must be absent in a local complex type");
313                         }
314
315                         // Process contents and BaseSchemaType
316                         if(contentModel != null)
317                         {
318                                 if(anyAttribute != null || Attributes.Count != 0 || Particle != null)
319                                         error(h,"attributes, particles or anyattribute is not allowed if ContentModel is present");
320                                 errorCount += contentModel.Compile (h, schema);
321
322                                 XmlSchemaSimpleContent smodel = ContentModel as XmlSchemaSimpleContent;
323                                 if(smodel != null)
324                                 {
325                                         XmlSchemaSimpleContentExtension sscx = smodel.Content as XmlSchemaSimpleContentExtension;
326                                         if (sscx == null) {
327                                                 XmlSchemaSimpleContentRestriction sscr = smodel.Content as XmlSchemaSimpleContentRestriction;
328                                                 if (sscr != null) {
329                                                         if (sscr.BaseType != null) {
330                                                                 sscr.BaseType.Compile (h, schema);
331                                                                 BaseXmlSchemaTypeInternal = sscr.BaseType;
332                                                         }
333                                                 }
334                                         }
335                                 }
336                         }
337                         else
338                         {
339                                 if (Particle != null)
340                                         errorCount += Particle.Compile (h, schema);
341
342                                 if(this.anyAttribute != null)
343                                 {
344                                         AnyAttribute.Compile(h,schema);
345                                 }
346                                 foreach(XmlSchemaObject obj in Attributes)
347                                 {
348                                         if(obj is XmlSchemaAttribute)
349                                         {
350                                                 XmlSchemaAttribute attr = (XmlSchemaAttribute) obj;
351                                                 errorCount += attr.Compile(h,schema);
352                                         }
353                                         else if(obj is XmlSchemaAttributeGroupRef)
354                                         {
355                                                 XmlSchemaAttributeGroupRef atgrp = (XmlSchemaAttributeGroupRef) obj;
356                                                 errorCount += atgrp.Compile(h,schema);
357                                         }
358                                         else
359                                                 error(h,obj.GetType() +" is not valid in this place::ComplexType");
360                                 }
361                         }
362
363                         XmlSchemaUtil.CompileID(Id, this, schema.IDCollection, h);
364                         this.CompilationId = schema.CompilationId;
365                         return errorCount;
366                 }
367
368                 Guid CollectProcessId;
369
370                 private void CollectSchemaComponent (ValidationEventHandler h, XmlSchema schema)
371                 {
372                         if (CollectProcessId == schema.CompilationId)
373                                 return;
374                         // Below are already contributed by Compile():
375                         // {name}, {namespace} => QualifiedName, QNameInternal
376                         // {abstract} => ValidatedIsAbstract
377                         // {prohibited substitutions} => BlockResolved
378                         // {final} => FinalResolved
379                         // {annotations} => Annotation (XmlSchemaAnnotated)
380
381                         // Below are different properties depending on simpleContent | complexContent.
382                         // {base type definition}
383                         // {derivation method}
384                         // {attribute uses} => AttributeUses (later)
385                         // {attribute wildcard} => AttributeWildcard (later)
386                         // {content type}
387
388
389                         // {base type definition} => baseSchemaTypeInternal (later)
390                         if (contentModel != null) {
391                                 BaseSchemaTypeName = contentModel.Content != null ? contentModel.Content.GetBaseTypeName () : XmlQualifiedName.Empty;
392
393                                 BaseXmlSchemaTypeInternal = schema.FindSchemaType(BaseSchemaTypeName);
394                         }
395                         // Resolve redefine.
396                         if (this.isRedefineChild && BaseXmlSchemaType != null && this.QualifiedName == BaseSchemaTypeName) {
397                                 XmlSchemaType redType = (XmlSchemaType) redefinedObject;
398                                 if (redType == null)
399                                         error (h, "Redefinition base type was not found.");
400                                 else
401                                         BaseXmlSchemaTypeInternal = redType;
402                         }
403
404                         // {derivation method} => resolvedDerivedBy
405                         if (contentModel != null && contentModel.Content != null) {
406                                 resolvedDerivedBy =
407                                         contentModel.Content.IsExtension ?
408                                         XmlSchemaDerivationMethod.Extension :
409                                         XmlSchemaDerivationMethod.Restriction;
410                         }
411                         else
412                                 resolvedDerivedBy = XmlSchemaDerivationMethod.Empty;
413                 }
414
415                 void FillContentTypeParticle (ValidationEventHandler h, XmlSchema schema)
416                 {
417                         if (CollectProcessId == schema.CompilationId)
418                                 return;
419                         CollectProcessId = schema.CompilationId;
420
421                         var ct = BaseXmlSchemaType as XmlSchemaComplexType;
422                         if (ct != null)
423                                 ct.FillContentTypeParticle (h, schema);
424
425                         // {content type} => ContentType and ContentTypeParticle (later)
426                         if (ContentModel != null) {
427                                 CollectContentTypeFromContentModel (h, schema);
428                         } else
429                                 CollectContentTypeFromImmediateContent ();
430
431                         contentTypeParticle = validatableParticle.GetOptimizedParticle (true);
432                         if (contentTypeParticle == XmlSchemaParticle.Empty && resolvedContentType == XmlSchemaContentType.ElementOnly)
433                                 resolvedContentType = XmlSchemaContentType.Empty;
434                 }
435
436                 #region {content type}
437                 private void CollectContentTypeFromImmediateContent ()
438                 {
439                         // leave resolvedDerivedBy as Empty
440                         if (Particle != null)
441                                 validatableParticle = Particle;
442                         if (this == AnyType) {
443                                 resolvedContentType = XmlSchemaContentType.Mixed;
444                                 return;
445                         }
446
447                         if (validatableParticle == XmlSchemaParticle.Empty) {
448                                 // note that this covers "Particle == null" case
449                                 if (this.IsMixed)
450                                         resolvedContentType = XmlSchemaContentType.TextOnly;
451                                 else
452                                         resolvedContentType = XmlSchemaContentType.Empty;
453                         } else {
454                                 if (this.IsMixed)
455                                         resolvedContentType = XmlSchemaContentType.Mixed;
456                                 else
457                                         resolvedContentType = XmlSchemaContentType.ElementOnly;
458                         }
459                         if (this != AnyType)
460                                 BaseXmlSchemaTypeInternal = XmlSchemaComplexType.AnyType;
461                 }
462
463                 private void CollectContentTypeFromContentModel (ValidationEventHandler h, XmlSchema schema)
464                 {
465                         if (ContentModel.Content == null) {
466                                 // basically it is error. Recover by specifying empty content.
467                                 validatableParticle = XmlSchemaParticle.Empty;
468                                 resolvedContentType = XmlSchemaContentType.Empty;
469                                 return;
470                         }
471
472                         if (ContentModel.Content is XmlSchemaComplexContentExtension)
473                                 CollectContentTypeFromComplexExtension (h, schema);
474                         if (ContentModel.Content is XmlSchemaComplexContentRestriction)
475                                 CollectContentTypeFromComplexRestriction ();
476                 }
477
478                 private void CollectContentTypeFromComplexExtension (ValidationEventHandler h, XmlSchema schema)
479                 {
480                         XmlSchemaComplexContentExtension cce = (XmlSchemaComplexContentExtension) ContentModel.Content;
481                         XmlSchemaComplexType baseComplexType = this.BaseXmlSchemaType as XmlSchemaComplexType;
482                         if (baseComplexType != null)
483                                 baseComplexType.CollectSchemaComponent (h ,schema);
484
485                         // It must exist, but consider validation error case.
486                         if (BaseSchemaTypeName == XmlSchemaComplexType.AnyTypeName)
487                                 baseComplexType = XmlSchemaComplexType.AnyType;
488
489                         // On error case, it simply rejects any contents
490                         if (baseComplexType == null) {
491                                 validatableParticle = XmlSchemaParticle.Empty;
492                                 resolvedContentType = XmlSchemaContentType.Empty;
493                                 return;
494                         }
495
496                         // 3.4.2 complex content {content type}
497                         // FIXME: this part is looking different than the spec. sections.
498                         if (cce.Particle == null || cce.Particle == XmlSchemaParticle.Empty) {
499                                 // - 2.1
500                                 if (baseComplexType == null) {
501                                         // Basically it is an error. Considering ValidationEventHandler.
502                                         validatableParticle = XmlSchemaParticle.Empty;
503                                         resolvedContentType = XmlSchemaContentType.Empty;
504                                 } else {
505                                         validatableParticle = baseComplexType.ValidatableParticle;
506                                         resolvedContentType = baseComplexType.resolvedContentType;
507                                         // Bug #501814
508                                         if (resolvedContentType == XmlSchemaContentType.Empty)
509                                                 resolvedContentType = GetComplexContentType (contentModel);
510                                 }
511                         } else if (baseComplexType.validatableParticle == XmlSchemaParticle.Empty
512                                 || baseComplexType == XmlSchemaComplexType.AnyType) {
513                                 // - 2.2
514                                 validatableParticle = cce.Particle;
515                                 resolvedContentType = GetComplexContentType (contentModel);
516                         } else {
517                                 // - 2.3 : create a new sequences that merges both contents.
518                                 XmlSchemaSequence seq = new XmlSchemaSequence ();
519                                 this.CopyInfo (seq);
520                                 seq.Items.Add (baseComplexType.validatableParticle);
521                                 seq.Items.Add (cce.Particle);
522                                 seq.Compile (h, schema);
523                                 seq.Validate (h, schema);
524                                 validatableParticle = seq;
525                                 resolvedContentType = GetComplexContentType (contentModel);
526                         }
527                         if (validatableParticle == null)
528                                 validatableParticle = XmlSchemaParticle.Empty;
529                 }
530
531                 private void CollectContentTypeFromComplexRestriction ()
532                 {
533                         XmlSchemaComplexContentRestriction ccr = (XmlSchemaComplexContentRestriction) ContentModel.Content;
534                         // 3.4.2 complex content schema component {content type}
535                         // - 1.1.1
536                         bool isEmptyParticle = false;
537                         if (ccr.Particle == null) 
538                                 isEmptyParticle = true;
539                         else {
540                                 XmlSchemaGroupBase gb = ccr.Particle as XmlSchemaGroupBase;
541                                 if (gb != null) {
542                                         // - 1.1.2
543                                         if (!(gb is XmlSchemaChoice) && gb.Items.Count == 0)
544                                                 isEmptyParticle = true;
545                                         // - 1.1.3
546                                         else if (gb is XmlSchemaChoice && gb.Items.Count == 0 && gb.ValidatedMinOccurs == 0)
547                                                 isEmptyParticle = true;
548                                 }
549                         }
550                         if (isEmptyParticle) {
551                                 resolvedContentType = XmlSchemaContentType.Empty;
552                                 validatableParticle = XmlSchemaParticle.Empty;
553                         } else {
554                                 // - 1.2.1
555                                 resolvedContentType = GetComplexContentType (contentModel);
556                                 // - 1.2.2
557                                 validatableParticle = ccr.Particle;
558                         }
559                 }
560
561                 // 3.4.2 Complex Content Schema Component {content type} 1.2.1
562                 private XmlSchemaContentType GetComplexContentType (XmlSchemaContentModel content)
563                 {
564                         if (this.IsMixed || ((XmlSchemaComplexContent) content).IsMixed)
565                                 return XmlSchemaContentType.Mixed;
566                         else
567                                 return XmlSchemaContentType.ElementOnly;
568                 }
569                 #endregion
570
571                 //
572                 // We have to validate:
573                 //
574                 //      - 3.4.3 Complex Type Definition Representation OK
575                 //      - 3.4.6 Type Definition Properties Correct
576                 //      - 3.4.6 Derivation Valid (Extension)
577                 //      - 3.4.6 Derivation Valid (Restriction, Complex)
578                 //
579                 // There are many schema errata:
580                 // http://www.w3.org/2001/05/xmlschema-errata#Errata1
581                 //
582                 // E1-43 Derivation Valid (Restriction, Complex) 5.
583                 // E1-21 Derivation Valid (Restriction, Complex) 4.3.
584                 // E1-17 Type Derivation OK (Complex) 2.1.
585                 //
586                 // And E1-38, E1-37, E1-30, E1-27
587                 //
588                 internal override int Validate (ValidationEventHandler h, XmlSchema schema)
589                 {
590                         if (IsValidated (schema.ValidationId))
591                                 return errorCount;
592                         // FIXME: omitting it causes StackOverflowException
593                         // among the compilation of element and types, but
594                         // it may result in insufficient results.
595                         ValidationId = schema.ValidationId;
596
597                         CollectSchemaComponent (h, schema);
598
599                         ValidateBaseXmlSchemaType (h, schema);
600                         
601                         ValidateParticle (h, schema);
602                         
603                         FillContentTypeParticle (h, schema);
604
605                         // 3.4.6: Properties Correct
606                         // Term. 1 => 3.4.1 already done by CollectSchemaComponent()
607                         //            except for {attribute uses} and {attribute wildcard}
608                         // Term. 2, 3 and 4 goes to ValidateContentModel().
609                         // Term. 5 follows in this method.
610                         //
611                         if (ContentModel != null)
612                                 ValidateContentModel (h, schema);
613                         else
614                                 ValidateImmediateAttributes (h, schema);
615
616                         // Additional support for 3.8.6 All Group Limited
617                         if (ContentTypeParticle != null) {
618                                 XmlSchemaAll termAll = contentTypeParticle.GetOptimizedParticle (true) as XmlSchemaAll;
619                                 if (termAll != null && (termAll.ValidatedMaxOccurs != 1 || contentTypeParticle.ValidatedMaxOccurs != 1)) // here contentTypeParticle is used to check occurence.
620                                         error (h, "Particle whose term is -all- and consists of complex type content particle must have maxOccurs = 1.");
621                         }
622
623 #if NET_2_0
624                         if (schema.Schemas.CompilationSettings != null &&
625                                 schema.Schemas.CompilationSettings.EnableUpaCheck)
626 #endif
627                         // This check is optional only after 2.0
628                         contentTypeParticle.ValidateUniqueParticleAttribution (new XmlSchemaObjectTable (),
629                                 new ArrayList (), h, schema);
630                         contentTypeParticle.ValidateUniqueTypeAttribution (
631                                 new XmlSchemaObjectTable (), h, schema);
632
633                         // 3.4.6 Properties Correct :: 5 (Two distinct ID attributes)
634                         XmlSchemaAttribute idAttr = null;
635                         foreach (DictionaryEntry entry in attributeUses) {
636                                 XmlSchemaAttribute attr = (XmlSchemaAttribute) entry.Value;
637                                 XmlSchemaDatatype dt = attr.AttributeType as XmlSchemaDatatype;
638                                 if (dt != null && dt.TokenizedType != XmlTokenizedType.ID)
639                                         continue;
640                                 if (dt == null)
641                                         dt = ((XmlSchemaSimpleType) attr.AttributeType).Datatype;
642                                 if (dt != null && dt.TokenizedType == XmlTokenizedType.ID) {
643                                         if (idAttr != null)
644                                                 error (h, "Two or more ID typed attribute declarations in a complex type are found.");
645                                         else
646                                                 idAttr = attr;
647                                 }
648                         }
649
650                         ValidationId = schema.ValidationId;
651                         return errorCount;
652                 }
653
654                 private void ValidateImmediateAttributes (ValidationEventHandler h, XmlSchema schema)
655                 {
656                         // {attribute uses}
657                         // also checks 3.4.6 Properties Correct :: 4 (Distinct attributes)
658                         attributeUses = new XmlSchemaObjectTable ();
659                         XmlSchemaUtil.ValidateAttributesResolved (attributeUses,
660                                 h, schema, attributes, anyAttribute, ref attributeWildcard, null, false);
661                 }
662                 
663                 private void ValidateBaseXmlSchemaType (ValidationEventHandler h, XmlSchema schema)
664                 {
665                         if (ContentModel != null && BaseXmlSchemaTypeInternal != null)
666                                 errorCount += BaseXmlSchemaTypeInternal.Validate (h, schema);
667                 }
668
669                 private void ValidateParticle (ValidationEventHandler h, XmlSchema schema)
670                 {       
671                         if (ContentModel == null && Particle != null) {
672                                 errorCount += particle.Validate (h, schema);
673                                 XmlSchemaGroupRef pgrp = Particle as XmlSchemaGroupRef;
674                                 if (pgrp != null) {
675                                         if (pgrp.TargetGroup != null)
676                                                 errorCount += pgrp.TargetGroup.Validate (h,schema);
677                                         // otherwise, it might be missing sub components.
678                                         else if (!schema.IsNamespaceAbsent (pgrp.RefName.Namespace))
679                                                 error (h, "Referenced group " + pgrp.RefName + " was not found in the corresponding schema.");
680                                 }
681                         }
682                 }
683
684                 private void ValidateContentModel (ValidationEventHandler h, XmlSchema schema)
685                 {
686                         errorCount += contentModel.Validate (h, schema);
687                         
688                         XmlSchemaType baseType = BaseXmlSchemaTypeInternal;
689
690                         // Here we check 3.4.6 Properties Correct :: 2. and 3.
691                         XmlSchemaComplexContentExtension cce = contentModel.Content as XmlSchemaComplexContentExtension;
692                         XmlSchemaComplexContentRestriction ccr = contentModel.Content as XmlSchemaComplexContentRestriction;
693                         XmlSchemaSimpleContentExtension sce = contentModel.Content as XmlSchemaSimpleContentExtension;
694                         XmlSchemaSimpleContentRestriction scr = contentModel.Content as XmlSchemaSimpleContentRestriction;
695
696                         XmlSchemaAnyAttribute localAnyAttribute = null;
697                         XmlSchemaAnyAttribute baseAnyAttribute = null;
698
699                         // 3.4.6 Properties Correct :: 3. Circular definition prohibited.
700                         if (ValidateRecursionCheck ())
701                                 error (h, "Circular definition of schema types was found.");
702                         if (baseType != null) {
703                                 // Fill "Datatype" property.
704                                 this.DatatypeInternal = baseType.Datatype;
705                         } else if (BaseSchemaTypeName == XmlSchemaComplexType.AnyTypeName)
706                                 DatatypeInternal = XmlSchemaSimpleType.AnySimpleType;
707                         else if (XmlSchemaUtil.IsBuiltInDatatypeName (BaseSchemaTypeName)) {
708                                 DatatypeInternal = XmlSchemaDatatype.FromName (BaseSchemaTypeName);
709                         }
710
711                         XmlSchemaComplexType baseComplexType = baseType as XmlSchemaComplexType;
712                         XmlSchemaSimpleType baseSimpleType = baseType as XmlSchemaSimpleType;
713
714                         // 3.4.6 Derivation Valid (common to Extension and Restriction, Complex) :: 1.
715                         if (baseType != null && (baseType.FinalResolved & resolvedDerivedBy) != 0)
716                                         error (h, "Specified derivation is specified as final by derived schema type.");
717
718                         // 3.4.6 Properties Correct :: 2.
719                         // Simple {base type definition} and restriction {derivation method} not allowed.
720                         if (baseSimpleType != null && resolvedDerivedBy == XmlSchemaDerivationMethod.Restriction)
721                                 error (h, "If the base schema type is a simple type, then this type must be extension.");
722
723                         // Common to complexContent
724                         if (cce != null || ccr != null) {
725                                 // 3.4.3 Complex Type Definition Representation OK :: 1.
726                                 // base
727                                 if (BaseSchemaTypeName == XmlSchemaComplexType.AnyTypeName)
728                                         baseComplexType = XmlSchemaComplexType.AnyType;
729                                 else if (XmlSchemaUtil.IsBuiltInDatatypeName (BaseSchemaTypeName))
730                                         error (h, "Referenced base schema type is XML Schema datatype.");
731                                 else if (baseComplexType == null && !schema.IsNamespaceAbsent (BaseSchemaTypeName.Namespace))
732                                         error (h, "Referenced base schema type " + BaseSchemaTypeName + " was not complex type or not found in the corresponding schema.");
733                         }
734                         // Common to simpleContent 
735                         else {
736                                 // ContentType of {content type}
737                                 resolvedContentType = XmlSchemaContentType.TextOnly;
738
739                                 // 3.4.3 Complex Type Definition Representation OK :: 1.
740                                 // base
741                                 if (BaseSchemaTypeName == XmlSchemaComplexType.AnyTypeName)
742                                         baseComplexType = XmlSchemaComplexType.AnyType;
743
744                                 if (baseComplexType != null && baseComplexType.ContentType != XmlSchemaContentType.TextOnly) {
745                                         error (h, "Base schema complex type of a simple content must be simple content type. Base type is " + BaseSchemaTypeName);
746                                 } else if (sce == null && (baseSimpleType != null && BaseSchemaTypeName.Namespace != XmlSchema.Namespace)) {
747                                         error (h, "If a simple content is not an extension, base schema type must be complex type. Base type is " + BaseSchemaTypeName);
748                                 } else if (XmlSchemaUtil.IsBuiltInDatatypeName (BaseSchemaTypeName)) {
749                                         // do nothing for particle.
750                                 }
751                                 // otherwise, it might be missing sub components.
752                                 else if (baseType == null && !schema.IsNamespaceAbsent (BaseSchemaTypeName.Namespace))
753                                         error (h, "Referenced base schema type " + BaseSchemaTypeName + " was not found in the corresponding schema.");
754
755                                 // 3.4.3 Complex Type Definition Representation OK :: 2.
756                                 // Note that baseSimpleType is also allowed as to Errata E1-27 (http://www.w3.org/2001/05/xmlschema-errata)
757                                 if (baseComplexType != null) {
758                                         if (baseComplexType.ContentType == XmlSchemaContentType.TextOnly) {
759                                                 // 2.1.1
760                                         // Here "baseComplexType.Particle != null" is required for error-ignorant case
761                                         } else if (scr != null && baseComplexType.ContentType == XmlSchemaContentType.Mixed && baseComplexType.Particle != null && baseComplexType.Particle.ValidateIsEmptiable () && scr.BaseType != null) {
762                                                 // 2.1.2 && 2.2: OK
763                                         }
764                                         else
765                                                 error (h, "Base complex type of a simple content restriction must be text only.");
766                                 } else {
767                                         if (sce != null && baseComplexType == null) {
768                                                 // 2.1.3 : OK
769                                         }
770                                         else
771                                                 error (h, "Not allowed base type of a simple content restriction.");
772                                 }
773                         }
774
775                         // complexType/complexContent/extension
776                         if (cce != null) {
777                                 // I don't think 3.4.6 Derivation Valid (Extension) :: 1.2
778                                 // is constraining anything here, since 3.4.2 {attribute uses}
779                                 // defines as to include base type's attribute uses.
780                                 localAnyAttribute = cce.AnyAttribute;
781                                 if (baseComplexType != null) {
782                                         foreach (DictionaryEntry entry in baseComplexType.AttributeUses) {
783                                                 XmlSchemaAttribute attr = (XmlSchemaAttribute) entry.Value;
784                                                 XmlSchemaUtil.AddToTable (attributeUses, attr, attr.QualifiedName, h);
785                                         }
786                                         baseAnyAttribute = baseComplexType.AttributeWildcard;
787                                 }
788                                 // attributes
789                                 errorCount += XmlSchemaUtil.ValidateAttributesResolved (
790                                         this.attributeUses, h, schema, cce.Attributes, 
791                                         cce.AnyAttribute , ref attributeWildcard, null, true);
792
793                                 // After adding them, test extension validity.
794                                 if (baseComplexType != null)
795                                         this.ValidateComplexBaseDerivationValidExtension (baseComplexType, h, schema);
796                                 else if (baseSimpleType != null)
797                                         this.ValidateSimpleBaseDerivationValidExtension (baseSimpleType, h, schema);
798                         }
799                         // complexType/complexContent/restriction
800                         if (ccr != null) {
801                                 // For ValidationEventHandler.
802                                 if (baseComplexType == null)
803                                         baseComplexType = XmlSchemaComplexType.AnyType;
804
805                                 // attributes
806                                 localAnyAttribute = ccr.AnyAttribute;
807                                 this.attributeWildcard = localAnyAttribute;
808                                 if (baseComplexType != null)
809                                         baseAnyAttribute = baseComplexType.AttributeWildcard;
810                                 if (baseAnyAttribute != null && localAnyAttribute != null)
811                                         // 1.3 attribute wildcard subset. (=> 3.10.6)
812                                         localAnyAttribute.ValidateWildcardSubset (baseAnyAttribute, h, schema);
813
814                                 // 3.4.2 Complex Type Definition with complex content Schema Component
815                                 // and its {attribute uses} and {attribute wildcard} are done here (descendantly)
816                                 errorCount += XmlSchemaUtil.ValidateAttributesResolved (
817                                         this.attributeUses, h, schema, ccr.Attributes, 
818                                         ccr.AnyAttribute, ref attributeWildcard, null, false);
819                                 foreach (DictionaryEntry entry in baseComplexType.AttributeUses) {
820                                         XmlSchemaAttribute attr = (XmlSchemaAttribute) entry.Value;
821                                         if (attributeUses [attr.QualifiedName] == null)
822                                                 XmlSchemaUtil.AddToTable (attributeUses, attr, attr.QualifiedName, h);
823                                 }
824
825                                 // Derivation Valid (Restriction, Complex) :: 5.
826                                 // Also see E1-15 of http://www.w3.org/2001/05/xmlschema-errata#Errata1
827                                 // 5.1 shouled be in scr (XmlSchemaSimpleContentRestriction)
828                                 this.ValidateDerivationValidRestriction (baseComplexType, h, schema);
829                         }
830                         // complexType/simpleContent/extension
831                         if (sce != null) {
832                                 errorCount += XmlSchemaUtil.ValidateAttributesResolved (
833                                         this.attributeUses, h, schema, sce.Attributes, 
834                                         sce.AnyAttribute, ref attributeWildcard, null, true);
835
836                                 // Attributes
837                                 // I don't think 3.4.6 Derivation Valid (Extension) :: 1.2
838                                 // is constraining anything here, since 3.4.2 {attribute uses}
839                                 // defines as to include base type's attribute uses.
840                                 localAnyAttribute = sce.AnyAttribute;
841
842                                 if (baseComplexType != null) {
843                                         baseAnyAttribute = baseComplexType.AttributeWildcard;
844
845                                         foreach (DictionaryEntry entry in baseComplexType.AttributeUses) {
846                                                 XmlSchemaAttribute attr = (XmlSchemaAttribute) entry.Value;
847 #if BUGGY_MS_COMPLIANT
848                                                 if (attr.Use != XmlSchemaUse.Prohibited)
849                                                         XmlSchemaUtil.AddToTable (attributeUses, attr, attr.QualifiedName, h);
850 #endif
851                                                 XmlSchemaUtil.AddToTable (attributeUses, attr, attr.QualifiedName, h);
852                                         }
853                                 }
854                                 if (baseAnyAttribute != null && localAnyAttribute != null)
855                                         // 1.3 attribute wildcard subset. (=> 3.10.6)
856                                         localAnyAttribute.ValidateWildcardSubset (baseAnyAttribute, h, schema);
857                         }
858                         // complexType/simpleContent/restriction
859                         if (scr != null) {
860                                 // Attributes
861                                 baseAnyAttribute = baseComplexType != null ? baseComplexType.AttributeWildcard : null;
862
863                                 localAnyAttribute = scr.AnyAttribute;
864                                 if (localAnyAttribute != null && baseAnyAttribute != null)
865                                         // 1.3 attribute wildcard subset. (=> 3.10.6)
866                                         localAnyAttribute.ValidateWildcardSubset (baseAnyAttribute, h, schema);
867                                 // 3.4.6 :: 5.1. Beware that There is an errata for 5.1!!
868                                 // http://www.w3.org/2001/05/xmlschema-errata#Errata1
869
870                                 // 3.4.2 Complex Type Definition with simple content Schema Component
871                                 // and its {attribute uses} and {attribute wildcard} are done here (descendantly)
872                                 errorCount += XmlSchemaUtil.ValidateAttributesResolved (
873                                         this.attributeUses, h, schema, scr.Attributes, 
874                                         scr.AnyAttribute, ref attributeWildcard, null, false);
875                         }
876
877                         // Common process of AttributeWildcard.
878                         if (localAnyAttribute != null) {
879                                 this.attributeWildcard = localAnyAttribute;
880                         }
881                         else
882                                 this.attributeWildcard = baseAnyAttribute;
883                 }
884
885                 // 3.4.6 Type Derivation OK (Complex)
886                 internal void ValidateTypeDerivationOK (object b, ValidationEventHandler h, XmlSchema schema)
887                 {
888                         // AnyType derives from AnyType itself.
889                         if (this == XmlSchemaComplexType.AnyType && BaseXmlSchemaType == this)
890                                 return;
891
892                         XmlSchemaType bst = b as XmlSchemaType;
893                         if (b == this)  // 1 and 2.1
894                                 return;
895                         if (bst != null && (resolvedDerivedBy & bst.FinalResolved) != 0) // 1.
896                                 error (h, "Derivation type " + resolvedDerivedBy + " is prohibited by the base type.");
897                         // FIXME: here BaseSchemaType should be 
898                         // BaseXmlSchemaType, however for some case it 
899                         // seems not working.
900                         if (BaseSchemaType == b) // 2.2
901                                 return;
902                         if (BaseSchemaType == null || BaseXmlSchemaType == XmlSchemaComplexType.AnyType) { // 2.3.1
903                                 error (h, "Derived type's base schema type is anyType.");
904                                 return;
905                         }
906                         // 2.3.2.1
907                         XmlSchemaComplexType dbct = BaseXmlSchemaType as XmlSchemaComplexType;
908                         if (dbct != null) {
909                                 dbct.ValidateTypeDerivationOK (b, h, schema);
910                                 return;
911                         }
912                         // 2.3.2.2
913                         XmlSchemaSimpleType dbst = BaseXmlSchemaType as XmlSchemaSimpleType;
914                         if (dbst != null) {
915                                 dbst.ValidateTypeDerivationOK (b, h, schema, true);
916                                 return;
917                         }
918                 }
919
920                 // 3.4.6 Derivation Valid (Extension) - Term. 1 (Complex Type)
921                 internal void ValidateComplexBaseDerivationValidExtension (XmlSchemaComplexType baseComplexType,
922                         ValidationEventHandler h, XmlSchema schema)
923                 {
924                         // 1.1
925                         if ((baseComplexType.FinalResolved & XmlSchemaDerivationMethod.Extension) != 0)
926                                 error (h, "Derivation by extension is prohibited.");
927                         // 1.2
928                         foreach (DictionaryEntry entry in baseComplexType.AttributeUses) {
929                                 XmlSchemaAttribute ba = (XmlSchemaAttribute) entry.Value;
930                                 XmlSchemaAttribute da = AttributeUses [ba.QualifiedName] as XmlSchemaAttribute;
931                                 if (da == null)
932                                         error (h, "Invalid complex type derivation by extension was found. Missing attribute was found: " + ba.QualifiedName + " .");
933                         }
934                         // 1.3 -> 3.10.6 Wildcard Subset.
935                         if (AnyAttribute != null) {
936                                 if (baseComplexType.AnyAttribute == null)
937                                         error (h, "Invalid complex type derivation by extension was found. Base complex type does not have an attribute wildcard.");
938                                 else
939                                         baseComplexType.AnyAttribute.ValidateWildcardSubset (AnyAttribute, h, schema);
940                         }
941
942                         // 1.4 => 1.4.2 (1.4.1 would be included in SimpleContentExtention).
943                         // 1.4.2.1
944 //                      if (contentTypeParticle == null)
945 //                              error (h, "Extended complex type's content type must not be empty.");
946                         // 1.4.2.2.1
947                         if (baseComplexType.ContentType != XmlSchemaContentType.Empty) {
948                                 // 1.4.2.2.2.1
949                                 if (this.ContentType != baseComplexType.ContentType)
950 //                              if (this.GetContentType (false) != baseComplexType.GetContentType (false))
951                                         error (h, "Base complex type has different content type " + baseComplexType.ContentType + ".");
952                                 // 1.4.2.2.2.2 => 3.9.6 Particle Valid (Extension)
953                                 else if (this.contentTypeParticle == null ||
954                                         !this.contentTypeParticle.ParticleEquals (baseComplexType.ContentTypeParticle)) {
955                                         XmlSchemaSequence seq = contentTypeParticle as XmlSchemaSequence;
956                                         if (contentTypeParticle != XmlSchemaParticle.Empty && (seq == null || contentTypeParticle.ValidatedMinOccurs != 1 || contentTypeParticle.ValidatedMaxOccurs != 1))
957                                                 error (h, "Invalid complex content extension was found.");
958                                         else {
959                                                 // Identical sequence item should be checked, but
960                                                 // I think it is naturally achieved as coded above.
961                                         }
962                                 }
963                         }
964                 }
965
966                 // 3.4.6 Derivation Valid (Extension) - Term. 2 (Simple Type)
967                 internal void ValidateSimpleBaseDerivationValidExtension (object baseType,
968                         ValidationEventHandler h, XmlSchema schema)
969                 {
970                         XmlSchemaSimpleType st = baseType as XmlSchemaSimpleType;
971                         if (st != null && (st.FinalResolved & XmlSchemaDerivationMethod.Extension) != 0)
972                                 error (h, "Extension is prohibited by the base type.");
973
974                         XmlSchemaDatatype dt = baseType as XmlSchemaDatatype;
975                         if (dt == null)
976                                 dt = st.Datatype;
977                         if (dt != this.Datatype)
978                                 error (h, "To extend simple type, a complex type must have the same content type as the base type.");
979                 }
980
981                 internal void ValidateDerivationValidRestriction (XmlSchemaComplexType baseType,
982                         ValidationEventHandler h, XmlSchema schema)
983                 {
984                         // 1.
985                         if (baseType == null) {
986                                 error (h, "Base schema type is not a complex type.");
987                                 return;
988                         }
989                         if ((baseType.FinalResolved & XmlSchemaDerivationMethod.Restriction) != 0) {
990                                 error (h, "Prohibited derivation by restriction by base schema type.");
991                                 return;
992                         }
993
994                         // 2.
995                         foreach (DictionaryEntry entry in this.AttributeUses) {
996                                 XmlSchemaAttribute attr = (XmlSchemaAttribute) entry.Value;
997                                 XmlSchemaAttribute baseAttr = baseType.AttributeUses [attr.QualifiedName] as XmlSchemaAttribute;
998                                 if (baseAttr != null) {
999                                         // 2.1
1000                                         // 2.1.1
1001                                         if (baseAttr.ValidatedUse != XmlSchemaUse.Optional && attr.ValidatedUse != XmlSchemaUse.Required)
1002                                                 error (h, "Invalid attribute derivation by restriction was found for " + attr.QualifiedName + " .");
1003                                         // 2.1.2
1004                                         XmlSchemaSimpleType attrSimpleType = attr.AttributeType as XmlSchemaSimpleType;
1005                                         XmlSchemaSimpleType baseAttrSimpleType = baseAttr.AttributeType as XmlSchemaSimpleType;
1006                                         bool typeError = false;
1007                                         if (attrSimpleType != null)
1008                                                 attrSimpleType.ValidateDerivationValid (baseAttrSimpleType, null, h, schema);
1009                                         else if (attrSimpleType == null && baseAttrSimpleType != null)
1010                                                 typeError = true;
1011                                         else {
1012                                                 Type t1 = attr.AttributeType.GetType ();
1013                                                 Type t2 = baseAttr.AttributeType.GetType ();
1014                                                 if (t1 != t2 && t1.IsSubclassOf (t2))
1015                                                         typeError = true;
1016                                         }
1017                                         if (typeError)
1018                                                 error (h, "Invalid attribute derivation by restriction because of its type: " + attr.QualifiedName + " .");
1019                                         // 2.1.3
1020                                         if (baseAttr.ValidatedFixedValue != null && attr.ValidatedFixedValue != baseAttr.ValidatedFixedValue)
1021                                                 error (h, "Invalid attribute derivation by restriction because of its fixed value constraint: " + attr.QualifiedName + " .");
1022                                 } else {
1023                                         // 2.2
1024                                         if (baseType.AttributeWildcard != null)
1025                                                 if (!baseType.AttributeWildcard.ValidateWildcardAllowsNamespaceName (
1026                                                         attr.QualifiedName.Namespace, schema) &&
1027                                                         !schema.IsNamespaceAbsent (attr.QualifiedName.Namespace))
1028                                                         error (h, "Invalid attribute derivation by restriction was found for " + attr.QualifiedName + " .");
1029                                 }
1030                         }
1031                         // I think 3. is considered in 2.
1032                         // 4.
1033                         if (this.AttributeWildcard != null && baseType != XmlSchemaComplexType.AnyType) {
1034                                 if (baseType.AttributeWildcard == null)
1035                                         error (h, "Invalid attribute derivation by restriction because of attribute wildcard.");
1036                                 else
1037                                         AttributeWildcard.ValidateWildcardSubset (baseType.AttributeWildcard, h, schema);
1038                         }
1039
1040                         // 5.
1041                         if (this == AnyType)
1042                                 return;
1043                         if (contentTypeParticle == XmlSchemaParticle.Empty) {
1044                                 // 5.1
1045                                 if (ContentType != XmlSchemaContentType.Empty) {
1046                                         // TODO: 5.1.1
1047 //                                      XmlSchemaSimpleType baseST = baseType as XmlSchemaSimpleType;
1048                                         // 5.1.2
1049                                         if (baseType.ContentType == XmlSchemaContentType.Mixed && !baseType.ContentTypeParticle.ValidateIsEmptiable ())
1050                                                 error (h, "Invalid content type derivation.");
1051
1052                                 } else {
1053                                         // 5.2
1054                                         if (baseType.ContentTypeParticle != XmlSchemaParticle.Empty &&
1055                                                 !baseType.ContentTypeParticle.ValidateIsEmptiable ())
1056                                                 error (h, "Invalid content type derivation.");
1057                                 }
1058                         } else {
1059                                 // 5.3 => 3.9.6 Particle Valid (Restriction)
1060                                 if (baseType.ContentTypeParticle != null) {
1061                                         // 3.9.6 - 1 : same particle.
1062                                         // 3.9.6 - 2 is covered by using ActualParticle.
1063                                         if (!contentTypeParticle.ParticleEquals (baseType.ContentTypeParticle))
1064                                                 contentTypeParticle.ValidateDerivationByRestriction (baseType.ContentTypeParticle, h, schema, true);
1065                                 }
1066                         }
1067                 }
1068
1069 #region Read
1070                 //<complexType
1071                 //  abstract = boolean : false
1072                 //  block = (#all | List of (extension | restriction)) 
1073                 //  final = (#all | List of (extension | restriction)) 
1074                 //  id = ID
1075                 //  mixed = boolean : false
1076                 //  name = NCName
1077                 //  {any attributes with non-schema namespace . . .}>
1078                 //  Content: (annotation?, (simpleContent | complexContent | ((group | all | choice | sequence)?, ((attribute | attributeGroup)*, anyAttribute?))))
1079                 //</complexType>
1080                 internal static XmlSchemaComplexType Read(XmlSchemaReader reader, ValidationEventHandler h)
1081                 {
1082                         XmlSchemaComplexType ctype = new XmlSchemaComplexType();
1083                         reader.MoveToElement();
1084                         Exception innerex;
1085
1086                         if(reader.NamespaceURI != XmlSchema.Namespace || reader.LocalName != xmlname)
1087                         {
1088                                 error(h,"Should not happen :1: XmlSchemaComplexType.Read, name="+reader.Name,null);
1089                                 reader.SkipToEnd();
1090                                 return null;
1091                         }
1092
1093                         ctype.LineNumber = reader.LineNumber;
1094                         ctype.LinePosition = reader.LinePosition;
1095                         ctype.SourceUri = reader.BaseURI;
1096
1097                         while(reader.MoveToNextAttribute())
1098                         {
1099                                 if(reader.Name == "abstract")
1100                                 {
1101                                         ctype.IsAbstract = XmlSchemaUtil.ReadBoolAttribute(reader,out innerex);
1102                                         if(innerex != null)
1103                                                 error(h,reader.Value + " is invalid value for abstract",innerex);
1104                                 }
1105                                 else if(reader.Name == "block")
1106                                 {
1107                                         ctype.block = XmlSchemaUtil.ReadDerivationAttribute(reader,out innerex, "block",
1108                                                 XmlSchemaUtil.ComplexTypeBlockAllowed);
1109                                         if(innerex != null)
1110                                                 error (h,"some invalid values for block attribute were found",innerex);
1111                                 }
1112                                 else if(reader.Name == "final")
1113                                 {
1114                                         ctype.Final = XmlSchemaUtil.ReadDerivationAttribute(reader,out innerex, "final",
1115                                                 XmlSchemaUtil.FinalAllowed);
1116                                         if(innerex != null)
1117                                                 error (h,"some invalid values for final attribute were found",innerex);
1118                                 }
1119                                 else if(reader.Name == "id")
1120                                 {
1121                                         ctype.Id = reader.Value;
1122                                 }
1123                                 else if(reader.Name == "mixed")
1124                                 {
1125                                         ctype.isMixed = XmlSchemaUtil.ReadBoolAttribute(reader,out innerex);
1126                                         if(innerex != null)
1127                                                 error(h,reader.Value + " is invalid value for mixed",innerex);
1128                                 }
1129                                 else if(reader.Name == "name")
1130                                 {
1131                                         ctype.Name = reader.Value;
1132                                 }
1133                                 else if((reader.NamespaceURI == "" && reader.Name != "xmlns") || reader.NamespaceURI == XmlSchema.Namespace)
1134                                 {
1135                                         error(h,reader.Name + " is not a valid attribute for complexType",null);
1136                                 }
1137                                 else
1138                                 {
1139                                         XmlSchemaUtil.ReadUnhandledAttribute(reader,ctype);
1140                                 }
1141                         }
1142                         
1143                         reader.MoveToElement();
1144                         if(reader.IsEmptyElement)
1145                                 return ctype;
1146
1147                         //Content: 1. annotation?, 
1148                         //                 2. simpleContent | 2. complexContent | 
1149                         //                      (3.(group | all | choice | sequence)?, (4.(attribute | attributeGroup)*, 5.anyAttribute?)))
1150                         int level = 1;
1151                         while(reader.ReadNextElement())
1152                         {
1153                                 if(reader.NodeType == XmlNodeType.EndElement)
1154                                 {
1155                                         if(reader.LocalName != xmlname)
1156                                                 error(h,"Should not happen :2: XmlSchemaComplexType.Read, name="+reader.Name,null);
1157                                         break;
1158                                 }
1159                                 if(level <= 1 && reader.LocalName == "annotation")
1160                                 {
1161                                         level = 2; //Only one annotation
1162                                         XmlSchemaAnnotation annotation = XmlSchemaAnnotation.Read(reader,h);
1163                                         if(annotation != null)
1164                                                 ctype.Annotation = annotation;
1165                                         continue;
1166                                 }
1167                                 if(level <=2)
1168                                 {
1169                                         if(reader.LocalName == "simpleContent")
1170                                         {
1171                                                 level = 6;
1172                                                 XmlSchemaSimpleContent simple = XmlSchemaSimpleContent.Read(reader,h);
1173                                                 if(simple != null)
1174                                                         ctype.ContentModel = simple;
1175                                                 continue;
1176                                         }
1177                                         if(reader.LocalName == "complexContent")
1178                                         {
1179                                                 level = 6;
1180                                                 XmlSchemaComplexContent complex = XmlSchemaComplexContent.Read(reader,h);
1181                                                 if(complex != null)
1182                                                         ctype.contentModel = complex;
1183                                                 continue;
1184                                         }
1185                                 }
1186                                 if(level <= 3)
1187                                 {
1188                                         if(reader.LocalName == "group")
1189                                         {
1190                                                 level = 4;
1191                                                 XmlSchemaGroupRef group = XmlSchemaGroupRef.Read(reader,h);
1192                                                 if(group != null)
1193                                                         ctype.particle = group;
1194                                                 continue;
1195                                         }
1196                                         if(reader.LocalName == "all")
1197                                         {
1198                                                 level = 4;
1199                                                 XmlSchemaAll all = XmlSchemaAll.Read(reader,h);
1200                                                 if(all != null)
1201                                                         ctype.particle = all;
1202                                                 continue;
1203                                         }
1204                                         if(reader.LocalName == "choice")
1205                                         {
1206                                                 level = 4;
1207                                                 XmlSchemaChoice choice = XmlSchemaChoice.Read(reader,h);
1208                                                 if(choice != null)
1209                                                         ctype.particle = choice;
1210                                                 continue;
1211                                         }
1212                                         if(reader.LocalName == "sequence")
1213                                         {
1214                                                 level = 4;
1215                                                 XmlSchemaSequence sequence = XmlSchemaSequence.Read(reader,h);
1216                                                 if(sequence != null)
1217                                                         ctype.particle = sequence;
1218                                                 continue;
1219                                         }
1220                                 }
1221                                 if(level <= 4)
1222                                 {
1223                                         if(reader.LocalName == "attribute")
1224                                         {
1225                                                 level = 4;
1226                                                 XmlSchemaAttribute attr = XmlSchemaAttribute.Read(reader,h);
1227                                                 if(attr != null)
1228                                                         ctype.Attributes.Add(attr);
1229                                                 continue;
1230                                         }
1231                                         if(reader.LocalName == "attributeGroup")
1232                                         {
1233                                                 level = 4;
1234                                                 XmlSchemaAttributeGroupRef attr = XmlSchemaAttributeGroupRef.Read(reader,h);
1235                                                 if(attr != null)
1236                                                         ctype.attributes.Add(attr);
1237                                                 continue;
1238                                         }
1239                                 }
1240                                 if(level <= 5 && reader.LocalName == "anyAttribute")
1241                                 {
1242                                         level = 6;
1243                                         XmlSchemaAnyAttribute anyattr = XmlSchemaAnyAttribute.Read(reader,h);
1244                                         if(anyattr != null)
1245                                                 ctype.AnyAttribute = anyattr;
1246                                         continue;
1247                                 }
1248                                 reader.RaiseInvalidElementError();
1249                         }
1250                         return ctype;
1251                 }
1252 #endregion
1253         }
1254 }