Merge pull request #211 from symform/master
[mono.git] / mcs / class / Commons.Xml.Relaxng / Commons.Xml.Relaxng.Derivative / RdpPatterns.cs
1 //
2 // Commons.Xml.Relaxng.Derivative.RdpPatterns.cs
3 //
4 // Author:
5 //      Atsushi Enomoto <ginga@kit.hi-ho.ne.jp>
6 //
7 // 2003 Atsushi Enomoto "No rights reserved."
8 //
9 // Copyright (c) 2004 Novell Inc.
10 // All rights reserved
11 //
12
13 //
14 // Permission is hereby granted, free of charge, to any person obtaining
15 // a copy of this software and associated documentation files (the
16 // "Software"), to deal in the Software without restriction, including
17 // without limitation the rights to use, copy, modify, merge, publish,
18 // distribute, sublicense, and/or sell copies of the Software, and to
19 // permit persons to whom the Software is furnished to do so, subject to
20 // the following conditions:
21 // 
22 // The above copyright notice and this permission notice shall be
23 // included in all copies or substantial portions of the Software.
24 // 
25 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
29 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
30 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
31 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 //
33
34 using System;
35 using System.Collections;
36 using System.Xml;
37 using Commons.Xml.Relaxng;
38
39 using LabelList = System.Collections.Hashtable;
40
41
42 namespace Commons.Xml.Relaxng.Derivative
43 {
44         public delegate RdpPattern RdpApplyAfterHandler (RdpPattern p);
45
46         // abstract Pattern. Note that in README the classes in this namespace
47         // is explicitly written as not for public use (and hidden in monodoc
48         // for now).
49         public abstract class RdpPattern
50         {
51                 public static readonly RdpPattern Anything;
52
53                 static RdpPattern ()
54                 {
55                         RdpPattern anyAtts = new RdpList (new RdpAttribute (RdpAnyName.Instance, RdpText.Instance));
56                         RdpElement anyElement = new RdpElement (RdpAnyName.Instance, null);
57                         Anything = new RdpChoice (RdpEmpty.Instance, new RdpChoice (anyAtts, new RdpChoice (RdpText.Instance, new RdpList (anyElement))));
58                         anyElement.Children = Anything;
59                 }
60
61                 internal bool nullableComputed;
62                 internal bool isNullable;
63                 Hashtable patternPool;
64
65                 internal string debug ()
66                 {
67                         return RdpUtil.DebugRdpPattern (this, new Hashtable ());
68                 }
69
70                 public abstract RelaxngPatternType PatternType { get; }
71
72                 public abstract RdpContentType ContentType { get; }
73
74                 private Hashtable setupTable (Type type, RdpPattern p)
75                 {
76                         if (patternPool == null) // could be null for RdpElement etc.
77                                 patternPool = new Hashtable ();
78
79                         Hashtable typePool = (Hashtable) patternPool [type];
80                         if (typePool == null) {
81                                 typePool = new Hashtable ();
82                                 patternPool [type] = typePool;
83                         }
84                         Hashtable pTable = (Hashtable) typePool [p];
85                         if (pTable == null) {
86                                 pTable = new Hashtable ();
87                                 typePool [p] = pTable;
88                         }
89                         return pTable;
90                 }
91
92                 internal RdpFlip MakeFlip (RdpBinaryFunction func, RdpPattern p)
93                 {
94                         if (patternPool == null) // could be null for RdpElement etc.
95                                 patternPool = new Hashtable ();
96
97                         // Though this method takes function argument, all
98                         // p1 callers have different pattern types, so we don't
99                         // have to distinguish tables by func.
100
101                         Hashtable table = patternPool [func] as Hashtable;
102                         if (table == null) {
103                                 table = new Hashtable ();
104                                 patternPool [func] = table;
105                         }
106                         RdpFlip f = table [p] as RdpFlip;
107                         if (f != null)
108                                 return f;
109                         f = new RdpFlip (func, p);
110                         table [p] = f;
111                         return f;
112                 }
113
114                 public RdpChoice MakeChoiceLeaf (RdpPattern p)
115                 {
116                         if (patternPool == null) // could be null for RdpElement etc.
117                                 patternPool = new Hashtable ();
118                         Hashtable leaves = (Hashtable) patternPool [typeof (RdpEmpty)];
119                         if (leaves == null) {
120                                 leaves = new Hashtable ();
121                                 patternPool [typeof (RdpEmpty)] = leaves;
122                         }
123                         RdpChoice leaf = leaves [p] as RdpChoice;
124                         if (leaf == null) {
125                                 leaf = new RdpChoice (RdpEmpty.Instance, p);
126                                 leaf.setInternTable (patternPool);
127                                 leaves [p] = leaf;
128                         }
129                         return leaf;
130                 }
131
132                 public RdpPattern MakeChoice (RdpPattern p1, RdpPattern p2)
133                 {
134                         if (p1.PatternType == RelaxngPatternType.NotAllowed)
135                                 return p2;
136                         if (p2.PatternType == RelaxngPatternType.NotAllowed)
137                                 return p1;
138                         if (p1 == p2)
139                                 return p1;
140                         // choice-leaves support
141                         if (p1.PatternType == RelaxngPatternType.Empty)
142                                 return MakeChoiceLeaf (p2);
143                         if (p2.PatternType == RelaxngPatternType.Empty)
144                                 return MakeChoiceLeaf (p1);
145
146                         if (p1.GetHashCode () > p2.GetHashCode ()) {
147                                 RdpPattern tmp = p1;
148                                 p1 = p2;
149                                 p2 = tmp;
150                         }
151
152                         Hashtable p1Table = setupTable (typeof (RdpChoice), p1);
153                         if (p1Table [p2] == null) {
154                                 RdpChoice c = new RdpChoice (p1, p2);
155                                 c.setInternTable (this.patternPool);
156                                 p1Table [p2] = c;
157                         }
158                         return (RdpChoice) p1Table [p2];
159                 }
160
161                 public RdpPattern MakeGroup (RdpPattern p1, RdpPattern p2)
162                 {
163                         if (p1.PatternType == RelaxngPatternType.Empty)
164                                 return p2;
165
166                         Hashtable p1Table = setupTable (typeof (RdpGroup), p1);
167                         if (p1Table [p2] == null) {
168                                 RdpGroup g = new RdpGroup (p1, p2);
169                                 g.setInternTable (this.patternPool);
170                                 p1Table [p2] = g;
171                         }
172                         return (RdpGroup) p1Table [p2];
173                 }
174
175                 public RdpInterleave MakeInterleave (RdpPattern p1, RdpPattern p2)
176                 {
177                         if (p1.GetHashCode () > p2.GetHashCode ()) {
178                                 RdpPattern tmp = p1;
179                                 p1 = p2;
180                                 p2 = tmp;
181                         }
182
183                         Hashtable p1Table = setupTable (typeof (RdpInterleave), p1);
184                         if (p1Table [p2] == null) {
185                                 RdpInterleave i = new RdpInterleave (p1, p2);
186                                 i.setInternTable (this.patternPool);
187                                 p1Table [p2] = i;
188                         }
189                         return (RdpInterleave) p1Table [p2];
190                 }
191
192                 public RdpAfter MakeAfter (RdpPattern p1, RdpPattern p2)
193                 {
194                         Hashtable p1Table = setupTable (typeof (RdpAfter), p1);
195                         if (p1Table [p2] == null) {
196                                 RdpAfter a = new RdpAfter (p1, p2);
197                                 a.setInternTable (this.patternPool);
198                                 p1Table [p2] = a;
199                         }
200                         return (RdpAfter) p1Table [p2];
201                 }
202
203                 public RdpOneOrMore MakeOneOrMore (RdpPattern p)
204                 {
205                         if (patternPool == null) // could be null for RdpElement etc.
206                                 patternPool = new Hashtable ();
207
208                         Hashtable pTable = (Hashtable) patternPool [typeof (RdpOneOrMore)];
209                         if (pTable == null) {
210                                 pTable = new Hashtable ();
211                                 patternPool [typeof (RdpOneOrMore)] = pTable;
212                         }
213                         if (pTable [p] == null) {
214                                 RdpOneOrMore oom = new RdpOneOrMore (p);
215                                 oom.setInternTable (patternPool);
216                                 pTable [p] = oom;
217                         }
218                         return (RdpOneOrMore) pTable [p];
219                 }
220
221                 internal void setInternTable (Hashtable ht)
222                 {
223                         if (this.patternPool != null)
224                                 return;
225                         this.patternPool = ht;
226
227                         Hashtable pt = ht [GetType ()] as Hashtable;
228                         if (pt == null) {
229                                 pt = new Hashtable ();
230                                 ht [GetType ()] = pt;
231                         }
232
233                         RdpAbstractSingleContent single =
234                                 this as RdpAbstractSingleContent;
235                         if (single != null) {
236                                 if (pt [single.Child] == null) {
237                                         pt [single.Child] = this;
238                                         single.Child.setInternTable (ht);
239                                 }
240                                 return;
241                         }
242
243                         RdpAbstractBinary binary =
244                                 this as RdpAbstractBinary;
245                         if (binary != null) {
246                                 Hashtable lTable = setupTable (GetType (), binary.LValue);
247                                 if (lTable [binary.RValue] == null) {
248                                         lTable [binary.RValue] = this;
249                                         binary.LValue.setInternTable (ht);
250                                         binary.RValue.setInternTable (ht);
251                                 }
252                                 return;
253                         }
254
255                         // For rest patterns, only check recursively, without pooling.
256                         RdpAttribute attr = this as RdpAttribute;
257                         if (attr != null) {
258                                 attr.Children.setInternTable (ht);
259                                 return;
260                         }
261                         RdpElement el = this as RdpElement;
262                         if (el != null) {
263                                 el.Children.setInternTable (ht);
264                                 return;
265                         }
266                         RdpDataExcept dex= this as RdpDataExcept;
267                         if (dex != null) {
268                                 dex.Except.setInternTable (ht);
269                                 return;
270                         }
271
272                         switch (PatternType) {
273                         case RelaxngPatternType.Empty:
274                         case RelaxngPatternType.NotAllowed:
275                         case RelaxngPatternType.Text:
276                         case RelaxngPatternType.Data:
277                         case RelaxngPatternType.Value:
278                                 return;
279                         }
280
281 #if REPLACE_IN_ADVANCE
282                         throw new InvalidOperationException ();
283 #endif
284                 }
285
286                 internal abstract void MarkReachableDefs ();
287
288                 internal abstract void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept);
289
290                 // This method is to detect text pattern inside interleave child.
291                 internal abstract bool ContainsText ();
292
293                 internal virtual RdpPattern ExpandRef (Hashtable defs)
294                 {
295                         return this;
296                 }
297
298                 internal virtual RdpPattern ReduceEmptyAndNotAllowed (ref bool result, Hashtable visited)
299                 {
300                         return this;
301                 }
302
303                 public abstract bool Nullable { get; }
304
305                 internal virtual bool IsTextValueDependent {
306                         get { return false; }
307                 }
308
309                 internal virtual bool IsContextDependent {
310                         get { return false; }
311                 }
312
313                 // fills QName collection
314                 public void GetLabels (LabelList elements, LabelList attributes)
315                 {
316                         GetLabels (elements, attributes, false);
317                 }
318
319                 public abstract void GetLabels (LabelList elements, LabelList attributes, bool collectNameClass);
320
321                 internal void AddNameLabel (LabelList names, RdpNameClass nc)
322                 {
323                         RdpName name = nc as RdpName;
324                         if (name != null) {
325                                 XmlQualifiedName qname = new XmlQualifiedName (
326                                         name.LocalName, name.NamespaceURI);
327                                 names [qname] = qname;
328                                 return;
329                         }
330                         RdpNameClassChoice choice = nc as RdpNameClassChoice;
331                         if (choice != null) {
332                                 AddNameLabel (names, choice.LValue);
333                                 AddNameLabel (names, choice.RValue);
334                                 return;
335                         }
336                         // For NsName and AnyName, do nothing.
337                 }
338
339                 #region Derivative
340                 public virtual RdpPattern TextDeriv (string s, XmlReader reader)
341                 {
342                         return RdpNotAllowed.Instance;
343                 }
344
345                 internal virtual RdpPattern TextDeriv (string s, XmlReader reader, MemoizationStore memo)
346                 {
347                         return TextDeriv (s, reader);
348                 }
349
350                 internal virtual RdpPattern EmptyTextDeriv (MemoizationStore memo)
351                 {
352                         return TextDeriv (String.Empty, null, memo);
353                 }
354
355                 internal virtual RdpPattern TextOnlyDeriv ()
356                 {
357                         return this;
358                 }
359
360                 internal virtual RdpPattern TextOnlyDeriv (MemoizationStore store)
361                 {
362                         return this;
363                 }
364
365                 internal virtual RdpPattern MixedTextDeriv ()
366                 {
367                         return RdpNotAllowed.Instance;
368                 }
369
370                 internal virtual RdpPattern MixedTextDeriv (MemoizationStore memo)
371                 {
372                         return RdpNotAllowed.Instance;
373                 }
374
375                 public RdpPattern ListDeriv (string [] list, int index, XmlReader reader)
376                 {
377                         return listDerivInternal (list, 0, reader);
378                 }
379
380                 private RdpPattern listDerivInternal (string [] list, int start, XmlReader reader)
381                 {
382                         if (list.Length <= start)
383                                 return this;
384                         else if (list [start].Length == 0)
385                                 return listDerivInternal (list, start + 1, reader);
386                         else
387                                 return this.TextDeriv (list [start].Trim (RdpUtil.WhitespaceChars), reader).listDerivInternal (list, start + 1, reader);
388                 }
389
390                 // Choice(this, p)
391                 public virtual RdpPattern Choice (RdpPattern p)
392                 {
393                         if (p is RdpNotAllowed)
394                                 return this;
395                         else if (this is RdpNotAllowed)
396                                 return p;
397                         else
398                                 return MakeChoice (this, p);
399                 }
400
401                 // Group(this, p)
402                 public virtual RdpPattern Group (RdpPattern p)
403                 {
404                         if (p is RdpNotAllowed || this is RdpNotAllowed)
405                                 return RdpNotAllowed.Instance;
406                         else if (p is RdpEmpty)
407                                 return this;
408                         else if (this is RdpEmpty)
409                                 return p;
410                         else
411                                 return MakeGroup (this, p);
412                 }
413
414                 // Interleave(this, p)
415                 public virtual RdpPattern Interleave (RdpPattern p)
416                 {
417                         if (p is RdpNotAllowed || this is RdpNotAllowed)
418                                 return RdpNotAllowed.Instance;
419                         else if (p is RdpEmpty)
420                                 return this;
421                         else if (this is RdpEmpty)
422                                 return p;
423                         else
424                                 return MakeInterleave (this, p);
425                 }
426
427                 // After(this, p)
428                 public virtual RdpPattern After (RdpPattern p)
429                 {
430                         if (this is RdpNotAllowed || p is RdpNotAllowed)
431                                 return RdpNotAllowed.Instance;
432                         else
433                                 return MakeAfter (this, p);
434                 }
435
436
437                 // applyAfter((f, p1=this), p2)
438                 public virtual RdpPattern ApplyAfter (RdpApplyAfterHandler h)
439                 {
440                         throw new Exception ("INTERNAL ERROR: should not happen. This is " + this);
441                 }
442
443                 // startTagOpenDeriv (this, qname)
444                 // startTagOpenDeriv _ qn = NotAllowed (default)
445                 public virtual RdpPattern StartTagOpenDeriv (string name, string ns)
446                 {
447                         return RdpNotAllowed.Instance;
448                 }
449
450                 internal virtual RdpPattern StartTagOpenDeriv (string name, string ns, MemoizationStore memo)
451                 {
452                         return StartTagOpenDeriv (name, ns);
453                 }
454
455                 // attDeriv(ctx, this, att)
456                 // attDeriv _ _ _ = NotAllowed
457                 public virtual RdpPattern AttDeriv (string name, string ns, string value, XmlReader reader)
458                 {
459                         return RdpNotAllowed.Instance;
460                 }
461
462                 public virtual RdpPattern StartAttDeriv (string name, string ns)
463                 {
464                         return RdpNotAllowed.Instance;
465                 }
466
467                 internal virtual RdpPattern StartAttDeriv (string name, string ns, MemoizationStore memo)
468                 {
469                         return StartAttDeriv (name, ns);
470                 }
471
472                 public virtual RdpPattern EndAttDeriv ()
473                 {
474                         return RdpNotAllowed.Instance;
475                 }
476
477                 internal virtual RdpPattern EndAttDeriv (MemoizationStore memo)
478                 {
479                         return EndAttDeriv ();
480                 }
481
482                 public bool ValueMatch (string s, XmlReader reader)
483                 {
484                         return Nullable && Util.IsWhitespace (s) ||
485                                 TextDeriv (s, reader).Nullable;
486                 }
487
488                 public virtual RdpPattern StartTagCloseDeriv ()
489                 {
490                         return this;
491                 }
492
493                 internal virtual RdpPattern StartTagCloseDeriv (MemoizationStore memo)
494                 {
495                         return StartTagCloseDeriv ();
496                 }
497
498                 public RdpPattern OneOrMore ()
499                 {
500                         if (PatternType == RelaxngPatternType.NotAllowed)
501                                 return RdpNotAllowed.Instance;
502                         else
503                                 return MakeOneOrMore (this);
504                 }
505
506                 public virtual RdpPattern EndTagDeriv ()
507                 {
508                         return RdpNotAllowed.Instance;
509                 }
510
511                 internal virtual RdpPattern EndTagDeriv (MemoizationStore memo)
512                 {
513                         return EndTagDeriv ();
514                 }
515                 #endregion
516         }
517
518         // Empty
519         public class RdpEmpty : RdpPattern
520         {
521                 public RdpEmpty () {}
522                 static RdpEmpty ()
523                 {
524                         instance = new RdpEmpty ();
525                 }
526
527                 public override bool Nullable {
528                         get { return true; }
529                 }
530
531                 internal override bool IsTextValueDependent {
532                         get { return false; }
533                 }
534
535                 internal override bool IsContextDependent {
536                         get { return false; }
537                 }
538
539                 static RdpEmpty instance;
540                 public static RdpEmpty Instance {
541                         get { return instance; }
542                 }
543
544                 public override RelaxngPatternType PatternType {
545                         get { return RelaxngPatternType.Empty; }
546                 }
547
548                 public override RdpContentType ContentType {
549                         get { return RdpContentType.Empty; }
550                 }
551
552                 public override void GetLabels (LabelList elements, LabelList attributes, bool collectNameClass)
553                 {
554                         // do nothing
555                 }
556
557                 internal override void MarkReachableDefs () 
558                 {
559                         // do nothing
560                 }
561
562                 internal override void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept)
563                 {
564                         if (dataExcept)
565                                 throw new RelaxngException ("empty cannot appear under except of a data pattern.");
566                 }
567
568                 internal override bool ContainsText()
569                 {
570                         return false;
571                 }
572         }
573
574         // NotAllowed
575         public class RdpNotAllowed : RdpPattern
576         {
577                 public RdpNotAllowed () {}
578                 static RdpNotAllowed ()
579                 {
580                         instance = new RdpNotAllowed ();
581                 }
582
583                 static RdpNotAllowed instance;
584                 public static RdpNotAllowed Instance {
585                         get { return instance; }
586                 }
587
588                 public override bool Nullable {
589                         get { return false; }
590                 }
591
592                 internal override bool IsTextValueDependent {
593                         get { return false; }
594                 }
595
596                 internal override bool IsContextDependent {
597                         get { return false; }
598                 }
599
600                 public override RdpPattern ApplyAfter (RdpApplyAfterHandler h)
601                 {
602                         return RdpNotAllowed.Instance;
603                 }
604
605                 public override RelaxngPatternType PatternType {
606                         get { return RelaxngPatternType.NotAllowed; }
607                 }
608
609                 public override RdpContentType ContentType {
610                         get { return RdpContentType.Empty; }
611                 }
612
613                 internal override void MarkReachableDefs () 
614                 {
615                         // do nothing
616                 }
617
618                 internal override void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept)
619                 {
620                         // do nothing
621                 }
622
623                 internal override bool ContainsText()
624                 {
625                         return false;
626                 }
627
628                 public override void GetLabels (LabelList elements, LabelList attributes, bool collectNameClass)
629                 {
630                         // FIXME: Supposed to clear something here?
631                 }
632         }
633
634         // Text
635         public class RdpText : RdpPattern
636         {
637                 static RdpText instance;
638                 public static RdpText Instance {
639                         get { return instance; }
640                 }
641
642                 public RdpText () {}
643                 static RdpText ()
644                 {
645                         instance = new RdpText ();
646                 }
647
648                 public override bool Nullable {
649                         get { return true; }
650                 }
651
652                 internal override bool IsTextValueDependent {
653                         get { return false; }
654                 }
655
656                 internal override bool IsContextDependent {
657                         get { return false; }
658                 }
659
660                 public override RelaxngPatternType PatternType {
661                         get { return RelaxngPatternType.Text; }
662                 }
663
664                 public override RdpContentType ContentType {
665                         get { return RdpContentType.Complex; }
666                 }
667
668                 public override RdpPattern TextDeriv (string s, XmlReader reader)
669                 {
670                         return this;
671                 }
672
673                 internal override RdpPattern EmptyTextDeriv (MemoizationStore memo)
674                 {
675                         return this;
676                 }
677
678                 internal override RdpPattern MixedTextDeriv ()
679                 {
680                         return this;
681                 }
682
683                 internal override RdpPattern MixedTextDeriv (MemoizationStore memo)
684                 {
685                         return this;
686                 }
687
688                 internal override void MarkReachableDefs () 
689                 {
690                         // do nothing
691                 }
692
693                 internal override void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept)
694                 {
695                         if (list)
696                                 throw new RelaxngException ("text is not allowed under a list.");
697                         if (dataExcept)
698                                 throw new RelaxngException ("text is not allowed under except of a list.");
699                 }
700
701                 internal override bool ContainsText()
702                 {
703                         return true;
704                 }
705
706                 public override void GetLabels (LabelList elements, LabelList attributes, bool collectNameClass)
707                 {
708                         // do nothing
709                 }
710         }
711
712         // AbstractBinary
713         public abstract class RdpAbstractBinary : RdpPattern
714         {
715                 public RdpAbstractBinary (RdpPattern l, RdpPattern r)
716                 {
717                         this.l = l;
718                         this.r = r;
719                 }
720
721                 RdpPattern l;
722                 public RdpPattern LValue {
723                         get { return l; }
724                         set { l = value; }
725                 }
726
727                 RdpPattern r;
728                 public RdpPattern RValue {
729                         get { return r; }
730                         set { r = value; }
731                 }
732
733                 RdpContentType computedContentType = RdpContentType.Invalid;
734                 public override RdpContentType ContentType {
735                         get {
736                                 if (computedContentType == RdpContentType.Invalid) {
737                                         if (l.ContentType == RdpContentType.Empty)
738                                                 computedContentType = r.ContentType;
739                                         else if (r.ContentType == RdpContentType.Empty)
740                                                 computedContentType = l.ContentType;
741                                         else if ((l.ContentType & RdpContentType.Simple) != 0 || ((r.ContentType & RdpContentType.Simple) != 0))
742                                                 throw new RelaxngException ("The content type of this group is invalid.");
743                                         else
744                                                 computedContentType = RdpContentType.Complex;
745                                 }
746                                 return computedContentType;
747                         }
748                 }
749
750                 bool expanded;
751                 internal override RdpPattern ExpandRef (Hashtable defs)
752                 {
753                         if (!expanded) {
754                                 l = l.ExpandRef (defs);
755                                 r = r.ExpandRef (defs);
756                         }
757                         return this;
758                 }
759
760                 internal override RdpPattern ReduceEmptyAndNotAllowed (ref bool result, Hashtable visited)
761                 {
762                         if (visited.Contains (this))
763                                 return this;
764                         visited.Add (this, this);
765
766                         if (LValue.PatternType == RelaxngPatternType.NotAllowed ||
767                                 RValue.PatternType == RelaxngPatternType.NotAllowed) {
768                                 result = true;
769                                 return RdpNotAllowed.Instance;
770                         } else if (LValue.PatternType == RelaxngPatternType.Empty) {
771                                 result = true;
772                                 return RValue.ReduceEmptyAndNotAllowed (ref result, visited);
773                         } else if (RValue.PatternType == RelaxngPatternType.Empty) {
774                                 result = true;
775                                 return LValue.ReduceEmptyAndNotAllowed (ref result, visited);
776                         } else {
777                                 LValue = LValue.ReduceEmptyAndNotAllowed (ref result, visited);
778                                 RValue = RValue.ReduceEmptyAndNotAllowed (ref result, visited);
779                                 return this;
780                         }
781                 }
782
783                 internal override void MarkReachableDefs () 
784                 {
785                         l.MarkReachableDefs ();
786                         r.MarkReachableDefs ();
787                 }
788
789                 internal override bool ContainsText()
790                 {
791                         return l.ContainsText () || r.ContainsText ();
792                 }
793
794                 // 7.3 (group/interleave attribute names) and
795                 // part of 7.4 (interleave element names)
796                 // FIXME: Actually it should be done against the correct
797                 // simplified grammar, expanding all refs.
798                 internal void CheckNameOverlap (bool checkElements)
799                 {
800                         if (RdpUtil.NamesOverlap (LValue, RValue, checkElements))
801                                 throw new RelaxngException ("Duplicate attributes inside a group or an interleave is not allowed.");
802                         return;
803                 }
804         }
805
806         // Choice
807         public class RdpChoice : RdpAbstractBinary
808         {
809                 public RdpChoice (RdpPattern l, RdpPattern r) : base (l, r)
810                 {
811                 }
812
813                 public override bool Nullable {
814                         get {
815                                 if (!nullableComputed) {
816                                         isNullable =
817                                                 LValue.Nullable || RValue.Nullable;
818                                         nullableComputed = true;
819                                 }
820                                 return isNullable;
821                         }
822                 }
823
824                 bool isTextValueDependentComputed;
825                 bool isTextValueDependent;
826
827                 internal override bool IsTextValueDependent {
828                         get {
829                                 if (!isTextValueDependentComputed) {
830                                         isTextValueDependent = LValue.IsTextValueDependent || RValue.IsTextValueDependent;
831                                         isTextValueDependentComputed = true;
832                                 }
833                                 return isTextValueDependent;
834                         }
835                 }
836
837                 bool isContextDependentComputed;
838                 bool isContextDependent;
839
840                 internal override bool IsContextDependent {
841                         get {
842                                 if (!isContextDependentComputed) {
843                                         isContextDependent = LValue.IsContextDependent || RValue.IsContextDependent;
844                                         isContextDependentComputed = true;
845                                 }
846                                 return isContextDependent;
847                         }
848                 }
849
850                 public override RelaxngPatternType PatternType {
851                         get { return RelaxngPatternType.Choice; }
852                 }
853
854                 RdpContentType computedContentType = RdpContentType.Invalid;
855                 public override RdpContentType ContentType {
856                         get {
857                                 if (computedContentType == RdpContentType.Invalid) {
858                                         if (LValue.ContentType == RdpContentType.Simple ||
859                                                 RValue.ContentType == RdpContentType.Simple)
860                                                 computedContentType = RdpContentType.Simple;
861                                         else
862                                                 computedContentType = base.ContentType;
863                                 }
864                                 return computedContentType;
865                         }
866                 }
867
868                 public override void GetLabels (LabelList elements, LabelList attributes, bool collectNameClass)
869                 {
870                         LValue.GetLabels (elements, attributes, collectNameClass);
871                         RValue.GetLabels (elements, attributes, collectNameClass);
872                 }
873
874
875                 internal override RdpPattern ReduceEmptyAndNotAllowed (ref bool result, Hashtable visited)
876                 {
877                         if (visited.Contains (this))
878                                 return this;
879                         visited.Add (this, this);
880
881                         if (LValue.PatternType == RelaxngPatternType.NotAllowed &&
882                                 RValue.PatternType == RelaxngPatternType.NotAllowed) {
883                                 result = true;
884                                 return RdpNotAllowed.Instance;
885                         } else if (LValue.PatternType == RelaxngPatternType.NotAllowed) {
886                                 result = true;
887                                 return RValue.ReduceEmptyAndNotAllowed (ref result, visited);
888                         } else if (RValue.PatternType == RelaxngPatternType.NotAllowed) {
889                                 result = true;
890                                 return LValue.ReduceEmptyAndNotAllowed (ref result, visited);
891                         } else if (LValue.PatternType == RelaxngPatternType.Empty &&
892                                 RValue.PatternType == RelaxngPatternType.Empty) {
893                                 result = true;
894                                 return RdpEmpty.Instance;
895                         } else if (RValue.PatternType == RelaxngPatternType.Empty) {
896                                 result = true;
897                                 RValue = LValue.ReduceEmptyAndNotAllowed (ref result, visited);
898                                 LValue = RdpEmpty.Instance;
899                                 return this;
900                         } else {
901                                 LValue = LValue.ReduceEmptyAndNotAllowed (ref result, visited);
902                                 RValue = RValue.ReduceEmptyAndNotAllowed (ref result, visited);
903                                 return this;
904                         }
905                 }
906
907                 public override RdpPattern TextDeriv (string s, XmlReader reader)
908                 {
909                         return LValue.TextDeriv (s, reader).Choice (RValue.TextDeriv (s, reader));
910                 }
911
912                 internal override RdpPattern TextDeriv (string s, XmlReader reader, MemoizationStore memo)
913                 {
914                         return memo.TextDeriv (LValue, s, reader).Choice (memo.TextDeriv (RValue, s, reader));
915                 }
916
917                 internal override RdpPattern EmptyTextDeriv (MemoizationStore memo)
918                 {
919                         return memo.EmptyTextDeriv (LValue)
920                                 .Choice (memo.EmptyTextDeriv (RValue));
921                 }
922
923                 internal override RdpPattern TextOnlyDeriv ()
924                 {
925                         return LValue.TextOnlyDeriv ().Choice (
926                                 RValue.TextOnlyDeriv ());
927                 }
928
929                 internal override RdpPattern TextOnlyDeriv (MemoizationStore memo)
930                 {
931                         return memo.TextOnlyDeriv (LValue).Choice (
932                                 memo.TextOnlyDeriv (RValue));
933                 }
934
935                 internal override RdpPattern MixedTextDeriv ()
936                 {
937                         return LValue.MixedTextDeriv ().Choice (
938                                 RValue.MixedTextDeriv ());
939                 }
940
941                 internal override RdpPattern MixedTextDeriv (MemoizationStore memo)
942                 {
943                         return memo.MixedTextDeriv (LValue).Choice (
944                                 memo.MixedTextDeriv (RValue));
945                 }
946
947                 public override RdpPattern ApplyAfter (RdpApplyAfterHandler handler)
948                 {
949 //                      return handler (LValue).Choice (handler (RValue));
950                         return LValue.ApplyAfter (handler).Choice (RValue.ApplyAfter (handler));
951                 }
952
953                 public override RdpPattern StartTagOpenDeriv (string name, string ns)
954                 {
955 #if UseStatic
956                         return RdpUtil.Choice (
957                                 RdpUtil.StartTagOpenDeriv (LValue, qname),
958                                 RdpUtil.StartTagOpenDeriv (RValue, qname));
959 #else
960                         RdpPattern lDeriv = LValue.StartTagOpenDeriv (name, ns);
961                         return lDeriv.Choice (RValue.StartTagOpenDeriv (name, ns));
962 #endif
963                 }
964
965                 internal override RdpPattern StartTagOpenDeriv (string name, string ns, MemoizationStore memo)
966                 {
967                         RdpPattern lDeriv = memo.StartTagOpenDeriv (LValue, name, ns);
968                         return lDeriv.Choice (memo.StartTagOpenDeriv (RValue, name, ns));
969                 }
970
971                 // attDeriv cx (Choice p1 p2) att =
972                 //  choice (attDeriv cx p1 att) (attDeriv cx p2 att)
973                 public override RdpPattern AttDeriv (string name, string ns, string value, XmlReader reader)
974                 {
975                         return LValue.AttDeriv (name, ns, value, reader)
976                                 .Choice (RValue.AttDeriv (name, ns, value, reader));
977                 }
978
979                 public override RdpPattern StartAttDeriv (string name, string ns)
980                 {
981                         RdpPattern lDeriv = LValue.StartAttDeriv (name, ns);
982                         return lDeriv.Choice (RValue.StartAttDeriv (name, ns));
983                 }
984
985                 internal override RdpPattern StartAttDeriv (string name, string ns, MemoizationStore memo)
986                 {
987                         return memo.StartAttDeriv (LValue, name, ns)
988                                 .Choice (memo.StartAttDeriv (RValue, name, ns));
989                 }
990
991                 public override RdpPattern EndAttDeriv ()
992                 {
993                         return LValue.EndAttDeriv ().Choice (RValue.EndAttDeriv ());
994                 }
995
996                 internal override RdpPattern EndAttDeriv (MemoizationStore memo)
997                 {
998                         return memo.EndAttDeriv (LValue).Choice (memo.EndAttDeriv (RValue));
999                 }
1000
1001                 // startTagCloseDeriv (Choice p1 p2) =
1002                 //  choice (startTagCloseDeriv p1) (startTagCloseDeriv p2)
1003                 public override RdpPattern StartTagCloseDeriv ()
1004                 {
1005                         return LValue.StartTagCloseDeriv ()
1006                                 .Choice (RValue.StartTagCloseDeriv ());
1007                 }
1008
1009                 internal override RdpPattern StartTagCloseDeriv (MemoizationStore memo)
1010                 {
1011                         return memo.StartTagCloseDeriv (LValue)
1012                                 .Choice (memo.StartTagCloseDeriv (RValue));
1013                 }
1014
1015                 public override RdpPattern EndTagDeriv ()
1016                 {
1017                         return LValue.EndTagDeriv ().Choice (RValue.EndTagDeriv ());
1018                 }
1019
1020                 internal override RdpPattern EndTagDeriv (MemoizationStore memo)
1021                 {
1022                         return memo.EndTagDeriv (LValue).Choice (memo.EndTagDeriv (RValue));
1023                 }
1024
1025                 internal override void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept)
1026                 {
1027                         LValue.CheckConstraints (attribute, oneOrMore, oneOrMoreGroup, oneOrMoreInterleave, list, dataExcept);
1028                         RValue.CheckConstraints (attribute, oneOrMore, oneOrMoreGroup, oneOrMoreInterleave, list, dataExcept);
1029                 }
1030         }
1031
1032         // Interleave
1033         public class RdpInterleave : RdpAbstractBinary
1034         {
1035                 public RdpInterleave (RdpPattern l, RdpPattern r) : base (l, r)
1036                 {
1037                 }
1038
1039                 public override bool Nullable {
1040                         get {
1041                                 if (!nullableComputed) {
1042                                         isNullable =
1043                                                 LValue.Nullable && RValue.Nullable;
1044                                         nullableComputed = true;
1045                                 }
1046                                 return isNullable;
1047                         }
1048                 }
1049
1050                 internal override bool IsTextValueDependent {
1051                         get { return LValue.IsTextValueDependent || RValue.IsTextValueDependent; }
1052                 }
1053
1054                 internal override bool IsContextDependent {
1055                         get { return LValue.IsContextDependent || RValue.IsContextDependent; }
1056                 }
1057
1058                 public override void GetLabels (LabelList elements, LabelList attributes, bool collectNameClass)
1059                 {
1060                         LValue.GetLabels (elements, attributes, collectNameClass);
1061                         RValue.GetLabels (elements, attributes, collectNameClass);
1062                 }
1063
1064                 internal override RdpPattern ReduceEmptyAndNotAllowed (ref bool result, Hashtable visited)
1065                 {
1066                         if (visited.Contains (this))
1067                                 return this;
1068                         visited.Add (this, this);
1069
1070                         if (LValue.PatternType == RelaxngPatternType.NotAllowed ||
1071                                 RValue.PatternType == RelaxngPatternType.NotAllowed) {
1072                                 result = true;
1073                                 return RdpNotAllowed.Instance;
1074                         } else {
1075                                 LValue = LValue.ReduceEmptyAndNotAllowed (ref result, visited);
1076                                 RValue = RValue.ReduceEmptyAndNotAllowed (ref result, visited);
1077                                 return this;
1078                         }
1079                 }
1080
1081                 public override RdpPattern TextDeriv (string s, XmlReader reader)
1082                 {
1083                         return LValue.TextDeriv (s, reader).Interleave (RValue)
1084                                 .Choice (LValue.Interleave (RValue.TextDeriv (s, reader)));
1085                 }
1086
1087                 internal override RdpPattern TextDeriv (string s, XmlReader reader, MemoizationStore memo)
1088                 {
1089                         return memo.TextDeriv (LValue, s, reader).Interleave (RValue)
1090                                 .Choice (LValue.Interleave (memo.TextDeriv (RValue, s, reader)));
1091                 }
1092
1093                 internal override RdpPattern EmptyTextDeriv (MemoizationStore memo)
1094                 {
1095                         return memo.EmptyTextDeriv (LValue).Interleave (RValue)
1096                                 .Choice (LValue.Interleave (memo.EmptyTextDeriv (RValue)));
1097                 }
1098
1099                 internal override RdpPattern TextOnlyDeriv ()
1100                 {
1101                         return LValue.TextOnlyDeriv ().Interleave (
1102                                 RValue.TextOnlyDeriv ());
1103                 }
1104
1105                 internal override RdpPattern TextOnlyDeriv (MemoizationStore memo)
1106                 {
1107                         return memo.TextOnlyDeriv (LValue).Interleave (
1108                                 memo.TextOnlyDeriv (RValue));
1109                 }
1110
1111                 internal override RdpPattern MixedTextDeriv ()
1112                 {
1113                         return LValue.MixedTextDeriv ().Interleave (RValue).Choice (
1114                                 LValue.Interleave (RValue.MixedTextDeriv ()));
1115                 }
1116
1117                 internal override RdpPattern MixedTextDeriv (MemoizationStore memo)
1118                 {
1119                         return memo.MixedTextDeriv (LValue).Interleave (RValue).Choice (
1120                                 LValue.Interleave (memo.MixedTextDeriv (RValue)));
1121                 }
1122
1123                 // => choice (applyAfter (flip interleave p2) (startTagOpenDeriv p1 qn)) (applyAfter (interleave p1) (startTagOpenDeriv p2 qn)
1124                 // => p1.startTagOpenDeriv(qn).applyAfter (flip interleave p2).choice (p2.startTagOpenDeriv(qn).applyAfter (interleave p1) )
1125                 public override RdpPattern StartTagOpenDeriv (string name, string ns)
1126                 {
1127                         RdpPattern handledL = LValue.StartTagOpenDeriv (name, ns);
1128                         RdpPattern handledR = RValue.StartTagOpenDeriv (name, ns);
1129                         RdpFlip flipL = MakeFlip (RdpUtil.InterleaveFunction, RValue);
1130                         RdpPattern choiceL = handledL.ApplyAfter (new RdpApplyAfterHandler (flipL.Apply));
1131                         RdpPattern choiceR = handledR.ApplyAfter (new RdpApplyAfterHandler (LValue.Interleave));
1132                         return choiceL.Choice (choiceR);
1133                 }
1134
1135                 internal override RdpPattern StartTagOpenDeriv (string name, string ns, MemoizationStore memo)
1136                 {
1137                         RdpPattern handledL = memo.StartTagOpenDeriv (LValue, name, ns);
1138                         RdpPattern handledR = memo.StartTagOpenDeriv (RValue, name, ns);
1139                         RdpFlip flipL = MakeFlip (RdpUtil.InterleaveFunction, RValue);
1140                         RdpPattern choiceL = handledL.ApplyAfter (new RdpApplyAfterHandler (flipL.Apply));
1141                         RdpPattern choiceR = handledR.ApplyAfter (new RdpApplyAfterHandler (LValue.Interleave));
1142                         return choiceL.Choice (choiceR);
1143                 }
1144
1145                 // attDeriv cx (Interleave p1 p2) att =
1146                 //  choice (interleave (attDeriv cx p1 att) p2)
1147                 //         (interleave p1 (attDeriv cx p2 att))
1148                 public override RdpPattern AttDeriv (string name, string ns, string value, XmlReader reader)
1149                 {
1150                         return LValue.AttDeriv (name, ns, value, reader)
1151                                 .Interleave (RValue)
1152                                 .Choice (LValue.Interleave (
1153                                         RValue.AttDeriv (name, ns, value, reader)));
1154                 }
1155
1156                 public override RdpPattern StartAttDeriv (string name, string ns)
1157                 {
1158                         RdpPattern handledL = LValue.StartAttDeriv (name, ns);
1159                         RdpPattern handledR = RValue.StartAttDeriv (name, ns);
1160                         RdpFlip flipL = MakeFlip (RdpUtil.InterleaveFunction, RValue);
1161                         RdpPattern choiceL = handledL.ApplyAfter (new RdpApplyAfterHandler (flipL.Apply));
1162                         RdpPattern choiceR = handledR.ApplyAfter (new RdpApplyAfterHandler (LValue.Interleave));
1163                         return choiceL.Choice (choiceR);
1164                 }
1165
1166                 internal override RdpPattern StartAttDeriv (string name, string ns, MemoizationStore memo)
1167                 {
1168                         RdpPattern handledL = memo.StartAttDeriv (LValue, name, ns);
1169                         RdpPattern handledR = memo.StartAttDeriv (RValue, name, ns);
1170                         RdpFlip flipL = MakeFlip (RdpUtil.InterleaveFunction, RValue);
1171                         RdpPattern choiceL = handledL.ApplyAfter (new RdpApplyAfterHandler (flipL.Apply));
1172                         RdpPattern choiceR = handledR.ApplyAfter (new RdpApplyAfterHandler (LValue.Interleave));
1173                         return choiceL.Choice (choiceR);
1174                 }
1175
1176                 // startTagCloseDeriv (Interleave p1 p2) =
1177                 //  interleave (startTagCloseDeriv p1) (startTagCloseDeriv p2)
1178                 public override RdpPattern StartTagCloseDeriv ()
1179                 {
1180                         return LValue.StartTagCloseDeriv ()
1181                                 .Interleave (RValue.StartTagCloseDeriv ());
1182                 }
1183
1184                 internal override RdpPattern StartTagCloseDeriv (MemoizationStore memo)
1185                 {
1186                         return memo.StartTagCloseDeriv (LValue)
1187                                 .Interleave (memo.StartTagCloseDeriv (RValue));
1188                 }
1189
1190                 public override RelaxngPatternType PatternType {
1191                         get { return RelaxngPatternType.Interleave; }
1192                 }
1193
1194                 internal override void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept)
1195                 {
1196                         if (list)
1197                                 throw new RelaxngException ("interleave is not allowed under a list.");
1198                         if (dataExcept)
1199                                 throw new RelaxngException ("interleave is not allowed under except of a data.");
1200
1201                         // 7.1
1202                         LValue.CheckConstraints (attribute, oneOrMore, oneOrMoreGroup, oneOrMore, list, dataExcept);
1203                         RValue.CheckConstraints (attribute, oneOrMore, oneOrMoreGroup, oneOrMore, list, dataExcept);
1204
1205                         // unique name analysis - 7.3 and part of 7.4
1206                         CheckNameOverlap (true);
1207
1208                         // (2) text/text prohibited
1209                         if (LValue.ContainsText () && RValue.ContainsText ())
1210                                 throw new RelaxngException ("Both branches of the interleave contains a text pattern.");
1211                 }
1212         }
1213
1214         // Group
1215         public class RdpGroup : RdpAbstractBinary
1216         {
1217                 public RdpGroup (RdpPattern l, RdpPattern r) : base (l, r)
1218                 {
1219                 }
1220
1221                 public override bool Nullable {
1222                         get {
1223                                 if (!nullableComputed) {
1224                                         isNullable =
1225                                                 LValue.Nullable && RValue.Nullable;
1226                                         nullableComputed = true;
1227                                 }
1228                                 return isNullable;
1229                         }
1230                 }
1231
1232                 internal override bool IsTextValueDependent {
1233                         get { return LValue.IsTextValueDependent || (LValue.Nullable ? RValue.IsTextValueDependent : false); }
1234                 }
1235
1236                 internal override bool IsContextDependent {
1237                         get { return LValue.IsContextDependent || (LValue.Nullable ? RValue.IsContextDependent : false); }
1238                 }
1239
1240                 public override void GetLabels (LabelList elements, LabelList attributes, bool collectNameClass)
1241                 {
1242                         LValue.GetLabels (elements, attributes, collectNameClass);
1243                         if (LValue.Nullable)
1244                                 RValue.GetLabels (elements, attributes, collectNameClass);
1245                         else
1246                                 RValue.GetLabels (null, attributes, collectNameClass);
1247                 }
1248
1249                 public override RdpPattern TextDeriv (string s, XmlReader reader)
1250                 {
1251                         RdpPattern p = LValue.TextDeriv (s, reader);
1252                         p = (p.PatternType == RelaxngPatternType.NotAllowed) ?
1253                                 p : p.Group (RValue);
1254                         return LValue.Nullable ?
1255                                 p.Choice (RValue.TextDeriv (s, reader)) : p;
1256                 }
1257
1258                 internal override RdpPattern TextDeriv (string s, XmlReader reader, MemoizationStore memo)
1259                 {
1260                         RdpPattern p = memo.TextDeriv (LValue, s, reader);
1261                         p = (p.PatternType == RelaxngPatternType.NotAllowed) ?
1262                                 p : p.Group (RValue);
1263                         return LValue.Nullable ?
1264                                 p.Choice (memo.TextDeriv (RValue, s, reader)) : p;
1265                 }
1266
1267                 internal override RdpPattern EmptyTextDeriv (MemoizationStore memo)
1268                 {
1269                         RdpPattern p = memo.EmptyTextDeriv (LValue);
1270                         p = p.PatternType == RelaxngPatternType.NotAllowed ?
1271                                 p : p.Group (RValue);
1272                         return LValue.Nullable ?
1273                                 p.Choice (memo.EmptyTextDeriv (RValue)) : p;
1274                 }
1275
1276                 internal override RdpPattern TextOnlyDeriv ()
1277                 {
1278                         RdpPattern p = LValue.TextOnlyDeriv ();
1279                         return p.PatternType == RelaxngPatternType.NotAllowed ?
1280                                 p : p.Group (RValue.TextOnlyDeriv ());
1281                 }
1282
1283                 internal override RdpPattern TextOnlyDeriv (MemoizationStore memo)
1284                 {
1285                         RdpPattern p = memo.TextOnlyDeriv (LValue);
1286                         return p.PatternType == RelaxngPatternType.NotAllowed ?
1287                                 p : p.Group (memo.TextOnlyDeriv (RValue));
1288                 }
1289
1290                 internal override RdpPattern MixedTextDeriv ()
1291                 {
1292                         RdpPattern p = LValue.MixedTextDeriv ().Group (RValue);
1293                         return LValue.Nullable ?
1294                                 p.Choice (RValue.MixedTextDeriv ()) : p;
1295                 }
1296
1297                 internal override RdpPattern MixedTextDeriv (MemoizationStore memo)
1298                 {
1299                         RdpPattern p = memo.MixedTextDeriv (LValue).Group (RValue);
1300                         return LValue.Nullable ?
1301                                 p.Choice (memo.MixedTextDeriv (RValue)) : p;
1302                 }
1303
1304                 // startTagOpenDeriv (Group p1 p2) qn =
1305                 //  let x = applyAfter (flip group p2) (startTagOpenDeriv p1 qn)
1306                 //  in if nullable p1 then
1307                 //       choice x (startTagOpenDeriv p2 qn)
1308                 //     else
1309                 //       x
1310                 public override RdpPattern StartTagOpenDeriv (string name, string ns)
1311                 {
1312                         RdpPattern handled = LValue.StartTagOpenDeriv (name, ns);
1313                         RdpFlip f = MakeFlip (RdpUtil.GroupFunction, RValue);
1314                         RdpPattern x = handled.ApplyAfter (new RdpApplyAfterHandler (f.Apply));
1315                         if (LValue.Nullable)
1316                                 return x.Choice (RValue.StartTagOpenDeriv (name, ns));
1317                         else
1318                                 return x;
1319                 }
1320
1321                 internal override RdpPattern StartTagOpenDeriv (string name, string ns, MemoizationStore memo)
1322                 {
1323                         RdpPattern handled = memo.StartTagOpenDeriv (LValue, name, ns);
1324                         RdpFlip f = MakeFlip (RdpUtil.GroupFunction, RValue);
1325                         RdpPattern x = handled.ApplyAfter (new RdpApplyAfterHandler (f.Apply));
1326                         if (LValue.Nullable)
1327                                 return x.Choice (memo.StartTagOpenDeriv (RValue, name, ns));
1328                         else
1329                                 return x;
1330                 }
1331
1332                 // attDeriv cx (Group p1 p2) att =
1333                 //  choice (group (attDeriv cx p1 att) p2)
1334                 //         (group p1 (attDeriv cx p2 att))
1335                 public override RdpPattern AttDeriv (string name, string ns, string value, XmlReader reader)
1336                 {
1337                         return LValue.AttDeriv (name, ns, value, reader).Group (RValue)
1338                                 .Choice (LValue.Group (
1339                                         RValue.AttDeriv (name, ns, value, reader)));
1340                 }
1341
1342                 // startAttDeriv (group p1 p2) == startAttDeriv (interleave p1 p2)
1343                 public override RdpPattern StartAttDeriv (string name, string ns)
1344                 {
1345                         RdpPattern handledL = LValue.StartAttDeriv (name, ns);
1346                         RdpPattern handledR = RValue.StartAttDeriv (name, ns);
1347                         RdpFlip flipL = MakeFlip (RdpUtil.GroupFunction, RValue);
1348                         RdpPattern choiceL = handledL.ApplyAfter (new RdpApplyAfterHandler (flipL.Apply));
1349                         RdpPattern choiceR = handledR.ApplyAfter (new RdpApplyAfterHandler (LValue.Group));
1350                         return choiceL.Choice (choiceR);
1351                 }
1352
1353                 internal override RdpPattern StartAttDeriv (string name, string ns, MemoizationStore memo)
1354                 {
1355                         RdpPattern handledL = memo.StartAttDeriv (LValue, name, ns);
1356                         RdpPattern handledR = memo.StartAttDeriv (RValue, name, ns);
1357                         RdpFlip flipL = MakeFlip (RdpUtil.GroupFunction, RValue);
1358                         RdpPattern choiceL = handledL.ApplyAfter (new RdpApplyAfterHandler (flipL.Apply));
1359                         RdpPattern choiceR = handledR.ApplyAfter (new RdpApplyAfterHandler (LValue.Group));
1360                         return choiceL.Choice (choiceR);
1361                 }
1362
1363                 // startTagCloseDeriv (Group p1 p2) =
1364                 //  group (startTagCloseDeriv p1) (startTagCloseDeriv p2)
1365                 public override RdpPattern StartTagCloseDeriv ()
1366                 {
1367                         RdpPattern p = LValue.StartTagCloseDeriv ();
1368                         return p.PatternType == RelaxngPatternType.NotAllowed ?
1369                                 p : p.Group (RValue.StartTagCloseDeriv ());
1370                 }
1371
1372                 internal override RdpPattern StartTagCloseDeriv (MemoizationStore memo)
1373                 {
1374                         RdpPattern p = memo.StartTagCloseDeriv (LValue);
1375                         return p.PatternType == RelaxngPatternType.NotAllowed ?
1376                                 p : p.Group (memo.StartTagCloseDeriv (RValue));
1377                 }
1378
1379                 public override RelaxngPatternType PatternType {
1380                         get { return RelaxngPatternType.Group; }
1381                 }
1382
1383                 internal override void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept)
1384                 {
1385                         if (dataExcept)
1386                                 throw new RelaxngException ("interleave is not allowed under except of a data.");
1387
1388                         LValue.CheckConstraints (attribute, oneOrMore, oneOrMore, oneOrMoreInterleave, list, dataExcept);
1389                         RValue.CheckConstraints (attribute, oneOrMore, oneOrMore, oneOrMoreInterleave, list, dataExcept);
1390
1391                         // 7.3
1392                         CheckNameOverlap (false);
1393                 }
1394         }
1395
1396         public abstract class RdpAbstractSingleContent : RdpPattern
1397         {
1398                 RdpPattern child;
1399                 bool isExpanded;
1400
1401                 internal override RdpPattern ExpandRef (Hashtable defs)
1402                 {
1403                         if (!isExpanded)
1404                                 child = child.ExpandRef (defs);
1405                         return this;
1406                 }
1407
1408                 public RdpAbstractSingleContent (RdpPattern p)
1409                 {
1410                         this.child = p;
1411                 }
1412
1413                 public RdpPattern Child {
1414                         get { return child; }
1415                         set { child = value; }
1416                 }
1417
1418                 internal override void MarkReachableDefs () 
1419                 {
1420                         child.MarkReachableDefs ();
1421                 }
1422
1423                 internal override bool ContainsText()
1424                 {
1425                         return child.ContainsText ();
1426                 }
1427         }
1428
1429         // OneOrMore
1430         public class RdpOneOrMore : RdpAbstractSingleContent
1431         {
1432                 public RdpOneOrMore (RdpPattern p) : base (p)
1433                 {
1434                 }
1435
1436                 public override RelaxngPatternType PatternType {
1437                         get { return RelaxngPatternType.OneOrMore; }
1438                 }
1439
1440                 public override RdpContentType ContentType {
1441                         get {
1442                                 if (Child.ContentType == RdpContentType.Simple)
1443                                         throw new RelaxngException ("Invalid content type was found.");
1444                                 return Child.ContentType;
1445                         }
1446                 }
1447
1448                 public override bool Nullable {
1449                         get { return Child.Nullable; }
1450                 }
1451
1452                 internal override bool IsTextValueDependent {
1453                         get { return Child.IsTextValueDependent; }
1454                 }
1455
1456                 internal override bool IsContextDependent {
1457                         get { return Child.IsContextDependent; }
1458                 }
1459
1460                 public override void GetLabels (LabelList elements, LabelList attributes, bool collectNameClass)
1461                 {
1462                         Child.GetLabels (elements, attributes, collectNameClass);
1463                 }
1464
1465                 internal override RdpPattern ReduceEmptyAndNotAllowed (ref bool result, Hashtable visited)
1466                 {
1467                         if (visited.Contains (this))
1468                                 return this;
1469                         visited.Add (this, this);
1470
1471                         if (Child.PatternType == RelaxngPatternType.NotAllowed) {
1472                                 result = true;
1473                                 return RdpNotAllowed.Instance;
1474                         } else if (Child.PatternType == RelaxngPatternType.Empty)
1475                                 return RdpEmpty.Instance;
1476                         else {
1477                                 Child = Child.ReduceEmptyAndNotAllowed (ref result, visited);
1478                                 return this;
1479                         }
1480                 }
1481
1482                 public override RdpPattern TextDeriv (string s, XmlReader reader)
1483                 {
1484                         RdpPattern p = Child.TextDeriv (s, reader);
1485                         return p.PatternType == RelaxngPatternType.NotAllowed ?
1486                                 p : p.Group (this.Choice (RdpEmpty.Instance));
1487                 }
1488
1489                 internal override RdpPattern TextDeriv (string s, XmlReader reader, MemoizationStore memo)
1490                 {
1491                         RdpPattern p = memo.TextDeriv (Child, s, reader);
1492                         return p.PatternType == RelaxngPatternType.NotAllowed ?
1493                                 p : p.Group (this.Choice (RdpEmpty.Instance));
1494                 }
1495
1496                 internal override RdpPattern EmptyTextDeriv (MemoizationStore memo)
1497                 {
1498                         RdpPattern p = memo.EmptyTextDeriv (Child);
1499                         return p.PatternType == RelaxngPatternType.NotAllowed ?
1500                                 p : p.Group (this.Choice (RdpEmpty.Instance));
1501                 }
1502
1503                 internal override RdpPattern TextOnlyDeriv ()
1504                 {
1505                         return Child.TextOnlyDeriv ().OneOrMore ();
1506                 }
1507
1508                 internal override RdpPattern TextOnlyDeriv (MemoizationStore memo)
1509                 {
1510                         return memo.TextOnlyDeriv (Child).OneOrMore ();
1511                 }
1512
1513                 internal override RdpPattern MixedTextDeriv ()
1514                 {
1515                         RdpPattern p = Child.MixedTextDeriv ();
1516                         return p.PatternType == RelaxngPatternType.NotAllowed ?
1517                                 p : p.Group (this.Choice (RdpEmpty.Instance));
1518                 }
1519
1520                 internal override RdpPattern MixedTextDeriv (MemoizationStore memo)
1521                 {
1522                         RdpPattern p = memo.MixedTextDeriv (Child);
1523                         return p.PatternType == RelaxngPatternType.NotAllowed ?
1524                                 p : p.Group (this.Choice (RdpEmpty.Instance));
1525                 }
1526
1527                 // attDeriv cx (OneOrMore p) att =
1528                 //  group (attDeriv cx p att) (choice (OneOrMore p) Empty)
1529                 public override RdpPattern AttDeriv (string name, string ns, string value, XmlReader reader)
1530                 {
1531                         RdpPattern p = Child.AttDeriv (name, ns, value, reader);
1532                         return p.PatternType == RelaxngPatternType.NotAllowed ?
1533                                 p : p.Group (Choice (RdpEmpty.Instance));
1534                 }
1535
1536                 // startTagOpenDeriv (OneOrMore p) qn =
1537                 //  applyAfter (flip group (choice (OneOrMore p) Empty))
1538                 //             (startTagOpenDeriv p qn)
1539                 public override RdpPattern StartTagOpenDeriv (string name, string ns)
1540                 {
1541                         RdpPattern rest = RdpEmpty.Instance.Choice (Child.OneOrMore ());
1542                         RdpPattern handled = Child.StartTagOpenDeriv (name, ns);
1543                         RdpFlip f = MakeFlip (RdpUtil.GroupFunction, rest);
1544                         return handled.ApplyAfter (new RdpApplyAfterHandler (f.Apply));
1545                 }
1546
1547                 internal override RdpPattern StartTagOpenDeriv (string name, string ns, MemoizationStore memo)
1548                 {
1549                         RdpPattern rest = RdpEmpty.Instance.Choice (Child.OneOrMore ());
1550                         RdpPattern handled = memo.StartTagOpenDeriv (Child, name, ns);
1551                         RdpFlip f = MakeFlip (RdpUtil.GroupFunction, rest);
1552                         return handled.ApplyAfter (new RdpApplyAfterHandler (f.Apply));
1553                 }
1554
1555                 public override RdpPattern StartAttDeriv (string name, string ns)
1556                 {
1557                         RdpPattern rest = RdpEmpty.Instance.Choice (Child.OneOrMore ());
1558                         RdpPattern handled = Child.StartAttDeriv (name, ns);
1559                         RdpFlip f = MakeFlip (RdpUtil.GroupFunction, rest);
1560                         return handled.ApplyAfter (new RdpApplyAfterHandler (f.Apply));
1561                 }
1562
1563                 internal override RdpPattern StartAttDeriv (string name, string ns, MemoizationStore memo)
1564                 {
1565                         RdpPattern rest = RdpEmpty.Instance.Choice (Child.OneOrMore ());
1566                         RdpPattern handled = memo.StartAttDeriv (Child, name, ns);
1567                         RdpFlip f = MakeFlip (RdpUtil.GroupFunction, rest);
1568                         return handled.ApplyAfter (new RdpApplyAfterHandler (f.Apply));
1569                 }
1570
1571                 // startTagCloseDeriv (OneOrMore p) =
1572                 //  oneOrMore (startTagCloseDeriv p)
1573                 public override RdpPattern StartTagCloseDeriv ()
1574                 {
1575 #if UseStatic
1576                         return RdpUtil.OneOrMore (
1577                                 RdpUtil.StartTagCloseDeriv (children));
1578 #else
1579                         return Child.StartTagCloseDeriv ().OneOrMore ();
1580 #endif
1581                 }
1582
1583                 internal override RdpPattern StartTagCloseDeriv (MemoizationStore memo)
1584                 {
1585                         return memo.StartTagCloseDeriv (Child).OneOrMore ();
1586                 }
1587
1588                 internal override void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept)
1589                 {
1590                         if (dataExcept)
1591                                 throw new RelaxngException ("oneOrMore is not allowed under except of a data.");
1592                         this.Child.CheckConstraints (attribute, true, oneOrMoreGroup, oneOrMoreInterleave, list, dataExcept);
1593                 }
1594         }
1595
1596         // List
1597         public class RdpList : RdpAbstractSingleContent
1598         {
1599                 public RdpList (RdpPattern p) : base (p)
1600                 {
1601                 }
1602
1603                 internal override RdpPattern ReduceEmptyAndNotAllowed (ref bool result, Hashtable visited)
1604                 {
1605                         if (visited.Contains (this))
1606                                 return this;
1607                         visited.Add (this, this);
1608
1609                         if (Child.PatternType == RelaxngPatternType.NotAllowed) {
1610                                 result = true;
1611                                 return RdpNotAllowed.Instance;
1612                         } else {
1613                                 Child = Child.ReduceEmptyAndNotAllowed (ref result, visited);
1614                                 return this;
1615                         }
1616                 }
1617
1618                 public override bool Nullable {
1619                         get { return false; }
1620                 }
1621
1622                 internal override bool IsTextValueDependent {
1623                         get { return true; }
1624                 }
1625
1626                 internal override bool IsContextDependent {
1627                         get { return Child.IsContextDependent; }
1628                 }
1629
1630                 public override RelaxngPatternType PatternType {
1631                         get { return RelaxngPatternType.List; }
1632                 }
1633
1634                 public override RdpContentType ContentType {
1635                         get { return RdpContentType.Simple; }
1636                 }
1637
1638                 public override void GetLabels (LabelList elements, LabelList attributes, bool collectNameClass)
1639                 {
1640                         Child.GetLabels (elements, attributes, collectNameClass);
1641                 }
1642
1643                 public override RdpPattern TextDeriv (string s, XmlReader reader)
1644                 {
1645                         s = Util.NormalizeWhitespace (s);
1646
1647                         RdpPattern p = Child.ListDeriv (s.Split (RdpUtil.WhitespaceChars), 0, reader);                  
1648                         if (p.Nullable)
1649                                 return RdpEmpty.Instance;
1650                         else
1651                                 return RdpNotAllowed.Instance;
1652                 }
1653
1654                 internal override void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept)
1655                 {
1656                         if (list)
1657                                 throw new RelaxngException ("list is not allowed uner another list.");
1658                         if (dataExcept)
1659                                 throw new RelaxngException ("list is not allowed under except of a data.");
1660                         this.Child.CheckConstraints (attribute, oneOrMore, oneOrMoreGroup, oneOrMoreInterleave, true, dataExcept);
1661                 }
1662         }
1663
1664         // Data
1665         public class RdpData : RdpPattern
1666         {
1667                 public RdpData (RdpDatatype dt)
1668                 {
1669                         this.dt = dt;
1670                 }
1671
1672                 RdpDatatype dt;
1673                 public RdpDatatype Datatype {
1674                         get { return dt; }
1675                 }
1676
1677                 public override bool Nullable {
1678                         get { return false; }
1679                 }
1680
1681                 internal override bool IsTextValueDependent {
1682                         get { return true; }
1683                 }
1684
1685                 internal override bool IsContextDependent {
1686                         get { return dt.IsContextDependent; }
1687                 }
1688
1689                 public override RelaxngPatternType PatternType {
1690                         get { return RelaxngPatternType.Data; }
1691                 }
1692
1693                 public override RdpContentType ContentType {
1694                         get { return RdpContentType.Simple; }
1695                 }
1696
1697                 public override void GetLabels (LabelList elements, LabelList attributes, bool collectNameClass)
1698                 {
1699                         // do nothing.
1700                 }
1701
1702                 public override RdpPattern TextDeriv (string s, XmlReader reader)
1703                 {
1704                         if (dt.IsAllowed (s, reader))
1705                                 return RdpEmpty.Instance;
1706                         else
1707                                 return RdpNotAllowed.Instance;
1708                 }
1709
1710                 internal override void MarkReachableDefs () 
1711                 {
1712                         // do nothing
1713                 }
1714
1715                 internal override void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept)
1716                 {
1717                         // do nothing
1718                 }
1719
1720                 internal override bool ContainsText()
1721                 {
1722                         return false;
1723                 }
1724         }
1725
1726         // DataExcept
1727         public class RdpDataExcept : RdpData
1728         {
1729                 public RdpDataExcept (RdpDatatype dt, RdpPattern except)
1730                         : base (dt)
1731                 {
1732                         this.except = except;
1733                 }
1734
1735                 RdpPattern except;
1736                 public RdpPattern Except {
1737                         get { return except; }
1738                         set { except = value; }
1739                 }
1740
1741                 public override RelaxngPatternType PatternType {
1742                         get { return RelaxngPatternType.DataExcept; }
1743                 }
1744
1745                 public override RdpContentType ContentType {
1746                         get {
1747                                 RdpContentType c = except.ContentType; // conformance required for except pattern.
1748                                 return RdpContentType.Simple;
1749                         }
1750                 }
1751
1752                 internal override RdpPattern ReduceEmptyAndNotAllowed (ref bool result, Hashtable visited)
1753                 {
1754                         if (visited.Contains (this))
1755                                 return this;
1756                         visited.Add (this, this);
1757
1758                         if (except.PatternType == RelaxngPatternType.NotAllowed) {
1759                                 result = true;
1760                                 return new RdpData (this.Datatype);
1761                         } else {
1762                                 except = except.ReduceEmptyAndNotAllowed (ref result, visited);
1763                                 return this;
1764                         }
1765                 }
1766
1767                 public override RdpPattern TextDeriv (string s, XmlReader reader)
1768                 {
1769                         if (Datatype.IsAllowed (s, reader) && !except.TextDeriv (s, reader).Nullable)
1770                                 return RdpEmpty.Instance;
1771                         else
1772                                 return RdpNotAllowed.Instance;
1773                 }
1774
1775                 internal override void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept)
1776                 {
1777                         this.except.CheckConstraints (attribute, oneOrMore, oneOrMoreGroup, oneOrMoreInterleave, list, true);
1778                 }
1779
1780                 internal override bool ContainsText()
1781                 {
1782                         return except.ContainsText ();
1783                 }
1784         }
1785
1786         // Value
1787         public class RdpValue : RdpPattern
1788         {
1789                 public RdpValue (RdpDatatype dt, string value)
1790                 {
1791                         this.dt = dt;
1792                         this.value = value;
1793                 }
1794
1795                 RdpDatatype dt;
1796                 public RdpDatatype Datatype {
1797                         get { return dt; }
1798                 }
1799
1800                 string value;
1801                 public string Value {
1802                         get { return value; }
1803                 }
1804
1805                 public override bool Nullable {
1806                         get { return false; }
1807                 }
1808
1809                 internal override bool IsTextValueDependent {
1810                         get { return true; }
1811                 }
1812
1813                 internal override bool IsContextDependent {
1814                         get { return dt.IsContextDependent; }
1815                 }
1816
1817                 public override RelaxngPatternType PatternType {
1818                         get { return RelaxngPatternType.Value; }
1819                 }
1820
1821                 public override RdpContentType ContentType {
1822                         get { return RdpContentType.Simple; }
1823                 }
1824
1825                 public override void GetLabels (LabelList elements, LabelList attributes, bool collectNameClass)
1826                 {
1827                         // do nothing
1828                 }
1829
1830                 string cachedValue;
1831                 RdpPattern cachedPattern;
1832
1833                 public override RdpPattern TextDeriv (string s, XmlReader reader)
1834                 {
1835                         if (s == cachedValue && !IsContextDependent)
1836                                 return cachedPattern;
1837                         cachedPattern = TextDerivCore (s, reader);
1838                         cachedValue = s;
1839                         return cachedPattern;
1840                 }
1841
1842                 RdpPattern TextDerivCore (string s, XmlReader reader)
1843                 {
1844                         if (dt.IsTypeEqual (value, s, reader))
1845                                 return RdpEmpty.Instance;
1846                         else
1847                                 return RdpNotAllowed.Instance;
1848                 }
1849
1850                 internal override void MarkReachableDefs () 
1851                 {
1852                         // do nothing
1853                 }
1854
1855                 internal override void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept) 
1856                 {
1857                         // nothing to be checked
1858                 }
1859
1860                 internal override bool ContainsText()
1861                 {
1862                         return false;
1863                 }
1864         }
1865
1866         // Attribute
1867         public class RdpAttribute : RdpPattern
1868         {
1869                 public RdpAttribute (RdpNameClass nameClass, RdpPattern p)
1870                 {
1871                         this.nameClass = nameClass;
1872                         this.children = p;
1873                 }
1874
1875                 RdpNameClass nameClass;
1876                 public RdpNameClass NameClass {
1877                         get { return nameClass; }
1878                 }
1879
1880                 RdpPattern children;
1881                 public RdpPattern Children {
1882                         get { return children; }
1883                         set { children = value; }
1884                 }
1885
1886                 public override bool Nullable {
1887                         get { return false; }
1888                 }
1889
1890                 internal override bool IsTextValueDependent {
1891                         get { return false; }
1892                 }
1893
1894                 internal override bool IsContextDependent {
1895                         get { return false; }
1896                 }
1897
1898                 public override RelaxngPatternType PatternType {
1899                         get { return RelaxngPatternType.Attribute; }
1900                 }
1901
1902                 public override RdpContentType ContentType {
1903                         get { return RdpContentType.Empty; }
1904                 }
1905
1906                 public override void GetLabels (LabelList elements, LabelList attributes, bool collectNameClass)
1907                 {
1908                         if (attributes != null) {
1909                                 if (collectNameClass)
1910                                         attributes [NameClass] = NameClass;
1911                                 else
1912                                         AddNameLabel (attributes, NameClass);
1913                         }
1914                 }
1915
1916                 bool isExpanded;
1917                 internal override RdpPattern ExpandRef (Hashtable defs)
1918                 {
1919                         if (!isExpanded) {
1920                                 isExpanded = true;
1921                                 children = children.ExpandRef (defs);
1922                         }
1923                         return this;
1924                 }
1925
1926                 internal override RdpPattern ReduceEmptyAndNotAllowed (ref bool result, Hashtable visited)
1927                 {
1928                         if (visited.Contains (this))
1929                                 return this;
1930                         visited.Add (this, this);
1931
1932                         if (children.PatternType == RelaxngPatternType.NotAllowed) {
1933                                 result = true;
1934                                 return RdpNotAllowed.Instance;
1935                         } else {
1936                                 children = children.ReduceEmptyAndNotAllowed (ref result, visited);
1937                                 return this;
1938                         }
1939                 }
1940
1941                 // attDeriv cx (Attribute nc p) (AttributeNode qn s) =
1942                 //  if contains nc qn && valueMatch cx p s then Empty else NotAllowed
1943                 public override RdpPattern AttDeriv (string name, string ns, string value, XmlReader reader)
1944                 {
1945                         // If value is null, then does not check ValueMatch.
1946 #if UseStatic
1947                         if (RdpUtil.Contains (this.nameClass, att.QName)
1948                                 && (value == null || RdpUtil.ValueMatch (ctx, this.children, att.Value)))
1949                                 return RdpEmpty.Instance;
1950                         else
1951                                 return RdpNotAllowed.Instance;
1952 #else
1953                         if (nameClass.Contains (name, ns) &&
1954                                 (value == null || children.ValueMatch (value, reader)))
1955                                 return RdpEmpty.Instance;
1956                         else
1957                                 return RdpNotAllowed.Instance;
1958 #endif
1959                 }
1960
1961                 public override RdpPattern StartAttDeriv (string name, string ns)
1962                 {
1963                         return nameClass.Contains (name, ns) ?
1964                                 children.After (RdpEmpty.Instance) : RdpNotAllowed.Instance;
1965                 }
1966
1967                 internal override RdpPattern StartAttDeriv (string name, string ns, MemoizationStore memo)
1968                 {
1969                         return nameClass.Contains (name, ns) ?
1970                                 children.After (RdpEmpty.Instance) : RdpNotAllowed.Instance;
1971                 }
1972
1973                 // startTagCloseDeriv (Attribute _ _) = NotAllowed
1974                 public override RdpPattern StartTagCloseDeriv ()
1975                 {
1976                         return RdpNotAllowed.Instance;
1977                 }
1978
1979                 internal override RdpPattern StartTagCloseDeriv (MemoizationStore memo)
1980                 {
1981                         return RdpNotAllowed.Instance;
1982                 }
1983
1984                 internal override void MarkReachableDefs () 
1985                 {
1986                         children.MarkReachableDefs ();
1987                 }
1988
1989                 internal override void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept) 
1990                 {
1991                         // 7.1.1 and 7.1.2
1992                         if (attribute || oneOrMoreGroup || oneOrMoreInterleave || list || dataExcept)
1993                                 throw new RelaxngException ("Not allowed attribute occurence was specified in the pattern.");
1994
1995                         // latter part of 7.3
1996                         if (!oneOrMore && NameClass.HasInfiniteName)
1997                                 throw new RelaxngException ("Attributes that has an infinite name class must be repeatable.");
1998
1999                         this.Children.CheckConstraints (true, oneOrMore, false, false, false, false);
2000                 }
2001
2002                 internal override bool ContainsText()
2003                 {
2004                         // This method is to detect text pattern inside interleave child.
2005                         // return children.ContainsText ();
2006                         return false;
2007                 }
2008         }
2009
2010         // Element
2011         public class RdpElement : RdpPattern
2012         {
2013                 public RdpElement (RdpNameClass nameClass, RdpPattern p)
2014                 {
2015                         this.nameClass = nameClass;
2016                         this.children = p;
2017                 }
2018
2019                 RdpNameClass nameClass;
2020                 public RdpNameClass NameClass {
2021                         get { return nameClass; }
2022                 }
2023
2024                 RdpPattern children;
2025                 public RdpPattern Children {
2026                         get { return children; }
2027                         set { children = value; }
2028                 }
2029
2030                 public override bool Nullable {
2031                         get { return false; }
2032                 }
2033
2034                 internal override bool IsTextValueDependent {
2035                         get { return false; }
2036                 }
2037
2038                 internal override bool IsContextDependent {
2039                         get { return false; }
2040                 }
2041
2042                 public override RelaxngPatternType PatternType {
2043                         get { return RelaxngPatternType.Element; }
2044                 }
2045
2046                 bool contentTypeCheckDone;
2047                 public override RdpContentType ContentType {
2048                         get {
2049                                 if (!contentTypeCheckDone) {
2050                                         contentTypeCheckDone = true;
2051                                         RdpContentType ct = children.ContentType; // conformance required.
2052                                 }
2053                                 return RdpContentType.Complex;
2054                         }
2055                 }
2056
2057                 public override void GetLabels (LabelList elements, LabelList attributes, bool collectNameClass)
2058                 {
2059                         if (elements != null) {
2060                                 if (collectNameClass)
2061                                         elements [NameClass] = NameClass;
2062                                 else
2063                                         AddNameLabel (elements, NameClass);
2064                         }
2065                 }
2066
2067
2068                 bool isExpanded;
2069                 short expanding; // FIXME: It is totally not required, but there is
2070                 // some bugs in simplification and without it it causes infinite loop.
2071                 internal override RdpPattern ExpandRef (Hashtable defs)
2072                 {
2073                         if (!isExpanded) {
2074                                 isExpanded = true;
2075                                 if (expanding == 100)
2076                                         throw new RelaxngException (String.Format ("Invalid recursion was found. Name is {0}", nameClass));
2077                                 expanding++;
2078                                 children = children.ExpandRef (defs);
2079                                 expanding--;
2080                         }
2081                         return this;
2082                 }
2083
2084                 internal override RdpPattern ReduceEmptyAndNotAllowed (ref bool result, Hashtable visited)
2085                 {
2086                         if (visited.Contains (this))
2087                                 return this;
2088                         visited.Add (this, this);
2089
2090                         children = children.ReduceEmptyAndNotAllowed (ref result, visited);
2091                         return this;
2092                 }
2093
2094                 internal override RdpPattern TextOnlyDeriv ()
2095                 {
2096                         return RdpNotAllowed.Instance;
2097                 }
2098
2099                 internal override RdpPattern TextOnlyDeriv (MemoizationStore memo)
2100                 {
2101                         return RdpNotAllowed.Instance;
2102                 }
2103
2104                 public override RdpPattern StartTagOpenDeriv (string name, string ns)
2105                 {
2106 #if UseStatic
2107                         if (RdpUtil.Contains (this.nameClass, qname))
2108                                 return RdpUtil.After (this.Children, RdpEmpty.Instance);
2109                         else
2110                                 return RdpNotAllowed.Instance;
2111 #else
2112                         return nameClass.Contains (name, ns) ?
2113                                 children.After (RdpEmpty.Instance) :
2114                                 RdpNotAllowed.Instance;
2115 #endif
2116                 }
2117
2118                 internal override RdpPattern StartTagOpenDeriv (string name, string ns, MemoizationStore memo)
2119                 {
2120                         return nameClass.Contains (name, ns) ?
2121                                 children.After (RdpEmpty.Instance) :
2122                                 RdpNotAllowed.Instance;
2123                 }
2124
2125                 internal override void MarkReachableDefs () 
2126                 {
2127                         children.MarkReachableDefs ();
2128                 }
2129
2130                 bool constraintsChecked;
2131                 internal override void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept) 
2132                 {
2133                         if (constraintsChecked)
2134                                 return;
2135                         constraintsChecked = true;
2136                         if (attribute || list || dataExcept)
2137                                 throw new RelaxngException ("Not allowed element occurence was specified in the pattern.");
2138                         this.Children.CheckConstraints (false, false, false, oneOrMoreInterleave, false, false);
2139                 }
2140
2141                 internal override bool ContainsText()
2142                 {
2143                         return false;
2144                 }
2145         }
2146
2147         // After
2148         public class RdpAfter : RdpAbstractBinary
2149         {
2150                 public RdpAfter (RdpPattern l, RdpPattern r) : base (l, r)
2151                 {
2152                 }
2153
2154                 public override bool Nullable {
2155                         get { return false; }
2156                 }
2157
2158                 internal override bool IsTextValueDependent {
2159                         get { return LValue.IsTextValueDependent; }
2160                 }
2161
2162                 internal override bool IsContextDependent {
2163                         get { return LValue.IsContextDependent; }
2164                 }
2165
2166                 public override void GetLabels (LabelList elements, LabelList attributes, bool collectNameClass)
2167                 {
2168                         LValue.GetLabels (elements, attributes, collectNameClass);
2169                 }
2170
2171                 public override RdpPattern TextDeriv (string s, XmlReader reader)
2172                 {
2173                         return LValue.TextDeriv (s, reader).After (RValue);
2174                 }
2175
2176                 internal override RdpPattern TextDeriv (string s, XmlReader reader, MemoizationStore memo)
2177                 {
2178                         return memo.TextDeriv (LValue, s, reader).After (RValue);
2179                 }
2180
2181                 internal override RdpPattern EmptyTextDeriv (MemoizationStore memo)
2182                 {
2183                         return memo.EmptyTextDeriv (LValue).After (RValue);
2184                 }
2185
2186                 internal override RdpPattern TextOnlyDeriv ()
2187                 {
2188                         return LValue.TextOnlyDeriv ().After (RValue);
2189                 }
2190
2191                 internal override RdpPattern TextOnlyDeriv (MemoizationStore memo)
2192                 {
2193                         return memo.TextOnlyDeriv (LValue).After (RValue);
2194                 }
2195
2196                 internal override RdpPattern MixedTextDeriv ()
2197                 {
2198                         return LValue.MixedTextDeriv ().After (RValue);
2199                 }
2200
2201                 internal override RdpPattern MixedTextDeriv (MemoizationStore memo)
2202                 {
2203                         return memo.MixedTextDeriv (LValue).After (RValue);
2204                 }
2205
2206                 // startTagOpenDeriv (After p1 p2) qn =
2207                 //   applyAfter (flip after p2) (startTagOpenDeriv p1 qn)
2208                 public override RdpPattern StartTagOpenDeriv (string name, string ns)
2209                 {
2210                         RdpPattern handled = LValue.StartTagOpenDeriv (name, ns);
2211                         RdpFlip f = MakeFlip (RdpUtil.AfterFunction, RValue);
2212                         return handled.ApplyAfter (new RdpApplyAfterHandler (
2213                                 f.Apply));
2214                 }
2215
2216                 internal override RdpPattern StartTagOpenDeriv (string name, string ns, MemoizationStore memo)
2217                 {
2218                         RdpPattern handled = memo.StartTagOpenDeriv (LValue, name, ns);
2219                         RdpFlip f = MakeFlip (RdpUtil.AfterFunction, RValue);
2220                         return handled.ApplyAfter (new RdpApplyAfterHandler (
2221                                 f.Apply));
2222                 }
2223
2224                 public override RdpPattern ApplyAfter (RdpApplyAfterHandler handler)
2225                 {
2226                         return LValue.After (handler (RValue));
2227                 }
2228
2229                 // attDeriv cx (After p1 p2) att =
2230                 //  after (attDeriv cx p1 att) p2
2231                 public override RdpPattern AttDeriv (string name, string ns, string value, XmlReader reader)
2232                 {
2233                         return LValue.AttDeriv (name, ns, value, reader).After (RValue);
2234                 }
2235
2236                 public override RdpPattern StartAttDeriv (string name, string ns)
2237                 {
2238                         RdpPattern handled = LValue.StartAttDeriv (name, ns);
2239                         RdpFlip f = MakeFlip (RdpUtil.AfterFunction, RValue);
2240                         return handled.ApplyAfter (new RdpApplyAfterHandler (
2241                                 f.Apply));
2242                 }
2243
2244                 internal override RdpPattern StartAttDeriv (string name, string ns, MemoizationStore memo)
2245                 {
2246                         RdpPattern handled = memo.StartAttDeriv (LValue, name, ns);
2247                         RdpFlip f = MakeFlip (RdpUtil.AfterFunction, RValue);
2248                         return handled.ApplyAfter (new RdpApplyAfterHandler (
2249                                 f.Apply));
2250                 }
2251
2252                 public override RdpPattern EndAttDeriv ()
2253                 {
2254                         return LValue.Nullable ? RValue : RdpNotAllowed.Instance;
2255                 }
2256
2257                 public override RdpPattern StartTagCloseDeriv ()
2258                 {
2259                         return LValue.StartTagCloseDeriv ().After (RValue);
2260                 }
2261
2262                 internal override RdpPattern StartTagCloseDeriv (MemoizationStore memo)
2263                 {
2264                         return memo.StartTagCloseDeriv (LValue).After (RValue);
2265                 }
2266
2267                 public override RdpPattern EndTagDeriv ()
2268                 {
2269                         return LValue.Nullable ? RValue : RdpNotAllowed.Instance;
2270                 }
2271
2272                 public override RelaxngPatternType PatternType {
2273                         get { return RelaxngPatternType.After; }
2274                 }
2275
2276                 internal override void MarkReachableDefs () 
2277                 {
2278                         throw new InvalidOperationException ();
2279                 }
2280
2281                 internal override void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept) 
2282                 {
2283                         throw new InvalidOperationException ();
2284                 }
2285
2286                 internal override bool ContainsText ()
2287                 {
2288                         throw new InvalidOperationException ();
2289                 }
2290         }
2291 }
2292