* roottypes.cs: Rename from tree.cs.
[mono.git] / mcs / class / Commons.Xml.Relaxng / Commons.Xml.Relaxng.Derivative / RdpPatterns.cs
index 7906de1ffe0152691f78e4947fb8118bfcc5d0cc..a729b8db56bc0f70d9a9fe8b0121478af1b7b579 100644 (file)
@@ -1,14 +1,14 @@
-//\r
-// Commons.Xml.Relaxng.Derivative.RdpPatterns.cs\r
-//\r
-// Author:\r
-//     Atsushi Enomoto <ginga@kit.hi-ho.ne.jp>\r
-//\r
-// 2003 Atsushi Enomoto "No rights reserved."\r
-//\r
-// Copyright (c) 2004 Novell Inc.\r
-// All rights reserved\r
-//\r
+//
+// Commons.Xml.Relaxng.Derivative.RdpPatterns.cs
+//
+// Author:
+//     Atsushi Enomoto <ginga@kit.hi-ho.ne.jp>
+//
+// 2003 Atsushi Enomoto "No rights reserved."
+//
+// Copyright (c) 2004 Novell Inc.
+// All rights reserved
+//
 
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 //
-\r
-using System;\r
-using System.Collections;\r
-using System.Xml;\r
-using Commons.Xml.Relaxng;\r
-\r
-using LabelList = System.Collections.Hashtable;\r
-\r
-\r
-namespace Commons.Xml.Relaxng.Derivative\r
-{\r
-       public delegate RdpPattern RdpApplyAfterHandler (RdpPattern p);\r
-\r
-       // abstract Pattern\r
-       public abstract class RdpPattern\r
-       {\r
-               internal bool nullableComputed;\r
-               internal bool isNullable;\r
-               Hashtable patternPool;\r
-\r
-               internal string debug ()\r
-               {\r
-                       return RdpUtil.DebugRdpPattern (this, new Hashtable ());\r
-               }\r
-\r
-               public abstract RelaxngPatternType PatternType { get; }\r
-\r
-               public abstract RdpContentType ContentType { get; }\r
-\r
-               private Hashtable setupTable (Type type, RdpPattern p)\r
-               {\r
-                       // Why?\r
-                       if (patternPool == null) {\r
-                               patternPool = new Hashtable ();\r
-                       }\r
-\r
-                       Hashtable typePool = (Hashtable) patternPool [type];\r
-                       if (typePool == null) {\r
-                               typePool = new Hashtable ();\r
-                               patternPool [type] = typePool;\r
-                       }\r
-                       Hashtable pTable = (Hashtable) typePool [p];\r
-                       if (pTable == null) {\r
-                               pTable = new Hashtable ();\r
-                               typePool [p] = pTable;\r
-                       }\r
-                       return pTable;\r
-               }\r
-\r
-               public RdpChoice MakeChoice (RdpPattern p1, RdpPattern p2)\r
-               {\r
-                       Hashtable p1Table = setupTable (typeof (RdpChoice), p1);\r
-                       if (p1Table [p2] == null) {\r
-                               RdpChoice c = new RdpChoice (p1, p2);\r
-                               c.setInternTable (this.patternPool);\r
-                               p1Table [p2] = c;\r
-                       }\r
-                       return (RdpChoice) p1Table [p2];\r
-               }\r
-\r
-               public RdpPattern MakeGroup (RdpPattern p1, RdpPattern p2)\r
-               {\r
-                       Hashtable p1Table = setupTable (typeof (RdpGroup), p1);\r
-                       if (p1Table [p2] == null) {\r
-                               RdpGroup g = new RdpGroup (p1, p2);\r
-                               g.setInternTable (this.patternPool);\r
-                               p1Table [p2] = g;\r
-                       }\r
-                       return (RdpGroup) p1Table [p2];\r
-               }\r
-\r
-               public RdpInterleave MakeInterleave (RdpPattern p1, RdpPattern p2)\r
-               {\r
-                       Hashtable p1Table = setupTable (typeof (RdpInterleave), p1);\r
-                       if (p1Table [p2] == null) {\r
-                               RdpInterleave i = new RdpInterleave (p1, p2);\r
-                               i.setInternTable (this.patternPool);\r
-                               p1Table [p2] = i;\r
-                       }\r
-                       return (RdpInterleave) p1Table [p2];\r
-               }\r
-\r
-               public RdpAfter MakeAfter (RdpPattern p1, RdpPattern p2)\r
-               {\r
-                       Hashtable p1Table = setupTable (typeof (RdpAfter), p1);\r
-                       if (p1Table [p2] == null) {\r
-                               RdpAfter a = new RdpAfter (p1, p2);\r
-                               a.setInternTable (this.patternPool);\r
-                               p1Table [p2] = a;\r
-                       }\r
-                       return (RdpAfter) p1Table [p2];\r
-               }\r
-\r
-               public RdpOneOrMore MakeOneOrMore (RdpPattern p)\r
-               {\r
-                       Hashtable p1Table = setupTable (typeof (RdpOneOrMore), p);\r
-                       Hashtable pTable = (Hashtable) patternPool [RelaxngPatternType.OneOrMore];\r
-                       if (pTable == null) {\r
-                               pTable = new Hashtable ();\r
-                               patternPool [RelaxngPatternType.OneOrMore] = pTable;\r
-                       }\r
-                       if (pTable [p] == null)\r
-                               pTable [p] = new RdpOneOrMore (p);\r
-                       return (RdpOneOrMore) pTable [p];\r
-               }\r
-\r
-               internal void setInternTable (Hashtable ht)\r
-               {\r
-                       this.patternPool = ht;\r
-\r
-                       Hashtable pt = ht [PatternType] as Hashtable;\r
-                       if (pt == null) {\r
-                               pt = new Hashtable ();\r
-                               ht [PatternType] = pt;\r
-                       }\r
-\r
-                       RdpAbstractSingleContent single =\r
-                               this as RdpAbstractSingleContent;\r
-                       if (single != null) {\r
-                               if (pt [single.Child] == null) {\r
-                                       pt [single.Child] = this;\r
-                                       single.Child.setInternTable (ht);\r
-                               }\r
-                               return;\r
-                       }\r
-\r
-                       RdpAbstractBinary binary =\r
-                               this as RdpAbstractBinary;\r
-                       if (binary != null) {\r
-                               Hashtable lTable = setupTable (GetType (), binary.LValue);\r
-                               if (lTable [binary.RValue] == null) {\r
-                                       lTable [binary.RValue] = this;\r
-                                       binary.LValue.setInternTable (ht);\r
-                                       binary.RValue.setInternTable (ht);\r
-                               }\r
-                               return;\r
-                       }\r
-\r
-                       // For rest patterns, only check recursively, without pooling.\r
-                       RdpAttribute attr = this as RdpAttribute;\r
-                       if (attr != null) {\r
-                               attr.Children.setInternTable (ht);\r
-                               return;\r
-                       }\r
-                       RdpElement el = this as RdpElement;\r
-                       if (el != null) {\r
-                               el.Children.setInternTable (ht);\r
-                               return;\r
-                       }\r
-                       RdpDataExcept dex= this as RdpDataExcept;\r
-                       if (dex != null) {\r
-                               dex.Except.setInternTable (ht);\r
-                               return;\r
-                       }\r
-\r
-                       switch (PatternType) {\r
-                       case RelaxngPatternType.Empty:\r
-                       case RelaxngPatternType.NotAllowed:\r
-                       case RelaxngPatternType.Text:\r
-                       case RelaxngPatternType.Data:\r
-                       case RelaxngPatternType.Value:\r
-                               return;\r
-                       }\r
-\r
-#if REPLACE_IN_ADVANCE\r
-                       throw new InvalidOperationException ();\r
-#endif\r
-               }\r
-\r
-               internal abstract void MarkReachableDefs ();\r
-\r
-               internal abstract void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept);\r
-\r
-               // This method is to detect text pattern inside interleave child.\r
-               internal abstract bool ContainsText ();\r
-\r
-               internal virtual RdpPattern ExpandRef (Hashtable defs)\r
-               {\r
-                       return this;\r
-               }\r
-\r
-               internal virtual RdpPattern ReduceEmptyAndNotAllowed (ref bool result, Hashtable visited)\r
-               {\r
-                       return this;\r
-               }\r
-\r
-               public abstract bool Nullable { get; }\r
-\r
-               // fills QName collection\r
-               public void GetLabels (LabelList elements, LabelList attributes)\r
-               {\r
-                       GetLabels (elements, attributes, false);\r
-               }\r
-\r
-               public abstract void GetLabels (LabelList elements, LabelList attributes, bool collectNameClass);\r
-\r
-               internal void AddNameLabel (LabelList names, RdpNameClass nc)\r
-               {\r
-                       RdpName name = nc as RdpName;\r
-                       if (name != null) {\r
-                               XmlQualifiedName qname = new XmlQualifiedName (\r
-                                       name.LocalName, name.NamespaceURI);\r
-                               names [qname] = qname;\r
-                               return;\r
-                       }\r
-                       RdpNameClassChoice choice = nc as RdpNameClassChoice;\r
-                       if (choice != null) {\r
-                               AddNameLabel (names, choice.LValue);\r
-                               AddNameLabel (names, choice.RValue);\r
-                               return;\r
-                       }\r
-                       // For NsName and AnyName, do nothing.\r
-               }\r
-\r
-               #region Derivative\r
-               public virtual RdpPattern TextDeriv (string s, XmlReader reader)\r
-               {\r
-                       // This is an extension to JJC algorithm.\r
-                       // Whitespace text are allowed except for Data and Value\r
-                       // (their TextDeriv are overridden)\r
-                       return Util.IsWhitespace (s) ? this : RdpNotAllowed.Instance;\r
-               }\r
-\r
-/*\r
-               public RdpPattern ChildDeriv (RdpChildNode child)\r
-               {\r
-                       RdpTextChild tc = child as RdpTextChild;\r
-//                     RdpElementChild ec = child as RdpElementChild;\r
-                       if (tc != null) {\r
-                               return TextDeriv (tc.Text);\r
-                       } else {\r
-                               // complex stuff;-(\r
-                               return StartTagOpenDeriv (ec.LocalName, ec.NamespaceURI)\r
-                                               .AttsDeriv (ec.Attributes)\r
-                                               .StartTagCloseDeriv ()\r
-                                       .ChildrenDeriv (ec.ChildNodes)\r
-                                       .EndTagDeriv ();\r
-                       }\r
-               }\r
-*/\r
-\r
-               public RdpPattern ListDeriv (string [] list, int index, XmlReader reader)\r
-               {\r
-                       return listDerivInternal (list, 0, reader);\r
-               }\r
-\r
-               private RdpPattern listDerivInternal (string [] list, int start, XmlReader reader)\r
-               {\r
-                       if (list.Length <= start)\r
-                               return this;\r
-                       else\r
-                               return this.TextDeriv (list [start], reader).listDerivInternal (list, start + 1, reader);\r
-               }\r
-\r
-               // Choice(this, p)\r
-               public virtual RdpPattern Choice (RdpPattern p)\r
-               {\r
-                       if (p is RdpNotAllowed)\r
-                               return this;\r
-                       else if (this is RdpNotAllowed)\r
-                               return p;\r
-                       else\r
-                               return MakeChoice (this, p);\r
-               }\r
-\r
-               // Group(this, p)\r
-               public virtual RdpPattern Group (RdpPattern p)\r
-               {\r
-                       if (p is RdpNotAllowed || this is RdpNotAllowed)\r
-                               return RdpNotAllowed.Instance;\r
-                       else if (p is RdpEmpty)\r
-                               return this;\r
-                       else if (this is RdpEmpty)\r
-                               return p;\r
-                       else\r
-                               return MakeGroup (this, p);\r
-               }\r
-\r
-               // Interleave(this, p)\r
-               public virtual RdpPattern Interleave (RdpPattern p)\r
-               {\r
-                       if (p is RdpNotAllowed || this is RdpNotAllowed)\r
-                               return RdpNotAllowed.Instance;\r
-                       else if (p is RdpEmpty)\r
-                               return this;\r
-                       else if (this is RdpEmpty)\r
-                               return p;\r
-                       else\r
-                               return MakeInterleave (this, p);\r
-               }\r
-\r
-               // After(this, p)\r
-               public virtual RdpPattern After (RdpPattern p)\r
-               {\r
-                       if (this is RdpNotAllowed || p is RdpNotAllowed)\r
-                               return RdpNotAllowed.Instance;\r
-                       else\r
-                               return MakeAfter (this, p);\r
-               }\r
-\r
-\r
-               // applyAfter((f, p1=this), p2)\r
-               public virtual RdpPattern ApplyAfter (RdpApplyAfterHandler h)\r
-               {\r
-                       return RdpNotAllowed.Instance;\r
-               }\r
-\r
-               // startTagOpenDeriv (this, qname)\r
-               // startTagOpenDeriv _ qn = NotAllowed (default)\r
-               public virtual RdpPattern StartTagOpenDeriv (string name, string ns)\r
-               {\r
-                       return RdpNotAllowed.Instance;\r
-               }\r
-\r
-               // attDeriv(ctx, this, att)\r
-               // attDeriv _ _ _ = NotAllowed\r
-               public virtual RdpPattern AttDeriv (string name, string ns, string value, XmlReader reader)\r
-               {\r
-                       return RdpNotAllowed.Instance;\r
-               }\r
-\r
-               public bool ValueMatch (string s, XmlReader reader)\r
-               {\r
-                       return TextDeriv (s, reader).Nullable;\r
-               }\r
-\r
-               public virtual RdpPattern StartTagCloseDeriv ()\r
-               {\r
-                       return this;\r
-               }\r
-\r
-               /*\r
-               public RdpPattern ChildrenDeriv (RdpChildNodes children)\r
-               {\r
-                       return childrenDerivInternal (children, 0);\r
-               }\r
-\r
-               RdpPattern childrenDerivInternal (RdpChildNodes children, int start)\r
-               {\r
-                       if (children.Count == 0) {\r
-                               // childrenDeriv cx p []\r
-                               RdpChildNodes c = new RdpChildNodes ();\r
-                               c.Add (new RdpTextChild (String.Empty));\r
-                               return ChildrenDeriv (c);\r
-                       } else if (children.Count == 1 && children [0] is RdpTextChild) {\r
-                               // childrenDeriv cx p [(TextNode s)]\r
-                               RdpTextChild tc = children [0] as RdpTextChild;\r
-                               RdpPattern p1 = ChildDeriv (tc);\r
-                               return RdpUtil.Whitespace (tc.Text) ?\r
-                                       RdpUtil.Choice (this, p1) : p1;\r
-                       } else\r
-                               // childrenDeriv cx p children\r
-                               return stripChildrenDerivInternal (children, start);\r
-               }\r
-\r
-               RdpPattern stripChildrenDerivInternal (RdpChildNodes children, int start)\r
-               {\r
-                       if (children.Count == start)\r
-                               return this;\r
-                       else {\r
-                               RdpChildNode firstChild =\r
-                                       children [start] as RdpChildNode;\r
-                               RdpPattern p =\r
-                                       (firstChild.IsNonWhitespaceText) ?\r
-                                       this : ChildDeriv (firstChild);\r
-                               return p.childrenDerivInternal (children, start + 1);\r
-                       }\r
-               }\r
-               */\r
-\r
-               public RdpPattern OneOrMore ()\r
-               {\r
-                       if (PatternType == RelaxngPatternType.NotAllowed)\r
-                               return RdpNotAllowed.Instance;\r
-                       else\r
-                               return MakeOneOrMore (this);\r
-               }\r
-\r
-               public virtual RdpPattern EndTagDeriv ()\r
-               {\r
-                       return RdpNotAllowed.Instance;\r
-               }\r
-               #endregion\r
-       }\r
-\r
-       // Empty\r
-       public class RdpEmpty : RdpPattern\r
-       {\r
-               public RdpEmpty () {}\r
-               static RdpEmpty ()\r
-               {\r
-                       instance = new RdpEmpty ();\r
-               }\r
-\r
-               public override bool Nullable {\r
-                       get { return true; }\r
-               }\r
-\r
-               static RdpEmpty instance;\r
-               public static RdpEmpty Instance {\r
-                       get { return instance; }\r
-               }\r
-\r
-               public override RelaxngPatternType PatternType {\r
-                       get { return RelaxngPatternType.Empty; }\r
-               }\r
-\r
-               public override RdpContentType ContentType {\r
-                       get { return RdpContentType.Empty; }\r
-               }\r
-\r
-               public override void GetLabels (LabelList elements, LabelList attributes, bool collectNameClass)\r
-               {\r
-                       // do nothing\r
-               }\r
-\r
-               internal override void MarkReachableDefs () \r
-               {\r
-                       // do nothing\r
-               }\r
-\r
-               internal override void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept)\r
-               {\r
-                       if (dataExcept)\r
-                               throw new RelaxngException ("empty cannot appear under except of a data pattern.");\r
-               }\r
-\r
-               internal override bool ContainsText()\r
-               {\r
-                       return false;\r
-               }\r
-       }\r
-\r
-       // NotAllowed\r
-       public class RdpNotAllowed : RdpPattern\r
-       {\r
-               public RdpNotAllowed () {}\r
-               static RdpNotAllowed ()\r
-               {\r
-                       instance = new RdpNotAllowed ();\r
-               }\r
-\r
-               static RdpNotAllowed instance;\r
-               public static RdpNotAllowed Instance {\r
-                       get { return instance; }\r
-               }\r
-\r
-               public override bool Nullable {\r
-                       get { return false; }\r
-               }\r
-\r
-               public override RdpPattern ApplyAfter (RdpApplyAfterHandler h)\r
-               {\r
-                       return RdpNotAllowed.Instance;\r
-               }\r
-\r
-               public override RelaxngPatternType PatternType {\r
-                       get { return RelaxngPatternType.NotAllowed; }\r
-               }\r
-\r
-               public override RdpContentType ContentType {\r
-                       get { return RdpContentType.Empty; }\r
-               }\r
-\r
-               internal override void MarkReachableDefs () \r
-               {\r
-                       // do nothing\r
-               }\r
-\r
-               internal override void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept)\r
-               {\r
-                       // do nothing\r
-               }\r
-\r
-               internal override bool ContainsText()\r
-               {\r
-                       return false;\r
-               }\r
-\r
-               public override void GetLabels (LabelList elements, LabelList attributes, bool collectNameClass)\r
-               {\r
-                       // FIXME: Supposed to clear something here?\r
-               }\r
-       }\r
-\r
-       // Text\r
-       public class RdpText : RdpPattern\r
-       {\r
-               static RdpText instance;\r
-               public static RdpText Instance {\r
-                       get { return instance; }\r
-               }\r
-\r
-               public RdpText () {}\r
-               static RdpText ()\r
-               {\r
-                       instance = new RdpText ();\r
-               }\r
-\r
-               public override bool Nullable {\r
-                       get { return true; }\r
-               }\r
-\r
-               public override RelaxngPatternType PatternType {\r
-                       get { return RelaxngPatternType.Text; }\r
-               }\r
-\r
-               public override RdpContentType ContentType {\r
-                       get { return RdpContentType.Complex; }\r
-               }\r
-\r
-               public override RdpPattern TextDeriv (string s, XmlReader reader)\r
-               {\r
-                       return this;\r
-               }\r
-\r
-               internal override void MarkReachableDefs () \r
-               {\r
-                       // do nothing\r
-               }\r
-\r
-               internal override void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept)\r
-               {\r
-                       if (list)\r
-                               throw new RelaxngException ("text is not allowed under a list.");\r
-                       if (dataExcept)\r
-                               throw new RelaxngException ("text is not allowed under except of a list.");\r
-               }\r
-\r
-               internal override bool ContainsText()\r
-               {\r
-                       return true;\r
-               }\r
-\r
-               public override void GetLabels (LabelList elements, LabelList attributes, bool collectNameClass)\r
-               {\r
-                       // do nothing\r
-               }\r
-       }\r
-\r
-       // AbstractBinary\r
-       public abstract class RdpAbstractBinary : RdpPattern\r
-       {\r
-               public RdpAbstractBinary (RdpPattern l, RdpPattern r)\r
-               {\r
-                       this.l = l;\r
-                       this.r = r;\r
-               }\r
-\r
-               RdpPattern l;\r
-               public RdpPattern LValue {\r
-                       get { return l; }\r
-                       set { l = value; }\r
-               }\r
-\r
-               RdpPattern r;\r
-               public RdpPattern RValue {\r
-                       get { return r; }\r
-                       set { r = value; }\r
-               }\r
-
-               RdpContentType computedContentType = RdpContentType.Invalid;\r
-               public override RdpContentType ContentType {\r
-                       get {\r
+
+using System;
+using System.Collections;
+using System.Xml;
+using Commons.Xml.Relaxng;
+
+using LabelList = System.Collections.Hashtable;
+
+
+namespace Commons.Xml.Relaxng.Derivative
+{
+       public delegate RdpPattern RdpApplyAfterHandler (RdpPattern p);
+
+       // abstract Pattern. Note that in README the classes in this namespace
+       // is explicitly written as not for public use (and hidden in monodoc
+       // for now).
+       public abstract class RdpPattern
+       {
+               internal bool nullableComputed;
+               internal bool isNullable;
+               Hashtable patternPool;
+
+               internal string debug ()
+               {
+                       return RdpUtil.DebugRdpPattern (this, new Hashtable ());
+               }
+
+               public abstract RelaxngPatternType PatternType { get; }
+
+               public abstract RdpContentType ContentType { get; }
+
+               private Hashtable setupTable (Type type, RdpPattern p)
+               {
+                       if (patternPool == null) // could be null for RdpElement etc.
+                               patternPool = new Hashtable ();
+
+                       Hashtable typePool = (Hashtable) patternPool [type];
+                       if (typePool == null) {
+                               typePool = new Hashtable ();
+                               patternPool [type] = typePool;
+                       }
+                       Hashtable pTable = (Hashtable) typePool [p];
+                       if (pTable == null) {
+                               pTable = new Hashtable ();
+                               typePool [p] = pTable;
+                       }
+                       return pTable;
+               }
+
+               internal RdpFlip MakeFlip (RdpBinaryFunction func, RdpPattern p)
+               {
+                       if (patternPool == null) // could be null for RdpElement etc.
+                               patternPool = new Hashtable ();
+
+                       // Though this method takes function argument, all
+                       // p1 callers have different pattern types, so we don't
+                       // have to distinguish tables by func.
+
+                       Hashtable table = patternPool [func] as Hashtable;
+                       if (table == null) {
+                               table = new Hashtable ();
+                               patternPool [func] = table;
+                       }
+                       RdpFlip f = table [p] as RdpFlip;
+                       if (f != null)
+                               return f;
+                       f = new RdpFlip (func, p);
+                       table [p] = f;
+                       return f;
+               }
+
+               public RdpChoice MakeChoiceLeaf (RdpPattern p)
+               {
+                       if (patternPool == null) // could be null for RdpElement etc.
+                               patternPool = new Hashtable ();
+                       Hashtable leaves = (Hashtable) patternPool [typeof (RdpEmpty)];
+                       if (leaves == null) {
+                               leaves = new Hashtable ();
+                               patternPool [typeof (RdpEmpty)] = leaves;
+                       }
+                       RdpChoice leaf = leaves [p] as RdpChoice;
+                       if (leaf == null) {
+                               leaf = new RdpChoice (RdpEmpty.Instance, p);
+                               leaf.setInternTable (patternPool);
+                               leaves [p] = leaf;
+                       }
+                       return leaf;
+               }
+
+               public RdpPattern MakeChoice (RdpPattern p1, RdpPattern p2)
+               {
+                       if (p1.PatternType == RelaxngPatternType.NotAllowed)
+                               return p2;
+                       if (p2.PatternType == RelaxngPatternType.NotAllowed)
+                               return p1;
+                       if (p1 == p2)
+                               return p1;
+                       // choice-leaves support
+                       if (p1.PatternType == RelaxngPatternType.Empty)
+                               return MakeChoiceLeaf (p2);
+                       if (p2.PatternType == RelaxngPatternType.Empty)
+                               return MakeChoiceLeaf (p1);
+
+                       if (p1.GetHashCode () > p2.GetHashCode ()) {
+                               RdpPattern tmp = p1;
+                               p1 = p2;
+                               p2 = tmp;
+                       }
+
+                       Hashtable p1Table = setupTable (typeof (RdpChoice), p1);
+                       if (p1Table [p2] == null) {
+                               RdpChoice c = new RdpChoice (p1, p2);
+                               c.setInternTable (this.patternPool);
+                               p1Table [p2] = c;
+                       }
+                       return (RdpChoice) p1Table [p2];
+               }
+
+               public RdpPattern MakeGroup (RdpPattern p1, RdpPattern p2)
+               {
+                       if (p1.PatternType == RelaxngPatternType.Empty)
+                               return p2;
+
+                       Hashtable p1Table = setupTable (typeof (RdpGroup), p1);
+                       if (p1Table [p2] == null) {
+                               RdpGroup g = new RdpGroup (p1, p2);
+                               g.setInternTable (this.patternPool);
+                               p1Table [p2] = g;
+                       }
+                       return (RdpGroup) p1Table [p2];
+               }
+
+               public RdpInterleave MakeInterleave (RdpPattern p1, RdpPattern p2)
+               {
+                       if (p1.GetHashCode () > p2.GetHashCode ()) {
+                               RdpPattern tmp = p1;
+                               p1 = p2;
+                               p2 = tmp;
+                       }
+
+                       Hashtable p1Table = setupTable (typeof (RdpInterleave), p1);
+                       if (p1Table [p2] == null) {
+                               RdpInterleave i = new RdpInterleave (p1, p2);
+                               i.setInternTable (this.patternPool);
+                               p1Table [p2] = i;
+                       }
+                       return (RdpInterleave) p1Table [p2];
+               }
+
+               public RdpAfter MakeAfter (RdpPattern p1, RdpPattern p2)
+               {
+                       Hashtable p1Table = setupTable (typeof (RdpAfter), p1);
+                       if (p1Table [p2] == null) {
+                               RdpAfter a = new RdpAfter (p1, p2);
+                               a.setInternTable (this.patternPool);
+                               p1Table [p2] = a;
+                       }
+                       return (RdpAfter) p1Table [p2];
+               }
+
+               public RdpOneOrMore MakeOneOrMore (RdpPattern p)
+               {
+                       if (patternPool == null) // could be null for RdpElement etc.
+                               patternPool = new Hashtable ();
+
+                       Hashtable pTable = (Hashtable) patternPool [typeof (RdpOneOrMore)];
+                       if (pTable == null) {
+                               pTable = new Hashtable ();
+                               patternPool [typeof (RdpOneOrMore)] = pTable;
+                       }
+                       if (pTable [p] == null) {
+                               RdpOneOrMore oom = new RdpOneOrMore (p);
+                               oom.setInternTable (patternPool);
+                               pTable [p] = oom;
+                       }
+                       return (RdpOneOrMore) pTable [p];
+               }
+
+               internal void setInternTable (Hashtable ht)
+               {
+                       if (this.patternPool != null)
+                               return;
+                       this.patternPool = ht;
+
+                       Hashtable pt = ht [GetType ()] as Hashtable;
+                       if (pt == null) {
+                               pt = new Hashtable ();
+                               ht [GetType ()] = pt;
+                       }
+
+                       RdpAbstractSingleContent single =
+                               this as RdpAbstractSingleContent;
+                       if (single != null) {
+                               if (pt [single.Child] == null) {
+                                       pt [single.Child] = this;
+                                       single.Child.setInternTable (ht);
+                               }
+                               return;
+                       }
+
+                       RdpAbstractBinary binary =
+                               this as RdpAbstractBinary;
+                       if (binary != null) {
+                               Hashtable lTable = setupTable (GetType (), binary.LValue);
+                               if (lTable [binary.RValue] == null) {
+                                       lTable [binary.RValue] = this;
+                                       binary.LValue.setInternTable (ht);
+                                       binary.RValue.setInternTable (ht);
+                               }
+                               return;
+                       }
+
+                       // For rest patterns, only check recursively, without pooling.
+                       RdpAttribute attr = this as RdpAttribute;
+                       if (attr != null) {
+                               attr.Children.setInternTable (ht);
+                               return;
+                       }
+                       RdpElement el = this as RdpElement;
+                       if (el != null) {
+                               el.Children.setInternTable (ht);
+                               return;
+                       }
+                       RdpDataExcept dex= this as RdpDataExcept;
+                       if (dex != null) {
+                               dex.Except.setInternTable (ht);
+                               return;
+                       }
+
+                       switch (PatternType) {
+                       case RelaxngPatternType.Empty:
+                       case RelaxngPatternType.NotAllowed:
+                       case RelaxngPatternType.Text:
+                       case RelaxngPatternType.Data:
+                       case RelaxngPatternType.Value:
+                               return;
+                       }
+
+#if REPLACE_IN_ADVANCE
+                       throw new InvalidOperationException ();
+#endif
+               }
+
+               internal abstract void MarkReachableDefs ();
+
+               internal abstract void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept);
+
+               // This method is to detect text pattern inside interleave child.
+               internal abstract bool ContainsText ();
+
+               internal virtual RdpPattern ExpandRef (Hashtable defs)
+               {
+                       return this;
+               }
+
+               internal virtual RdpPattern ReduceEmptyAndNotAllowed (ref bool result, Hashtable visited)
+               {
+                       return this;
+               }
+
+               public abstract bool Nullable { get; }
+
+               internal virtual bool IsTextValueDependent {
+                       get { return false; }
+               }
+
+               internal virtual bool IsContextDependent {
+                       get { return false; }
+               }
+
+               // fills QName collection
+               public void GetLabels (LabelList elements, LabelList attributes)
+               {
+                       GetLabels (elements, attributes, false);
+               }
+
+               public abstract void GetLabels (LabelList elements, LabelList attributes, bool collectNameClass);
+
+               internal void AddNameLabel (LabelList names, RdpNameClass nc)
+               {
+                       RdpName name = nc as RdpName;
+                       if (name != null) {
+                               XmlQualifiedName qname = new XmlQualifiedName (
+                                       name.LocalName, name.NamespaceURI);
+                               names [qname] = qname;
+                               return;
+                       }
+                       RdpNameClassChoice choice = nc as RdpNameClassChoice;
+                       if (choice != null) {
+                               AddNameLabel (names, choice.LValue);
+                               AddNameLabel (names, choice.RValue);
+                               return;
+                       }
+                       // For NsName and AnyName, do nothing.
+               }
+
+               #region Derivative
+               public virtual RdpPattern TextDeriv (string s, XmlReader reader)
+               {
+                       return RdpNotAllowed.Instance;
+               }
+
+               internal virtual RdpPattern TextDeriv (string s, XmlReader reader, MemoizationStore memo)
+               {
+                       return TextDeriv (s, reader);
+               }
+
+               internal virtual RdpPattern EmptyTextDeriv (MemoizationStore memo)
+               {
+                       return TextDeriv (String.Empty, null, memo);
+               }
+
+               internal virtual RdpPattern TextOnlyDeriv ()
+               {
+                       return this;
+               }
+
+               internal virtual RdpPattern TextOnlyDeriv (MemoizationStore store)
+               {
+                       return this;
+               }
+
+               internal virtual RdpPattern MixedTextDeriv ()
+               {
+                       return RdpNotAllowed.Instance;
+               }
+
+               internal virtual RdpPattern MixedTextDeriv (MemoizationStore memo)
+               {
+                       return RdpNotAllowed.Instance;
+               }
+
+               public RdpPattern ListDeriv (string [] list, int index, XmlReader reader)
+               {
+                       return listDerivInternal (list, 0, reader);
+               }
+
+               private RdpPattern listDerivInternal (string [] list, int start, XmlReader reader)
+               {
+                       if (list.Length <= start)
+                               return this;
+                       else if (list [start].Length == 0)
+                               return listDerivInternal (list, start + 1, reader);
+                       else
+                               return this.TextDeriv (list [start].Trim (RdpUtil.WhitespaceChars), reader).listDerivInternal (list, start + 1, reader);
+               }
+
+               // Choice(this, p)
+               public virtual RdpPattern Choice (RdpPattern p)
+               {
+                       if (p is RdpNotAllowed)
+                               return this;
+                       else if (this is RdpNotAllowed)
+                               return p;
+                       else
+                               return MakeChoice (this, p);
+               }
+
+               // Group(this, p)
+               public virtual RdpPattern Group (RdpPattern p)
+               {
+                       if (p is RdpNotAllowed || this is RdpNotAllowed)
+                               return RdpNotAllowed.Instance;
+                       else if (p is RdpEmpty)
+                               return this;
+                       else if (this is RdpEmpty)
+                               return p;
+                       else
+                               return MakeGroup (this, p);
+               }
+
+               // Interleave(this, p)
+               public virtual RdpPattern Interleave (RdpPattern p)
+               {
+                       if (p is RdpNotAllowed || this is RdpNotAllowed)
+                               return RdpNotAllowed.Instance;
+                       else if (p is RdpEmpty)
+                               return this;
+                       else if (this is RdpEmpty)
+                               return p;
+                       else
+                               return MakeInterleave (this, p);
+               }
+
+               // After(this, p)
+               public virtual RdpPattern After (RdpPattern p)
+               {
+                       if (this is RdpNotAllowed || p is RdpNotAllowed)
+                               return RdpNotAllowed.Instance;
+                       else
+                               return MakeAfter (this, p);
+               }
+
+
+               // applyAfter((f, p1=this), p2)
+               public virtual RdpPattern ApplyAfter (RdpApplyAfterHandler h)
+               {
+                       throw new Exception ("INTERNAL ERROR: should not happen. This is " + this);
+               }
+
+               // startTagOpenDeriv (this, qname)
+               // startTagOpenDeriv _ qn = NotAllowed (default)
+               public virtual RdpPattern StartTagOpenDeriv (string name, string ns)
+               {
+                       return RdpNotAllowed.Instance;
+               }
+
+               internal virtual RdpPattern StartTagOpenDeriv (string name, string ns, MemoizationStore memo)
+               {
+                       return StartTagOpenDeriv (name, ns);
+               }
+
+               // attDeriv(ctx, this, att)
+               // attDeriv _ _ _ = NotAllowed
+               public virtual RdpPattern AttDeriv (string name, string ns, string value, XmlReader reader)
+               {
+                       return RdpNotAllowed.Instance;
+               }
+
+               public virtual RdpPattern StartAttDeriv (string name, string ns)
+               {
+                       return RdpNotAllowed.Instance;
+               }
+
+               internal virtual RdpPattern StartAttDeriv (string name, string ns, MemoizationStore memo)
+               {
+                       return StartAttDeriv (name, ns);
+               }
+
+               public virtual RdpPattern EndAttDeriv ()
+               {
+                       return RdpNotAllowed.Instance;
+               }
+
+               internal virtual RdpPattern EndAttDeriv (MemoizationStore memo)
+               {
+                       return EndAttDeriv ();
+               }
+
+               public bool ValueMatch (string s, XmlReader reader)
+               {
+                       return Nullable && Util.IsWhitespace (s) ||
+                               TextDeriv (s, reader).Nullable;
+               }
+
+               public virtual RdpPattern StartTagCloseDeriv ()
+               {
+                       return this;
+               }
+
+               internal virtual RdpPattern StartTagCloseDeriv (MemoizationStore memo)
+               {
+                       return StartTagCloseDeriv ();
+               }
+
+               public RdpPattern OneOrMore ()
+               {
+                       if (PatternType == RelaxngPatternType.NotAllowed)
+                               return RdpNotAllowed.Instance;
+                       else
+                               return MakeOneOrMore (this);
+               }
+
+               public virtual RdpPattern EndTagDeriv ()
+               {
+                       return RdpNotAllowed.Instance;
+               }
+
+               internal virtual RdpPattern EndTagDeriv (MemoizationStore memo)
+               {
+                       return EndTagDeriv ();
+               }
+               #endregion
+       }
+
+       // Empty
+       public class RdpEmpty : RdpPattern
+       {
+               public RdpEmpty () {}
+               static RdpEmpty ()
+               {
+                       instance = new RdpEmpty ();
+               }
+
+               public override bool Nullable {
+                       get { return true; }
+               }
+
+               internal override bool IsTextValueDependent {
+                       get { return false; }
+               }
+
+               internal override bool IsContextDependent {
+                       get { return false; }
+               }
+
+               static RdpEmpty instance;
+               public static RdpEmpty Instance {
+                       get { return instance; }
+               }
+
+               public override RelaxngPatternType PatternType {
+                       get { return RelaxngPatternType.Empty; }
+               }
+
+               public override RdpContentType ContentType {
+                       get { return RdpContentType.Empty; }
+               }
+
+               public override void GetLabels (LabelList elements, LabelList attributes, bool collectNameClass)
+               {
+                       // do nothing
+               }
+
+               internal override void MarkReachableDefs () 
+               {
+                       // do nothing
+               }
+
+               internal override void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept)
+               {
+                       if (dataExcept)
+                               throw new RelaxngException ("empty cannot appear under except of a data pattern.");
+               }
+
+               internal override bool ContainsText()
+               {
+                       return false;
+               }
+       }
+
+       // NotAllowed
+       public class RdpNotAllowed : RdpPattern
+       {
+               public RdpNotAllowed () {}
+               static RdpNotAllowed ()
+               {
+                       instance = new RdpNotAllowed ();
+               }
+
+               static RdpNotAllowed instance;
+               public static RdpNotAllowed Instance {
+                       get { return instance; }
+               }
+
+               public override bool Nullable {
+                       get { return false; }
+               }
+
+               internal override bool IsTextValueDependent {
+                       get { return false; }
+               }
+
+               internal override bool IsContextDependent {
+                       get { return false; }
+               }
+
+               public override RdpPattern ApplyAfter (RdpApplyAfterHandler h)
+               {
+                       return RdpNotAllowed.Instance;
+               }
+
+               public override RelaxngPatternType PatternType {
+                       get { return RelaxngPatternType.NotAllowed; }
+               }
+
+               public override RdpContentType ContentType {
+                       get { return RdpContentType.Empty; }
+               }
+
+               internal override void MarkReachableDefs () 
+               {
+                       // do nothing
+               }
+
+               internal override void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept)
+               {
+                       // do nothing
+               }
+
+               internal override bool ContainsText()
+               {
+                       return false;
+               }
+
+               public override void GetLabels (LabelList elements, LabelList attributes, bool collectNameClass)
+               {
+                       // FIXME: Supposed to clear something here?
+               }
+       }
+
+       // Text
+       public class RdpText : RdpPattern
+       {
+               static RdpText instance;
+               public static RdpText Instance {
+                       get { return instance; }
+               }
+
+               public RdpText () {}
+               static RdpText ()
+               {
+                       instance = new RdpText ();
+               }
+
+               public override bool Nullable {
+                       get { return true; }
+               }
+
+               internal override bool IsTextValueDependent {
+                       get { return false; }
+               }
+
+               internal override bool IsContextDependent {
+                       get { return false; }
+               }
+
+               public override RelaxngPatternType PatternType {
+                       get { return RelaxngPatternType.Text; }
+               }
+
+               public override RdpContentType ContentType {
+                       get { return RdpContentType.Complex; }
+               }
+
+               public override RdpPattern TextDeriv (string s, XmlReader reader)
+               {
+                       return this;
+               }
+
+               internal override RdpPattern EmptyTextDeriv (MemoizationStore memo)
+               {
+                       return this;
+               }
+
+               internal override RdpPattern MixedTextDeriv ()
+               {
+                       return this;
+               }
+
+               internal override RdpPattern MixedTextDeriv (MemoizationStore memo)
+               {
+                       return this;
+               }
+
+               internal override void MarkReachableDefs () 
+               {
+                       // do nothing
+               }
+
+               internal override void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept)
+               {
+                       if (list)
+                               throw new RelaxngException ("text is not allowed under a list.");
+                       if (dataExcept)
+                               throw new RelaxngException ("text is not allowed under except of a list.");
+               }
+
+               internal override bool ContainsText()
+               {
+                       return true;
+               }
+
+               public override void GetLabels (LabelList elements, LabelList attributes, bool collectNameClass)
+               {
+                       // do nothing
+               }
+       }
+
+       // AbstractBinary
+       public abstract class RdpAbstractBinary : RdpPattern
+       {
+               public RdpAbstractBinary (RdpPattern l, RdpPattern r)
+               {
+                       this.l = l;
+                       this.r = r;
+               }
+
+               RdpPattern l;
+               public RdpPattern LValue {
+                       get { return l; }
+                       set { l = value; }
+               }
+
+               RdpPattern r;
+               public RdpPattern RValue {
+                       get { return r; }
+                       set { r = value; }
+               }
+
+               RdpContentType computedContentType = RdpContentType.Invalid;
+               public override RdpContentType ContentType {
+                       get {
                                if (computedContentType == RdpContentType.Invalid) {
-                                       if (l.ContentType == RdpContentType.Empty)\r
-                                               computedContentType = r.ContentType;\r
-                                       else if (r.ContentType == RdpContentType.Empty)\r
+                                       if (l.ContentType == RdpContentType.Empty)
+                                               computedContentType = r.ContentType;
+                                       else if (r.ContentType == RdpContentType.Empty)
                                                computedContentType = l.ContentType;
-                                       else if ((l.ContentType & RdpContentType.Simple) != 0 || ((r.ContentType & RdpContentType.Simple) != 0))\r
-                                               throw new RelaxngException ("The content type of this group is invalid.");\r
+                                       else if ((l.ContentType & RdpContentType.Simple) != 0 || ((r.ContentType & RdpContentType.Simple) != 0))
+                                               throw new RelaxngException ("The content type of this group is invalid.");
                                        else
                                                computedContentType = RdpContentType.Complex;
                                }
-                               return computedContentType;\r
-                       }\r
-               }\r
-\r
-               bool expanded;\r
-               internal override RdpPattern ExpandRef (Hashtable defs)\r
-               {\r
-                       if (!expanded) {\r
-                               l = l.ExpandRef (defs);\r
-                               r = r.ExpandRef (defs);\r
-                       }\r
-                       return this;\r
-               }\r
-\r
-               internal override RdpPattern ReduceEmptyAndNotAllowed (ref bool result, Hashtable visited)\r
-               {\r
-                       if (visited.Contains (this))\r
-                               return this;\r
-                       visited.Add (this, this);\r
-\r
-                       if (LValue.PatternType == RelaxngPatternType.NotAllowed ||\r
-                               RValue.PatternType == RelaxngPatternType.NotAllowed) {\r
-                               result = true;\r
-                               return RdpNotAllowed.Instance;\r
-                       } else if (LValue.PatternType == RelaxngPatternType.Empty) {\r
-                               result = true;\r
-                               return RValue.ReduceEmptyAndNotAllowed (ref result, visited);\r
-                       } else if (RValue.PatternType == RelaxngPatternType.Empty) {\r
-                               result = true;\r
-                               return LValue.ReduceEmptyAndNotAllowed (ref result, visited);\r
-                       } else {\r
-                               LValue = LValue.ReduceEmptyAndNotAllowed (ref result, visited);\r
-                               RValue = RValue.ReduceEmptyAndNotAllowed (ref result, visited);\r
-                               return this;\r
-                       }\r
-               }\r
-\r
-               internal override void MarkReachableDefs () \r
-               {\r
-                       l.MarkReachableDefs ();\r
-                       r.MarkReachableDefs ();\r
-               }\r
-\r
-               internal override bool ContainsText()\r
-               {\r
-                       return l.ContainsText () || r.ContainsText ();\r
-               }\r
-\r
-               // 7.3 (group/interleave attribute names) and\r
-               // part of 7.4 (interleave element names)\r
-               // FIXME: Actually it should be done against the correct\r
-               // simplified grammar, expanding all refs.\r
-               internal void CheckNameOverlap (bool checkElements)\r
-               {\r
-                       if (RdpUtil.NamesOverlap (LValue, RValue, checkElements))\r
-                               throw new RelaxngException ("Duplicate attributes inside a group or an interleave is not allowed.");\r
-                       return;\r
-               }\r
-       }\r
-\r
-       // Choice\r
-       public class RdpChoice : RdpAbstractBinary\r
-       {\r
-               public RdpChoice (RdpPattern l, RdpPattern r) : base (l, r)\r
-               {\r
-               }\r
-\r
-               public override bool Nullable {\r
-                       get {\r
-                               if (!nullableComputed) {\r
-                                       isNullable =\r
-                                               LValue.Nullable || RValue.Nullable;\r
-                                       nullableComputed = true;\r
-                               }\r
-                               return isNullable;\r
-                       }\r
-               }\r
-\r
-               public override RelaxngPatternType PatternType {\r
-                       get { return RelaxngPatternType.Choice; }\r
-               }\r
-
-               RdpContentType computedContentType = RdpContentType.Invalid;\r
-               public override RdpContentType ContentType {\r
+                               return computedContentType;
+                       }
+               }
+
+               bool expanded;
+               internal override RdpPattern ExpandRef (Hashtable defs)
+               {
+                       if (!expanded) {
+                               l = l.ExpandRef (defs);
+                               r = r.ExpandRef (defs);
+                       }
+                       return this;
+               }
+
+               internal override RdpPattern ReduceEmptyAndNotAllowed (ref bool result, Hashtable visited)
+               {
+                       if (visited.Contains (this))
+                               return this;
+                       visited.Add (this, this);
+
+                       if (LValue.PatternType == RelaxngPatternType.NotAllowed ||
+                               RValue.PatternType == RelaxngPatternType.NotAllowed) {
+                               result = true;
+                               return RdpNotAllowed.Instance;
+                       } else if (LValue.PatternType == RelaxngPatternType.Empty) {
+                               result = true;
+                               return RValue.ReduceEmptyAndNotAllowed (ref result, visited);
+                       } else if (RValue.PatternType == RelaxngPatternType.Empty) {
+                               result = true;
+                               return LValue.ReduceEmptyAndNotAllowed (ref result, visited);
+                       } else {
+                               LValue = LValue.ReduceEmptyAndNotAllowed (ref result, visited);
+                               RValue = RValue.ReduceEmptyAndNotAllowed (ref result, visited);
+                               return this;
+                       }
+               }
+
+               internal override void MarkReachableDefs () 
+               {
+                       l.MarkReachableDefs ();
+                       r.MarkReachableDefs ();
+               }
+
+               internal override bool ContainsText()
+               {
+                       return l.ContainsText () || r.ContainsText ();
+               }
+
+               // 7.3 (group/interleave attribute names) and
+               // part of 7.4 (interleave element names)
+               // FIXME: Actually it should be done against the correct
+               // simplified grammar, expanding all refs.
+               internal void CheckNameOverlap (bool checkElements)
+               {
+                       if (RdpUtil.NamesOverlap (LValue, RValue, checkElements))
+                               throw new RelaxngException ("Duplicate attributes inside a group or an interleave is not allowed.");
+                       return;
+               }
+       }
+
+       // Choice
+       public class RdpChoice : RdpAbstractBinary
+       {
+               public RdpChoice (RdpPattern l, RdpPattern r) : base (l, r)
+               {
+               }
+
+               public override bool Nullable {
+                       get {
+                               if (!nullableComputed) {
+                                       isNullable =
+                                               LValue.Nullable || RValue.Nullable;
+                                       nullableComputed = true;
+                               }
+                               return isNullable;
+                       }
+               }
+
+               bool isTextValueDependentComputed;
+               bool isTextValueDependent;
+
+               internal override bool IsTextValueDependent {
+                       get {
+                               if (!isTextValueDependentComputed) {
+                                       isTextValueDependent = LValue.IsTextValueDependent || RValue.IsTextValueDependent;
+                                       isTextValueDependentComputed = true;
+                               }
+                               return isTextValueDependent;
+                       }
+               }
+
+               bool isContextDependentComputed;
+               bool isContextDependent;
+
+               internal override bool IsContextDependent {
+                       get {
+                               if (!isContextDependentComputed) {
+                                       isContextDependent = LValue.IsContextDependent || RValue.IsContextDependent;
+                                       isContextDependentComputed = true;
+                               }
+                               return isContextDependent;
+                       }
+               }
+
+               public override RelaxngPatternType PatternType {
+                       get { return RelaxngPatternType.Choice; }
+               }
+
+               RdpContentType computedContentType = RdpContentType.Invalid;
+               public override RdpContentType ContentType {
                        get {
                                if (computedContentType == RdpContentType.Invalid) {
-                                       if (LValue.ContentType == RdpContentType.Simple ||\r
-                                               RValue.ContentType == RdpContentType.Simple)\r
+                                       if (LValue.ContentType == RdpContentType.Simple ||
+                                               RValue.ContentType == RdpContentType.Simple)
                                                computedContentType = RdpContentType.Simple;
-                                       else\r
-                                               computedContentType = base.ContentType;\r
+                                       else
+                                               computedContentType = base.ContentType;
+                               }
+                               return computedContentType;
+                       }
+               }
+
+               public override void GetLabels (LabelList elements, LabelList attributes, bool collectNameClass)
+               {
+                       LValue.GetLabels (elements, attributes, collectNameClass);
+                       RValue.GetLabels (elements, attributes, collectNameClass);
+               }
+
+
+               internal override RdpPattern ReduceEmptyAndNotAllowed (ref bool result, Hashtable visited)
+               {
+                       if (visited.Contains (this))
+                               return this;
+                       visited.Add (this, this);
+
+                       if (LValue.PatternType == RelaxngPatternType.NotAllowed &&
+                               RValue.PatternType == RelaxngPatternType.NotAllowed) {
+                               result = true;
+                               return RdpNotAllowed.Instance;
+                       } else if (LValue.PatternType == RelaxngPatternType.NotAllowed) {
+                               result = true;
+                               return RValue.ReduceEmptyAndNotAllowed (ref result, visited);
+                       } else if (RValue.PatternType == RelaxngPatternType.NotAllowed) {
+                               result = true;
+                               return LValue.ReduceEmptyAndNotAllowed (ref result, visited);
+                       } else if (LValue.PatternType == RelaxngPatternType.Empty &&
+                               RValue.PatternType == RelaxngPatternType.Empty) {
+                               result = true;
+                               return RdpEmpty.Instance;
+                       } else if (RValue.PatternType == RelaxngPatternType.Empty) {
+                               result = true;
+                               RValue = LValue.ReduceEmptyAndNotAllowed (ref result, visited);
+                               LValue = RdpEmpty.Instance;
+                               return this;
+                       } else {
+                               LValue = LValue.ReduceEmptyAndNotAllowed (ref result, visited);
+                               RValue = RValue.ReduceEmptyAndNotAllowed (ref result, visited);
+                               return this;
+                       }
+               }
+
+               public override RdpPattern TextDeriv (string s, XmlReader reader)
+               {
+                       return LValue.TextDeriv (s, reader).Choice (RValue.TextDeriv (s, reader));
+               }
+
+               internal override RdpPattern TextDeriv (string s, XmlReader reader, MemoizationStore memo)
+               {
+                       return memo.TextDeriv (LValue, s, reader).Choice (memo.TextDeriv (RValue, s, reader));
+               }
+
+               internal override RdpPattern EmptyTextDeriv (MemoizationStore memo)
+               {
+                       return memo.EmptyTextDeriv (LValue)
+                               .Choice (memo.EmptyTextDeriv (RValue));
+               }
+
+               internal override RdpPattern TextOnlyDeriv ()
+               {
+                       return LValue.TextOnlyDeriv ().Choice (
+                               RValue.TextOnlyDeriv ());
+               }
+
+               internal override RdpPattern TextOnlyDeriv (MemoizationStore memo)
+               {
+                       return memo.TextOnlyDeriv (LValue).Choice (
+                               memo.TextOnlyDeriv (RValue));
+               }
+
+               internal override RdpPattern MixedTextDeriv ()
+               {
+                       return LValue.MixedTextDeriv ().Choice (
+                               RValue.MixedTextDeriv ());
+               }
+
+               internal override RdpPattern MixedTextDeriv (MemoizationStore memo)
+               {
+                       return memo.MixedTextDeriv (LValue).Choice (
+                               memo.MixedTextDeriv (RValue));
+               }
+
+               public override RdpPattern ApplyAfter (RdpApplyAfterHandler handler)
+               {
+//                     return handler (LValue).Choice (handler (RValue));
+                       return LValue.ApplyAfter (handler).Choice (RValue.ApplyAfter (handler));
+               }
+
+               public override RdpPattern StartTagOpenDeriv (string name, string ns)
+               {
+#if UseStatic
+                       return RdpUtil.Choice (
+                               RdpUtil.StartTagOpenDeriv (LValue, qname),
+                               RdpUtil.StartTagOpenDeriv (RValue, qname));
+#else
+                       RdpPattern lDeriv = LValue.StartTagOpenDeriv (name, ns);
+                       return lDeriv.Choice (RValue.StartTagOpenDeriv (name, ns));
+#endif
+               }
+
+               internal override RdpPattern StartTagOpenDeriv (string name, string ns, MemoizationStore memo)
+               {
+                       RdpPattern lDeriv = memo.StartTagOpenDeriv (LValue, name, ns);
+                       return lDeriv.Choice (memo.StartTagOpenDeriv (RValue, name, ns));
+               }
+
+               // attDeriv cx (Choice p1 p2) att =
+               //  choice (attDeriv cx p1 att) (attDeriv cx p2 att)
+               public override RdpPattern AttDeriv (string name, string ns, string value, XmlReader reader)
+               {
+                       return LValue.AttDeriv (name, ns, value, reader)
+                               .Choice (RValue.AttDeriv (name, ns, value, reader));
+               }
+
+               public override RdpPattern StartAttDeriv (string name, string ns)
+               {
+                       RdpPattern lDeriv = LValue.StartAttDeriv (name, ns);
+                       return lDeriv.Choice (RValue.StartAttDeriv (name, ns));
+               }
+
+               internal override RdpPattern StartAttDeriv (string name, string ns, MemoizationStore memo)
+               {
+                       return memo.StartAttDeriv (LValue, name, ns)
+                               .Choice (memo.StartAttDeriv (RValue, name, ns));
+               }
+
+               public override RdpPattern EndAttDeriv ()
+               {
+                       return LValue.EndAttDeriv ().Choice (RValue.EndAttDeriv ());
+               }
+
+               internal override RdpPattern EndAttDeriv (MemoizationStore memo)
+               {
+                       return memo.EndAttDeriv (LValue).Choice (memo.EndAttDeriv (RValue));
+               }
+
+               // startTagCloseDeriv (Choice p1 p2) =
+               //  choice (startTagCloseDeriv p1) (startTagCloseDeriv p2)
+               public override RdpPattern StartTagCloseDeriv ()
+               {
+                       return LValue.StartTagCloseDeriv ()
+                               .Choice (RValue.StartTagCloseDeriv ());
+               }
+
+               internal override RdpPattern StartTagCloseDeriv (MemoizationStore memo)
+               {
+                       return memo.StartTagCloseDeriv (LValue)
+                               .Choice (memo.StartTagCloseDeriv (RValue));
+               }
+
+               public override RdpPattern EndTagDeriv ()
+               {
+                       return LValue.EndTagDeriv ().Choice (RValue.EndTagDeriv ());
+               }
+
+               internal override RdpPattern EndTagDeriv (MemoizationStore memo)
+               {
+                       return memo.EndTagDeriv (LValue).Choice (memo.EndTagDeriv (RValue));
+               }
+
+               internal override void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept)
+               {
+                       LValue.CheckConstraints (attribute, oneOrMore, oneOrMoreGroup, oneOrMoreInterleave, list, dataExcept);
+                       RValue.CheckConstraints (attribute, oneOrMore, oneOrMoreGroup, oneOrMoreInterleave, list, dataExcept);
+               }
+       }
+
+       // Interleave
+       public class RdpInterleave : RdpAbstractBinary
+       {
+               public RdpInterleave (RdpPattern l, RdpPattern r) : base (l, r)
+               {
+               }
+
+               public override bool Nullable {
+                       get {
+                               if (!nullableComputed) {
+                                       isNullable =
+                                               LValue.Nullable && RValue.Nullable;
+                                       nullableComputed = true;
                                }
-                               return computedContentType;\r
-                       }\r
-               }\r
-
-               public override void GetLabels (LabelList elements, LabelList attributes, bool collectNameClass)\r
-               {\r
-                       LValue.GetLabels (elements, attributes, collectNameClass);\r
-                       RValue.GetLabels (elements, attributes, collectNameClass);\r
-               }\r
-\r
-\r
-               internal override RdpPattern ReduceEmptyAndNotAllowed (ref bool result, Hashtable visited)\r
-               {\r
-                       if (visited.Contains (this))\r
-                               return this;\r
-                       visited.Add (this, this);\r
-\r
-                       if (LValue.PatternType == RelaxngPatternType.NotAllowed &&\r
-                               RValue.PatternType == RelaxngPatternType.NotAllowed) {\r
-                               result = true;\r
-                               return RdpNotAllowed.Instance;\r
-                       } else if (LValue.PatternType == RelaxngPatternType.NotAllowed) {\r
-                               result = true;\r
-                               return RValue.ReduceEmptyAndNotAllowed (ref result, visited);\r
-                       } else if (RValue.PatternType == RelaxngPatternType.NotAllowed) {\r
-                               result = true;\r
-                               return LValue.ReduceEmptyAndNotAllowed (ref result, visited);\r
-                       } else if (LValue.PatternType == RelaxngPatternType.Empty &&\r
-                               RValue.PatternType == RelaxngPatternType.Empty) {\r
-                               result = true;\r
-                               return RdpEmpty.Instance;\r
-                       } else if (RValue.PatternType == RelaxngPatternType.Empty) {\r
-                               result = true;\r
-                               RValue = LValue.ReduceEmptyAndNotAllowed (ref result, visited);\r
-                               LValue = RdpEmpty.Instance;\r
-                               return this;\r
-                       } else {\r
-                               LValue = LValue.ReduceEmptyAndNotAllowed (ref result, visited);\r
-                               RValue = RValue.ReduceEmptyAndNotAllowed (ref result, visited);\r
-                               return this;\r
-                       }\r
-               }\r
-\r
-               public override RdpPattern TextDeriv (string s, XmlReader reader)\r
-               {\r
-                       return LValue.TextDeriv (s, reader).Choice (RValue.TextDeriv (s, reader));\r
-               }\r
-\r
-               public override RdpPattern ApplyAfter (RdpApplyAfterHandler handler)\r
-               {\r
-//                     return handler (LValue).Choice (handler (RValue));\r
-                       return LValue.ApplyAfter (handler).Choice (RValue.ApplyAfter (handler));\r
-               }\r
-\r
-               public override RdpPattern StartTagOpenDeriv (string name, string ns)\r
-               {\r
-#if UseStatic\r
-                       return RdpUtil.Choice (\r
-                               RdpUtil.StartTagOpenDeriv (LValue, qname),\r
-                               RdpUtil.StartTagOpenDeriv (RValue, qname));\r
-#else\r
-                       RdpPattern lDeriv = LValue.StartTagOpenDeriv (name, ns);\r
-                       return lDeriv.Choice (RValue.StartTagOpenDeriv (name, ns));\r
-#endif\r
-               }\r
-\r
-               // attDeriv cx (Choice p1 p2) att =\r
-               //  choice (attDeriv cx p1 att) (attDeriv cx p2 att)\r
-               public override RdpPattern AttDeriv (string name, string ns, string value, XmlReader reader)\r
-               {\r
-                       return LValue.AttDeriv (name, ns, value, reader)\r
-                               .Choice (RValue.AttDeriv (name, ns, value, reader));\r
-               }\r
-\r
-               // startTagCloseDeriv (Choice p1 p2) =\r
-               //  choice (startTagCloseDeriv p1) (startTagCloseDeriv p2)\r
-               public override RdpPattern StartTagCloseDeriv ()\r
-               {\r
-                       return LValue.StartTagCloseDeriv ()\r
-                               .Choice (RValue.StartTagCloseDeriv ());\r
-               }\r
-\r
-               public override RdpPattern EndTagDeriv ()\r
-               {\r
-                       return LValue.EndTagDeriv ().Choice (RValue.EndTagDeriv ());\r
-               }\r
-\r
-               internal override void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept)\r
-               {\r
-                       LValue.CheckConstraints (attribute, oneOrMore, oneOrMoreGroup, oneOrMoreInterleave, list, dataExcept);\r
-                       RValue.CheckConstraints (attribute, oneOrMore, oneOrMoreGroup, oneOrMoreInterleave, list, dataExcept);\r
-               }\r
-       }\r
-\r
-       // Interleave\r
-       public class RdpInterleave : RdpAbstractBinary\r
-       {\r
-               public RdpInterleave (RdpPattern l, RdpPattern r) : base (l, r)\r
-               {\r
-               }\r
-\r
-               public override bool Nullable {\r
-                       get {\r
-                               if (!nullableComputed) {\r
-                                       isNullable =\r
-                                               LValue.Nullable && RValue.Nullable;\r
-                                       nullableComputed = true;\r
-                               }\r
-                               return isNullable;\r
-                       }\r
-               }\r
-\r
-               public override void GetLabels (LabelList elements, LabelList attributes, bool collectNameClass)\r
-               {\r
-                       LValue.GetLabels (elements, attributes, collectNameClass);\r
-                       RValue.GetLabels (elements, attributes, collectNameClass);\r
-               }\r
-\r
-               internal override RdpPattern ReduceEmptyAndNotAllowed (ref bool result, Hashtable visited)\r
-               {\r
-                       if (visited.Contains (this))\r
-                               return this;\r
-                       visited.Add (this, this);\r
-\r
-                       if (LValue.PatternType == RelaxngPatternType.NotAllowed ||\r
-                               RValue.PatternType == RelaxngPatternType.NotAllowed) {\r
-                               result = true;\r
-                               return RdpNotAllowed.Instance;\r
-                       } else {\r
-                               LValue = LValue.ReduceEmptyAndNotAllowed (ref result, visited);\r
-                               RValue = RValue.ReduceEmptyAndNotAllowed (ref result, visited);\r
-                               return this;\r
-                       }\r
-               }\r
-\r
-               public override RdpPattern TextDeriv (string s, XmlReader reader)\r
-               {\r
-                       return LValue.TextDeriv (s, reader).Interleave (RValue)\r
-                               .Choice (LValue.Interleave (RValue.TextDeriv (s, reader)));\r
-               }\r
-\r
-               // => choice (applyAfter (flip interleave p2) (startTagOpenDeriv p1 qn)) (applyAfter (interleave p1) (startTagOpenDeriv p2 qn)\r
-               // => p1.startTagOpenDeriv(qn).applyAfter (flip interleave p2).choice (p2.startTagOpenDeriv(qn).applyAfter (interleave p1) )\r
-               public override RdpPattern StartTagOpenDeriv (string name, string ns)\r
-               {\r
-                       RdpPattern handledL = LValue.StartTagOpenDeriv (name, ns);\r
-                       RdpPattern handledR = RValue.StartTagOpenDeriv (name, ns);\r
-                       RdpFlip flipL = new RdpFlip (new RdpBinaryFunction (RdpUtil.Interleave), RValue);\r
-                       RdpPattern choiceL = handledL.ApplyAfter (new RdpApplyAfterHandler (flipL.Apply));\r
-                       RdpPattern choiceR = handledR.ApplyAfter (new RdpApplyAfterHandler (LValue.Interleave));\r
-                       return choiceL.Choice (choiceR);\r
-               }\r
-\r
-               // attDeriv cx (Interleave p1 p2) att =\r
-               //  choice (interleave (attDeriv cx p1 att) p2)\r
-               //         (interleave p1 (attDeriv cx p2 att))\r
-               public override RdpPattern AttDeriv (string name, string ns, string value, XmlReader reader)\r
-               {\r
-                       return LValue.AttDeriv (name, ns, value, reader)\r
-                               .Interleave (RValue)\r
-                               .Choice (LValue.Interleave (\r
-                                       RValue.AttDeriv (name, ns, value, reader)));\r
-               }\r
-\r
-               // startTagCloseDeriv (Interleave p1 p2) =\r
-               //  interleave (startTagCloseDeriv p1) (startTagCloseDeriv p2)\r
-               public override RdpPattern StartTagCloseDeriv ()\r
-               {\r
-                       return LValue.StartTagCloseDeriv ()\r
-                               .Interleave (RValue.StartTagCloseDeriv ());\r
-               }\r
-\r
-               /*\r
-               // FIXME: This is not specified in James Clark's algorithm, so\r
-               // this may raise unstable behaviour!!\r
-               // I think this is right but not confident.\r
-               \r
-               // ... then I reminded to include it.\r
-               public override RdpPattern EndTagDeriv ()\r
-               {\r
-                       return LValue.Nullable ? RValue : RdpNotAllowed.Instance;\r
-               }\r
-               */\r
-\r
-               public override RelaxngPatternType PatternType {\r
-                       get { return RelaxngPatternType.Interleave; }\r
-               }\r
-\r
-               internal override void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept)\r
-               {\r
-                       if (list)\r
-                               throw new RelaxngException ("interleave is not allowed under a list.");\r
-                       if (dataExcept)\r
-                               throw new RelaxngException ("interleave is not allowed under except of a data.");\r
-\r
-                       // 7.1\r
-                       LValue.CheckConstraints (attribute, oneOrMore, oneOrMoreGroup, oneOrMore, list, dataExcept);\r
-                       RValue.CheckConstraints (attribute, oneOrMore, oneOrMoreGroup, oneOrMore, list, dataExcept);\r
-\r
-                       // unique name analysis - 7.3 and part of 7.4\r
-                       CheckNameOverlap (true);\r
-\r
-                       // (2) text/text prohibited\r
-                       if (LValue.ContainsText () && RValue.ContainsText ())\r
-                               throw new RelaxngException ("Both branches of the interleave contains a text pattern.");\r
-               }\r
-       }\r
-\r
-       // Group\r
-       public class RdpGroup : RdpAbstractBinary\r
-       {\r
-               public RdpGroup (RdpPattern l, RdpPattern r) : base (l, r)\r
-               {\r
-               }\r
-\r
-               public override bool Nullable {\r
-                       get {\r
-                               if (!nullableComputed) {\r
-                                       isNullable =\r
-                                               LValue.Nullable && RValue.Nullable;\r
-                                       nullableComputed = true;\r
-                               }\r
-                               return isNullable;\r
-                       }\r
-               }\r
-\r
-               public override void GetLabels (LabelList elements, LabelList attributes, bool collectNameClass)\r
-               {\r
-                       LValue.GetLabels (elements, attributes, collectNameClass);\r
-                       if (LValue.Nullable)\r
-                               RValue.GetLabels (elements, attributes, collectNameClass);\r
-                       else\r
-                               RValue.GetLabels (null, attributes, collectNameClass);\r
-               }\r
-\r
-               public override RdpPattern TextDeriv (string s, XmlReader reader)\r
-               {\r
-                       RdpPattern p = LValue.TextDeriv (s, reader).Group (RValue);\r
-                       return LValue.Nullable ?\r
-                               p.Choice (RValue.TextDeriv(s, reader)) : p;\r
-               }\r
-\r
-               // startTagOpenDeriv (Group p1 p2) qn =\r
-               //  let x = applyAfter (flip group p2) (startTagOpenDeriv p1 qn)\r
-               //  in if nullable p1 then\r
-               //       choice x (startTagOpenDeriv p2 qn)\r
-               //     else\r
-               //       x\r
-               public override RdpPattern StartTagOpenDeriv (string name, string ns)\r
-               {\r
-                       RdpPattern handled = LValue.StartTagOpenDeriv (name, ns);\r
-                       RdpFlip f = new RdpFlip (new RdpBinaryFunction (RdpUtil.Group), RValue);\r
-                       RdpPattern x = handled.ApplyAfter (new RdpApplyAfterHandler (f.Apply));\r
-                       if (LValue.Nullable)\r
-                               return x.Choice (RValue.StartTagOpenDeriv (name, ns));\r
-                       else\r
-                               return x;\r
-               }\r
-\r
-               // attDeriv cx (Group p1 p2) att =\r
-               //  choice (group (attDeriv cx p1 att) p2)\r
-               //         (group p1 (attDeriv cx p2 att))\r
-               public override RdpPattern AttDeriv (string name, string ns, string value, XmlReader reader)\r
-               {\r
-                       return LValue.AttDeriv (name, ns, value, reader).Group (RValue)\r
-                               .Choice (LValue.Group (\r
-                                       RValue.AttDeriv (name, ns, value, reader)));\r
-               }\r
-\r
-               // startTagCloseDeriv (Group p1 p2) =\r
-               //  group (startTagCloseDeriv p1) (startTagCloseDeriv p2)\r
-               public override RdpPattern StartTagCloseDeriv ()\r
-               {\r
-                       return LValue.StartTagCloseDeriv ()\r
-                               .Group (RValue.StartTagCloseDeriv ());\r
-               }\r
-\r
-               public override RelaxngPatternType PatternType {\r
-                       get { return RelaxngPatternType.Group; }\r
-               }\r
-\r
-               internal override void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept)\r
-               {\r
-                       if (dataExcept)\r
-                               throw new RelaxngException ("interleave is not allowed under except of a data.");\r
-\r
-                       LValue.CheckConstraints (attribute, oneOrMore, oneOrMore, oneOrMoreInterleave, list, dataExcept);\r
-                       RValue.CheckConstraints (attribute, oneOrMore, oneOrMore, oneOrMoreInterleave, list, dataExcept);\r
-\r
-                       // 7.3\r
-                       CheckNameOverlap (false);\r
-               }\r
-       }\r
-\r
-       public abstract class RdpAbstractSingleContent : RdpPattern\r
-       {\r
-               RdpPattern child;\r
-               bool isExpanded;\r
-\r
-               internal override RdpPattern ExpandRef (Hashtable defs)\r
-               {\r
-                       if (!isExpanded)\r
-                               child = child.ExpandRef (defs);\r
-                       return this;\r
-               }\r
-\r
-               public RdpAbstractSingleContent (RdpPattern p)\r
-               {\r
-                       this.child = p;\r
-               }\r
-\r
-               public RdpPattern Child {\r
-                       get { return child; }\r
-                       set { child = value; }\r
-               }\r
-\r
-               internal override void MarkReachableDefs () \r
-               {\r
-                       child.MarkReachableDefs ();\r
-               }\r
-\r
-               internal override bool ContainsText()\r
-               {\r
-                       return child.ContainsText ();\r
-               }\r
-       }\r
-\r
-       // OneOrMore\r
-       public class RdpOneOrMore : RdpAbstractSingleContent\r
-       {\r
-               public RdpOneOrMore (RdpPattern p) : base (p)\r
-               {\r
-               }\r
-\r
-               public override RelaxngPatternType PatternType {\r
-                       get { return RelaxngPatternType.OneOrMore; }\r
-               }\r
-\r
-               public override RdpContentType ContentType {\r
-                       get {\r
-                               if (Child.ContentType == RdpContentType.Simple)\r
-                                       throw new RelaxngException ("Invalid content type was found.");\r
-                               return Child.ContentType;\r
-                       }\r
-               }\r
-\r
-               public override bool Nullable {\r
-                       get { return Child.Nullable; }\r
-               }\r
-\r
-               public override void GetLabels (LabelList elements, LabelList attributes, bool collectNameClass)\r
-               {\r
-                       Child.GetLabels (elements, attributes, collectNameClass);\r
-               }\r
-\r
-               internal override RdpPattern ReduceEmptyAndNotAllowed (ref bool result, Hashtable visited)\r
-               {\r
-                       if (visited.Contains (this))\r
-                               return this;\r
-                       visited.Add (this, this);\r
-\r
-                       if (Child.PatternType == RelaxngPatternType.NotAllowed) {\r
-                               result = true;\r
-                               return RdpNotAllowed.Instance;\r
-                       } else if (Child.PatternType == RelaxngPatternType.Empty)\r
-                               return RdpEmpty.Instance;\r
-                       else {\r
-                               Child = Child.ReduceEmptyAndNotAllowed (ref result, visited);\r
-                               return this;\r
-                       }\r
-               }\r
-\r
-               public override RdpPattern TextDeriv (string s, XmlReader reader)\r
-               {\r
-                       return Child.TextDeriv (s, reader).Group (Choice (RdpEmpty.Instance));\r
-               }\r
-\r
-               // attDeriv cx (OneOrMore p) att =\r
-               //  group (attDeriv cx p att) (choice (OneOrMore p) Empty)\r
-               public override RdpPattern AttDeriv (string name, string ns, string value, XmlReader reader)\r
-               {\r
-#if UseStatic\r
-                       return RdpUtil.Group (\r
-                               RdpUtil.AttDeriv (ctx, children, att),\r
-                               RdpUtil.Choice (RdpUtil.OneOrMore (children), RdpEmpty.Instance));\r
-#else\r
-                       return Child.AttDeriv (name, ns, value, reader)\r
-                               .Group (Choice (RdpEmpty.Instance));\r
-#endif\r
-               }\r
-\r
-               // startTagOpenDeriv (OneOrMore p) qn =\r
-               //  applyAfter (flip group (choice (OneOrMore p) Empty))\r
-               //             (startTagOpenDeriv p qn)\r
-               public override RdpPattern StartTagOpenDeriv (string name, string ns)\r
-               {\r
-                       RdpPattern rest = RdpEmpty.Instance.Choice (Child.OneOrMore ());\r
-                       RdpPattern handled = Child.StartTagOpenDeriv (name, ns);\r
-                       RdpFlip f = new RdpFlip (new RdpBinaryFunction (RdpUtil.Group), rest);\r
-                       return handled.ApplyAfter (new RdpApplyAfterHandler (f.Apply));\r
-               }\r
-\r
-               // startTagCloseDeriv (OneOrMore p) =\r
-               //  oneOrMore (startTagCloseDeriv p)\r
-               public override RdpPattern StartTagCloseDeriv ()\r
-               {\r
-#if UseStatic\r
-                       return RdpUtil.OneOrMore (\r
-                               RdpUtil.StartTagCloseDeriv (children));\r
-#else\r
-                       return Child.StartTagCloseDeriv ().OneOrMore ();\r
-#endif\r
-               }\r
-\r
-               internal override void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept)\r
-               {\r
-                       if (dataExcept)\r
-                               throw new RelaxngException ("oneOrMore is not allowed under except of a data.");\r
-                       this.Child.CheckConstraints (attribute, true, oneOrMoreGroup, oneOrMoreInterleave, list, dataExcept);\r
-               }\r
-       }\r
-\r
-       // List\r
-       public class RdpList : RdpAbstractSingleContent\r
-       {\r
-               public RdpList (RdpPattern p) : base (p)\r
-               {\r
-               }\r
-\r
-               internal override RdpPattern ReduceEmptyAndNotAllowed (ref bool result, Hashtable visited)\r
-               {\r
-                       if (visited.Contains (this))\r
-                               return this;\r
-                       visited.Add (this, this);\r
-\r
-                       if (Child.PatternType == RelaxngPatternType.NotAllowed) {\r
-                               result = true;\r
-                               return RdpNotAllowed.Instance;\r
-                       } else {\r
-                               Child = Child.ReduceEmptyAndNotAllowed (ref result, visited);\r
-                               return this;\r
-                       }\r
-               }\r
-\r
-/*\r
-               // This is not written in James Clark's derivative algorithm\r
-               // ( http://www.thaiopensource.com/relaxng/derivative.html ),\r
-               // but it looks required.\r
-               public override bool Nullable {\r
-                       get { return this.Child.Nullable; }\r
-               }\r
-               \r
-               // ... but it also causes different error:\r
-               // <list><group><data .../><data .../></group></list>\r
-*/\r
-               public override bool Nullable {\r
-                       get { return false; }\r
-               }\r
-\r
-               public override RelaxngPatternType PatternType {\r
-                       get { return RelaxngPatternType.List; }\r
-               }\r
-\r
-               public override RdpContentType ContentType {\r
-                       get { return RdpContentType.Simple; }\r
-               }\r
-\r
-               public override void GetLabels (LabelList elements, LabelList attributes, bool collectNameClass)\r
-               {\r
-                       Child.GetLabels (elements, attributes, collectNameClass);\r
-               }\r
-\r
-               public override RdpPattern TextDeriv (string s, XmlReader reader)\r
-               {\r
-                       RdpPattern p = Child.ListDeriv (Util.NormalizeWhitespace (s).Split (RdpUtil.WhitespaceChars), 0, reader);                       \r
-                       if (p.Nullable)\r
-                               return RdpEmpty.Instance;\r
-                       else\r
-                               return RdpNotAllowed.Instance;\r
-               }\r
-\r
-               internal override void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept)\r
-               {\r
-                       if (list)\r
-                               throw new RelaxngException ("list is not allowed uner another list.");\r
-                       if (dataExcept)\r
-                               throw new RelaxngException ("list is not allowed under except of a data.");\r
-                       this.Child.CheckConstraints (attribute, oneOrMore, oneOrMoreGroup, oneOrMoreInterleave, true, dataExcept);\r
-               }\r
-       }\r
-\r
-       // Data\r
-       public class RdpData : RdpPattern\r
-       {\r
-               public RdpData (RdpDatatype dt)\r
-               {\r
-                       this.dt = dt;\r
-               }\r
-\r
-               RdpDatatype dt;\r
-               public RdpDatatype Datatype {\r
-                       get { return dt; }\r
-               }\r
-\r
-               // This is not written in James Clark's derivative algorithm\r
-               // ( http://www.thaiopensource.com/relaxng/derivative.html ),\r
-               // but it looks required.\r
-               public override bool Nullable {\r
-                       get {\r
-                               if (dt.NamespaceURI.Length == 0)\r
-                                       return true;\r
-                               return false; \r
-                       }\r
-               }\r
-\r
-               public override RelaxngPatternType PatternType {\r
-                       get { return RelaxngPatternType.Data; }\r
-               }\r
-\r
-               public override RdpContentType ContentType {\r
-                       get { return RdpContentType.Simple; }\r
-               }\r
-\r
-               public override void GetLabels (LabelList elements, LabelList attributes, bool collectNameClass)\r
-               {\r
-                       // do nothing.\r
-               }\r
-\r
-               public override RdpPattern TextDeriv (string s, XmlReader reader)\r
-               {\r
-                       if (dt.IsAllowed (s, reader))\r
-                               return RdpEmpty.Instance;\r
-                       else\r
-                               return RdpNotAllowed.Instance;\r
-               }\r
-\r
-               internal override void MarkReachableDefs () \r
-               {\r
-                       // do nothing\r
-               }\r
-\r
-               internal override void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept)\r
-               {\r
-                       // do nothing\r
-               }\r
-\r
-               internal override bool ContainsText()\r
-               {\r
-                       return false;\r
-               }\r
-       }\r
-\r
-       // DataExcept\r
-       public class RdpDataExcept : RdpData\r
-       {\r
-               public RdpDataExcept (RdpDatatype dt, RdpPattern except)\r
-                       : base (dt)\r
-               {\r
-                       this.except = except;\r
-               }\r
-\r
-               RdpPattern except;\r
-               public RdpPattern Except {\r
-                       get { return except; }\r
-                       set { except = value; }\r
-               }\r
-\r
-               public override RelaxngPatternType PatternType {\r
-                       get { return RelaxngPatternType.DataExcept; }\r
-               }\r
-\r
-               public override RdpContentType ContentType {\r
-                       get {\r
-                               RdpContentType c = except.ContentType; // conformance required for except pattern.\r
-                               return RdpContentType.Simple;\r
-                       }\r
-               }\r
-\r
-               internal override RdpPattern ReduceEmptyAndNotAllowed (ref bool result, Hashtable visited)\r
-               {\r
-                       if (visited.Contains (this))\r
-                               return this;\r
-                       visited.Add (this, this);\r
-\r
-                       if (except.PatternType == RelaxngPatternType.NotAllowed) {\r
-                               result = true;\r
-                               return new RdpData (this.Datatype);\r
-                       } else {\r
-                               except = except.ReduceEmptyAndNotAllowed (ref result, visited);\r
-                               return this;\r
-                       }\r
-               }\r
-\r
-               public override RdpPattern TextDeriv (string s, XmlReader reader)\r
-               {\r
-                       if (Datatype.IsAllowed (s, reader) && !except.TextDeriv (s, reader).Nullable)\r
-                               return RdpEmpty.Instance;\r
-                       else\r
-                               return RdpNotAllowed.Instance;\r
-               }\r
-\r
-               internal override void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept)\r
-               {\r
-                       this.except.CheckConstraints (attribute, oneOrMore, oneOrMoreGroup, oneOrMoreInterleave, list, true);\r
-               }\r
-\r
-               internal override bool ContainsText()\r
-               {\r
-                       return except.ContainsText ();\r
-               }\r
-       }\r
-\r
-       // Value\r
-       public class RdpValue : RdpPattern\r
-       {\r
-               public RdpValue (RdpDatatype dt, string value)\r
-               {\r
-                       this.dt = dt;\r
-                       this.value = value;\r
-               }\r
-\r
-               RdpDatatype dt;\r
-               public RdpDatatype Datatype {\r
-                       get { return dt; }\r
-               }\r
-\r
-               string value;\r
-               public string Value {\r
-                       get { return value; }\r
-               }\r
-\r
-               // This is not written in James Clark's derivative algorithm\r
-               // ( http://www.thaiopensource.com/relaxng/derivative.html ),\r
-               // but it looks required.\r
-               public override bool Nullable {\r
-                       get {\r
-                               if (dt.NamespaceURI.Length == 0 && value.Length == 0)\r
-                                       return true;\r
-                               return false; \r
-                       }\r
-               }\r
-\r
-               public override RelaxngPatternType PatternType {\r
-                       get { return RelaxngPatternType.Value; }\r
-               }\r
-\r
-               public override RdpContentType ContentType {\r
-                       get { return RdpContentType.Simple; }\r
-               }\r
-\r
-               public override void GetLabels (LabelList elements, LabelList attributes, bool collectNameClass)\r
-               {\r
-                       // do nothing\r
-               }\r
-\r
-               public override RdpPattern TextDeriv (string s, XmlReader reader)\r
-               {\r
-                       if (dt.IsTypeEqual (value, s, reader))\r
-                               return RdpEmpty.Instance;\r
-                       else\r
-                               return RdpNotAllowed.Instance;\r
-               }\r
-\r
-               internal override void MarkReachableDefs () \r
-               {\r
-                       // do nothing\r
-               }\r
-\r
-               internal override void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept) \r
-               {\r
-                       // nothing to be checked\r
-               }\r
-\r
-               internal override bool ContainsText()\r
-               {\r
-                       return false;\r
-               }\r
-       }\r
-\r
-       // Attribute\r
-       public class RdpAttribute : RdpPattern\r
-       {\r
-               public RdpAttribute (RdpNameClass nameClass, RdpPattern p)\r
-               {\r
-                       this.nameClass = nameClass;\r
-                       this.children = p;\r
-               }\r
-\r
-               RdpNameClass nameClass;\r
-               public RdpNameClass NameClass {\r
-                       get { return nameClass; }\r
-               }\r
-\r
-               RdpPattern children;\r
-               public RdpPattern Children {\r
-                       get { return children; }\r
-                       set { children = value; }\r
-               }\r
-\r
-               public override bool Nullable {\r
-                       get { return false; }\r
-               }\r
-\r
-               public override RelaxngPatternType PatternType {\r
-                       get { return RelaxngPatternType.Attribute; }\r
-               }\r
-\r
-               public override RdpContentType ContentType {\r
-                       get { return RdpContentType.Empty; }\r
-               }\r
-\r
-               public override void GetLabels (LabelList elements, LabelList attributes, bool collectNameClass)\r
-               {\r
-                       if (attributes != null) {\r
-                               if (collectNameClass)\r
-                                       attributes [NameClass] = NameClass;\r
-                               else\r
-                                       AddNameLabel (attributes, NameClass);\r
-                       }\r
-               }\r
-\r
-               bool isExpanded;\r
-               internal override RdpPattern ExpandRef (Hashtable defs)\r
-               {\r
-                       if (!isExpanded) {\r
-                               isExpanded = true;\r
-                               children = children.ExpandRef (defs);\r
-                       }\r
-                       return this;\r
-               }\r
-\r
-               internal override RdpPattern ReduceEmptyAndNotAllowed (ref bool result, Hashtable visited)\r
-               {\r
-                       if (visited.Contains (this))\r
-                               return this;\r
-                       visited.Add (this, this);\r
-\r
-                       if (children.PatternType == RelaxngPatternType.NotAllowed) {\r
-                               result = true;\r
-                               return RdpNotAllowed.Instance;\r
-                       } else {\r
-                               children = children.ReduceEmptyAndNotAllowed (ref result, visited);\r
-                               return this;\r
-                       }\r
-               }\r
-\r
-               // attDeriv cx (Attribute nc p) (AttributeNode qn s) =\r
-               //  if contains nc qn && valueMatch cx p s then Empty else NotAllowed\r
-               public override RdpPattern AttDeriv (string name, string ns, string value, XmlReader reader)\r
-               {\r
-                       // If value is null, then does not check ValueMatch.\r
-#if UseStatic\r
-                       if (RdpUtil.Contains (this.nameClass, att.QName)\r
-                               && (value == null || RdpUtil.ValueMatch (ctx, this.children, att.Value)))\r
-                               return RdpEmpty.Instance;\r
-                       else\r
-                               return RdpNotAllowed.Instance;\r
-#else\r
-                       if (nameClass.Contains (name, ns) &&\r
-                               (value == null || children.ValueMatch (value, reader)))\r
-                               return RdpEmpty.Instance;\r
-                       else\r
-                               return RdpNotAllowed.Instance;\r
-#endif\r
-               }\r
-\r
-               // startTagCloseDeriv (Attribute _ _) = NotAllowed\r
-               public override RdpPattern StartTagCloseDeriv ()\r
-               {\r
-                       return RdpNotAllowed.Instance;\r
-               }\r
-\r
-               internal override void MarkReachableDefs () \r
-               {\r
-                       children.MarkReachableDefs ();\r
-               }\r
-\r
-               internal override void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept) \r
-               {\r
-                       // 7.1.1 and 7.1.2\r
-                       if (attribute || oneOrMoreGroup || oneOrMoreInterleave || list || dataExcept)\r
-                               throw new RelaxngException ("Not allowed attribute occurence was specified in the pattern.");\r
-\r
-                       // latter part of 7.3\r
-                       if (!oneOrMore && NameClass.HasInfiniteName)\r
-                               throw new RelaxngException ("Attributes that has an infinite name class must be repeatable.");\r
-\r
-                       this.Children.CheckConstraints (true, oneOrMore, false, false, false, false);\r
-               }\r
-\r
-               internal override bool ContainsText()\r
-               {\r
-                       // This method is to detect text pattern inside interleave child.\r
-                       // return children.ContainsText ();\r
-                       return false;\r
-               }\r
-       }\r
-\r
-       // Element\r
-       public class RdpElement : RdpPattern\r
-       {\r
-               public RdpElement (RdpNameClass nameClass, RdpPattern p)\r
-               {\r
-                       this.nameClass = nameClass;\r
-                       this.children = p;\r
-               }\r
-\r
-               RdpNameClass nameClass;\r
-               public RdpNameClass NameClass {\r
-                       get { return nameClass; }\r
-               }\r
-\r
-               RdpPattern children;\r
-               public RdpPattern Children {\r
-                       get { return children; }\r
-                       set { children = value; }\r
-               }\r
-\r
-               public override bool Nullable {\r
-                       get { return false; }\r
-               }\r
-\r
-               public override RelaxngPatternType PatternType {\r
-                       get { return RelaxngPatternType.Element; }\r
-               }\r
-\r
-               bool contentTypeCheckDone;\r
-               public override RdpContentType ContentType {\r
-                       get {\r
-                               if (!contentTypeCheckDone) {\r
-                                       contentTypeCheckDone = true;\r
-                                       RdpContentType ct = children.ContentType; // conformance required.\r
-                               }\r
-                               return RdpContentType.Complex;\r
-                       }\r
-               }\r
-\r
-               public override void GetLabels (LabelList elements, LabelList attributes, bool collectNameClass)\r
-               {\r
-                       if (elements != null) {\r
-                               if (collectNameClass)\r
-                                       elements [NameClass] = NameClass;\r
-                               else\r
-                                       AddNameLabel (elements, NameClass);\r
-                       }\r
-               }\r
-\r
-\r
-               bool isExpanded;\r
-               short expanding; // FIXME: It is totally not required, but there is\r
-               // some bugs in simplification and without it it causes infinite loop.\r
-               internal override RdpPattern ExpandRef (Hashtable defs)\r
-               {\r
-                       if (!isExpanded) {\r
-                               isExpanded = true;\r
-                               if (expanding == 100)\r
-                                       throw new RelaxngException (String.Format ("Invalid recursion was found. Name is {0}", nameClass));\r
-                               expanding++;\r
-                               children = children.ExpandRef (defs);\r
-                               expanding--;\r
-                       }\r
-                       return this;\r
-               }\r
-\r
-               internal override RdpPattern ReduceEmptyAndNotAllowed (ref bool result, Hashtable visited)\r
-               {\r
-                       if (visited.Contains (this))\r
-                               return this;\r
-                       visited.Add (this, this);\r
-\r
-                       children = children.ReduceEmptyAndNotAllowed (ref result, visited);\r
-                       return this;\r
-               }\r
-\r
-               public override RdpPattern StartTagOpenDeriv (string name, string ns)\r
-               {\r
-#if UseStatic\r
-                       if (RdpUtil.Contains (this.nameClass, qname))\r
-                               return RdpUtil.After (this.Children, RdpEmpty.Instance);\r
-                       else\r
-                               return RdpNotAllowed.Instance;\r
-#else\r
-                       return nameClass.Contains (name, ns) ?\r
-                               children.After (RdpEmpty.Instance) :\r
-                               RdpNotAllowed.Instance;\r
-#endif\r
-               }\r
-\r
-               internal override void MarkReachableDefs () \r
-               {\r
-                       children.MarkReachableDefs ();\r
-               }\r
-\r
-               bool constraintsChecked;\r
-               internal override void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept) \r
-               {\r
-                       if (constraintsChecked)\r
-                               return;\r
-                       constraintsChecked = true;\r
-                       if (attribute || list || dataExcept)\r
-                               throw new RelaxngException ("Not allowed element occurence was specified in the pattern.");\r
-                       this.Children.CheckConstraints (false, oneOrMore, oneOrMoreGroup, oneOrMoreInterleave, false, false);\r
-               }\r
-\r
-               internal override bool ContainsText()\r
-               {\r
-                       return children.ContainsText ();\r
-               }\r
-       }\r
-\r
-       // After\r
-       public class RdpAfter : RdpAbstractBinary\r
-       {\r
-               public RdpAfter (RdpPattern l, RdpPattern r) : base (l, r)\r
-               {\r
-               }\r
-\r
-               public override bool Nullable {\r
-                       get { return false; }\r
-               }\r
-\r
-               public override void GetLabels (LabelList elements, LabelList attributes, bool collectNameClass)\r
-               {\r
-                       LValue.GetLabels (elements, attributes, collectNameClass);\r
-               }\r
-\r
-               public override RdpPattern TextDeriv (string s, XmlReader reader)\r
-               {\r
-                       return LValue.TextDeriv (s, reader).After (RValue);\r
-               }\r
-\r
-               // startTagOpenDeriv (After p1 p2) qn =\r
-               //   applyAfter (flip after p2) (startTagOpenDeriv p1 qn)\r
-               public override RdpPattern StartTagOpenDeriv (string name, string ns)\r
-               {\r
-                       RdpPattern handled = LValue.StartTagOpenDeriv (name, ns);\r
-                       RdpFlip f = new RdpFlip (new RdpBinaryFunction (RdpUtil.After), RValue);\r
-                       return handled.ApplyAfter (new RdpApplyAfterHandler (\r
-                               f.Apply));\r
-               }\r
-\r
-               public override RdpPattern ApplyAfter (RdpApplyAfterHandler handler)\r
-               {\r
-                       return LValue.After (handler (RValue));\r
-               }\r
-\r
-               // attDeriv cx (After p1 p2) att =\r
-               //  after (attDeriv cx p1 att) p2\r
-               public override RdpPattern AttDeriv (string name, string ns, string value, XmlReader reader)\r
-               {\r
-                       return LValue.AttDeriv (name, ns, value, reader).After (RValue);\r
-               }\r
-\r
-               public override RdpPattern StartTagCloseDeriv ()\r
-               {\r
-                       return LValue.StartTagCloseDeriv ().After (RValue);\r
-               }\r
-\r
-               public override RdpPattern EndTagDeriv ()\r
-               {\r
-                       return LValue.Nullable ? RValue : RdpNotAllowed.Instance;\r
-               }\r
-\r
-               public override RelaxngPatternType PatternType {\r
-                       get { return RelaxngPatternType.After; }\r
-               }\r
-\r
-               internal override void MarkReachableDefs () \r
-               {\r
-                       throw new InvalidOperationException ();\r
-               }\r
-\r
-               internal override void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept) \r
-               {\r
-                       throw new InvalidOperationException ();\r
-               }\r
-\r
-               internal override bool ContainsText ()\r
-               {\r
-                       throw new InvalidOperationException ();\r
-               }\r
-       }\r
-}\r
-\r
+                               return isNullable;
+                       }
+               }
+
+               internal override bool IsTextValueDependent {
+                       get { return LValue.IsTextValueDependent || RValue.IsTextValueDependent; }
+               }
+
+               internal override bool IsContextDependent {
+                       get { return LValue.IsContextDependent || RValue.IsContextDependent; }
+               }
+
+               public override void GetLabels (LabelList elements, LabelList attributes, bool collectNameClass)
+               {
+                       LValue.GetLabels (elements, attributes, collectNameClass);
+                       RValue.GetLabels (elements, attributes, collectNameClass);
+               }
+
+               internal override RdpPattern ReduceEmptyAndNotAllowed (ref bool result, Hashtable visited)
+               {
+                       if (visited.Contains (this))
+                               return this;
+                       visited.Add (this, this);
+
+                       if (LValue.PatternType == RelaxngPatternType.NotAllowed ||
+                               RValue.PatternType == RelaxngPatternType.NotAllowed) {
+                               result = true;
+                               return RdpNotAllowed.Instance;
+                       } else {
+                               LValue = LValue.ReduceEmptyAndNotAllowed (ref result, visited);
+                               RValue = RValue.ReduceEmptyAndNotAllowed (ref result, visited);
+                               return this;
+                       }
+               }
+
+               public override RdpPattern TextDeriv (string s, XmlReader reader)
+               {
+                       return LValue.TextDeriv (s, reader).Interleave (RValue)
+                               .Choice (LValue.Interleave (RValue.TextDeriv (s, reader)));
+               }
+
+               internal override RdpPattern TextDeriv (string s, XmlReader reader, MemoizationStore memo)
+               {
+                       return memo.TextDeriv (LValue, s, reader).Interleave (RValue)
+                               .Choice (LValue.Interleave (memo.TextDeriv (RValue, s, reader)));
+               }
+
+               internal override RdpPattern EmptyTextDeriv (MemoizationStore memo)
+               {
+                       return memo.EmptyTextDeriv (LValue).Interleave (RValue)
+                               .Choice (LValue.Interleave (memo.EmptyTextDeriv (RValue)));
+               }
+
+               internal override RdpPattern TextOnlyDeriv ()
+               {
+                       return LValue.TextOnlyDeriv ().Interleave (
+                               RValue.TextOnlyDeriv ());
+               }
+
+               internal override RdpPattern TextOnlyDeriv (MemoizationStore memo)
+               {
+                       return memo.TextOnlyDeriv (LValue).Interleave (
+                               memo.TextOnlyDeriv (RValue));
+               }
+
+               internal override RdpPattern MixedTextDeriv ()
+               {
+                       return LValue.MixedTextDeriv ().Interleave (RValue).Choice (
+                               LValue.Interleave (RValue.MixedTextDeriv ()));
+               }
+
+               internal override RdpPattern MixedTextDeriv (MemoizationStore memo)
+               {
+                       return memo.MixedTextDeriv (LValue).Interleave (RValue).Choice (
+                               LValue.Interleave (memo.MixedTextDeriv (RValue)));
+               }
+
+               // => choice (applyAfter (flip interleave p2) (startTagOpenDeriv p1 qn)) (applyAfter (interleave p1) (startTagOpenDeriv p2 qn)
+               // => p1.startTagOpenDeriv(qn).applyAfter (flip interleave p2).choice (p2.startTagOpenDeriv(qn).applyAfter (interleave p1) )
+               public override RdpPattern StartTagOpenDeriv (string name, string ns)
+               {
+                       RdpPattern handledL = LValue.StartTagOpenDeriv (name, ns);
+                       RdpPattern handledR = RValue.StartTagOpenDeriv (name, ns);
+                       RdpFlip flipL = MakeFlip (RdpUtil.InterleaveFunction, RValue);
+                       RdpPattern choiceL = handledL.ApplyAfter (new RdpApplyAfterHandler (flipL.Apply));
+                       RdpPattern choiceR = handledR.ApplyAfter (new RdpApplyAfterHandler (LValue.Interleave));
+                       return choiceL.Choice (choiceR);
+               }
+
+               internal override RdpPattern StartTagOpenDeriv (string name, string ns, MemoizationStore memo)
+               {
+                       RdpPattern handledL = memo.StartTagOpenDeriv (LValue, name, ns);
+                       RdpPattern handledR = memo.StartTagOpenDeriv (RValue, name, ns);
+                       RdpFlip flipL = MakeFlip (RdpUtil.InterleaveFunction, RValue);
+                       RdpPattern choiceL = handledL.ApplyAfter (new RdpApplyAfterHandler (flipL.Apply));
+                       RdpPattern choiceR = handledR.ApplyAfter (new RdpApplyAfterHandler (LValue.Interleave));
+                       return choiceL.Choice (choiceR);
+               }
+
+               // attDeriv cx (Interleave p1 p2) att =
+               //  choice (interleave (attDeriv cx p1 att) p2)
+               //         (interleave p1 (attDeriv cx p2 att))
+               public override RdpPattern AttDeriv (string name, string ns, string value, XmlReader reader)
+               {
+                       return LValue.AttDeriv (name, ns, value, reader)
+                               .Interleave (RValue)
+                               .Choice (LValue.Interleave (
+                                       RValue.AttDeriv (name, ns, value, reader)));
+               }
+
+               public override RdpPattern StartAttDeriv (string name, string ns)
+               {
+                       RdpPattern handledL = LValue.StartAttDeriv (name, ns);
+                       RdpPattern handledR = RValue.StartAttDeriv (name, ns);
+                       RdpFlip flipL = MakeFlip (RdpUtil.InterleaveFunction, RValue);
+                       RdpPattern choiceL = handledL.ApplyAfter (new RdpApplyAfterHandler (flipL.Apply));
+                       RdpPattern choiceR = handledR.ApplyAfter (new RdpApplyAfterHandler (LValue.Interleave));
+                       return choiceL.Choice (choiceR);
+               }
+
+               internal override RdpPattern StartAttDeriv (string name, string ns, MemoizationStore memo)
+               {
+                       RdpPattern handledL = memo.StartAttDeriv (LValue, name, ns);
+                       RdpPattern handledR = memo.StartAttDeriv (RValue, name, ns);
+                       RdpFlip flipL = MakeFlip (RdpUtil.InterleaveFunction, RValue);
+                       RdpPattern choiceL = handledL.ApplyAfter (new RdpApplyAfterHandler (flipL.Apply));
+                       RdpPattern choiceR = handledR.ApplyAfter (new RdpApplyAfterHandler (LValue.Interleave));
+                       return choiceL.Choice (choiceR);
+               }
+
+               // startTagCloseDeriv (Interleave p1 p2) =
+               //  interleave (startTagCloseDeriv p1) (startTagCloseDeriv p2)
+               public override RdpPattern StartTagCloseDeriv ()
+               {
+                       return LValue.StartTagCloseDeriv ()
+                               .Interleave (RValue.StartTagCloseDeriv ());
+               }
+
+               internal override RdpPattern StartTagCloseDeriv (MemoizationStore memo)
+               {
+                       return memo.StartTagCloseDeriv (LValue)
+                               .Interleave (memo.StartTagCloseDeriv (RValue));
+               }
+
+               public override RelaxngPatternType PatternType {
+                       get { return RelaxngPatternType.Interleave; }
+               }
+
+               internal override void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept)
+               {
+                       if (list)
+                               throw new RelaxngException ("interleave is not allowed under a list.");
+                       if (dataExcept)
+                               throw new RelaxngException ("interleave is not allowed under except of a data.");
+
+                       // 7.1
+                       LValue.CheckConstraints (attribute, oneOrMore, oneOrMoreGroup, oneOrMore, list, dataExcept);
+                       RValue.CheckConstraints (attribute, oneOrMore, oneOrMoreGroup, oneOrMore, list, dataExcept);
+
+                       // unique name analysis - 7.3 and part of 7.4
+                       CheckNameOverlap (true);
+
+                       // (2) text/text prohibited
+                       if (LValue.ContainsText () && RValue.ContainsText ())
+                               throw new RelaxngException ("Both branches of the interleave contains a text pattern.");
+               }
+       }
+
+       // Group
+       public class RdpGroup : RdpAbstractBinary
+       {
+               public RdpGroup (RdpPattern l, RdpPattern r) : base (l, r)
+               {
+               }
+
+               public override bool Nullable {
+                       get {
+                               if (!nullableComputed) {
+                                       isNullable =
+                                               LValue.Nullable && RValue.Nullable;
+                                       nullableComputed = true;
+                               }
+                               return isNullable;
+                       }
+               }
+
+               internal override bool IsTextValueDependent {
+                       get { return LValue.IsTextValueDependent || (LValue.Nullable ? RValue.IsTextValueDependent : false); }
+               }
+
+               internal override bool IsContextDependent {
+                       get { return LValue.IsContextDependent || (LValue.Nullable ? RValue.IsContextDependent : false); }
+               }
+
+               public override void GetLabels (LabelList elements, LabelList attributes, bool collectNameClass)
+               {
+                       LValue.GetLabels (elements, attributes, collectNameClass);
+                       if (LValue.Nullable)
+                               RValue.GetLabels (elements, attributes, collectNameClass);
+                       else
+                               RValue.GetLabels (null, attributes, collectNameClass);
+               }
+
+               public override RdpPattern TextDeriv (string s, XmlReader reader)
+               {
+                       RdpPattern p = LValue.TextDeriv (s, reader);
+                       p = (p.PatternType == RelaxngPatternType.NotAllowed) ?
+                               p : p.Group (RValue);
+                       return LValue.Nullable ?
+                               p.Choice (RValue.TextDeriv (s, reader)) : p;
+               }
+
+               internal override RdpPattern TextDeriv (string s, XmlReader reader, MemoizationStore memo)
+               {
+                       RdpPattern p = memo.TextDeriv (LValue, s, reader);
+                       p = (p.PatternType == RelaxngPatternType.NotAllowed) ?
+                               p : p.Group (RValue);
+                       return LValue.Nullable ?
+                               p.Choice (memo.TextDeriv (RValue, s, reader)) : p;
+               }
+
+               internal override RdpPattern EmptyTextDeriv (MemoizationStore memo)
+               {
+                       RdpPattern p = memo.EmptyTextDeriv (LValue);
+                       p = p.PatternType == RelaxngPatternType.NotAllowed ?
+                               p : p.Group (RValue);
+                       return LValue.Nullable ?
+                               p.Choice (memo.EmptyTextDeriv (RValue)) : p;
+               }
+
+               internal override RdpPattern TextOnlyDeriv ()
+               {
+                       RdpPattern p = LValue.TextOnlyDeriv ();
+                       return p.PatternType == RelaxngPatternType.NotAllowed ?
+                               p : p.Group (RValue.TextOnlyDeriv ());
+               }
+
+               internal override RdpPattern TextOnlyDeriv (MemoizationStore memo)
+               {
+                       RdpPattern p = memo.TextOnlyDeriv (LValue);
+                       return p.PatternType == RelaxngPatternType.NotAllowed ?
+                               p : p.Group (memo.TextOnlyDeriv (RValue));
+               }
+
+               internal override RdpPattern MixedTextDeriv ()
+               {
+                       RdpPattern p = LValue.MixedTextDeriv ().Group (RValue);
+                       return LValue.Nullable ?
+                               p.Choice (RValue.MixedTextDeriv ()) : p;
+               }
+
+               internal override RdpPattern MixedTextDeriv (MemoizationStore memo)
+               {
+                       RdpPattern p = memo.MixedTextDeriv (LValue).Group (RValue);
+                       return LValue.Nullable ?
+                               p.Choice (memo.MixedTextDeriv (RValue)) : p;
+               }
+
+               // startTagOpenDeriv (Group p1 p2) qn =
+               //  let x = applyAfter (flip group p2) (startTagOpenDeriv p1 qn)
+               //  in if nullable p1 then
+               //       choice x (startTagOpenDeriv p2 qn)
+               //     else
+               //       x
+               public override RdpPattern StartTagOpenDeriv (string name, string ns)
+               {
+                       RdpPattern handled = LValue.StartTagOpenDeriv (name, ns);
+                       RdpFlip f = MakeFlip (RdpUtil.GroupFunction, RValue);
+                       RdpPattern x = handled.ApplyAfter (new RdpApplyAfterHandler (f.Apply));
+                       if (LValue.Nullable)
+                               return x.Choice (RValue.StartTagOpenDeriv (name, ns));
+                       else
+                               return x;
+               }
+
+               internal override RdpPattern StartTagOpenDeriv (string name, string ns, MemoizationStore memo)
+               {
+                       RdpPattern handled = memo.StartTagOpenDeriv (LValue, name, ns);
+                       RdpFlip f = MakeFlip (RdpUtil.GroupFunction, RValue);
+                       RdpPattern x = handled.ApplyAfter (new RdpApplyAfterHandler (f.Apply));
+                       if (LValue.Nullable)
+                               return x.Choice (memo.StartTagOpenDeriv (RValue, name, ns));
+                       else
+                               return x;
+               }
+
+               // attDeriv cx (Group p1 p2) att =
+               //  choice (group (attDeriv cx p1 att) p2)
+               //         (group p1 (attDeriv cx p2 att))
+               public override RdpPattern AttDeriv (string name, string ns, string value, XmlReader reader)
+               {
+                       return LValue.AttDeriv (name, ns, value, reader).Group (RValue)
+                               .Choice (LValue.Group (
+                                       RValue.AttDeriv (name, ns, value, reader)));
+               }
+
+               // startAttDeriv (group p1 p2) == startAttDeriv (interleave p1 p2)
+               public override RdpPattern StartAttDeriv (string name, string ns)
+               {
+                       RdpPattern handledL = LValue.StartAttDeriv (name, ns);
+                       RdpPattern handledR = RValue.StartAttDeriv (name, ns);
+                       RdpFlip flipL = MakeFlip (RdpUtil.GroupFunction, RValue);
+                       RdpPattern choiceL = handledL.ApplyAfter (new RdpApplyAfterHandler (flipL.Apply));
+                       RdpPattern choiceR = handledR.ApplyAfter (new RdpApplyAfterHandler (LValue.Group));
+                       return choiceL.Choice (choiceR);
+               }
+
+               internal override RdpPattern StartAttDeriv (string name, string ns, MemoizationStore memo)
+               {
+                       RdpPattern handledL = memo.StartAttDeriv (LValue, name, ns);
+                       RdpPattern handledR = memo.StartAttDeriv (RValue, name, ns);
+                       RdpFlip flipL = MakeFlip (RdpUtil.GroupFunction, RValue);
+                       RdpPattern choiceL = handledL.ApplyAfter (new RdpApplyAfterHandler (flipL.Apply));
+                       RdpPattern choiceR = handledR.ApplyAfter (new RdpApplyAfterHandler (LValue.Group));
+                       return choiceL.Choice (choiceR);
+               }
+
+               // startTagCloseDeriv (Group p1 p2) =
+               //  group (startTagCloseDeriv p1) (startTagCloseDeriv p2)
+               public override RdpPattern StartTagCloseDeriv ()
+               {
+                       RdpPattern p = LValue.StartTagCloseDeriv ();
+                       return p.PatternType == RelaxngPatternType.NotAllowed ?
+                               p : p.Group (RValue.StartTagCloseDeriv ());
+               }
+
+               internal override RdpPattern StartTagCloseDeriv (MemoizationStore memo)
+               {
+                       RdpPattern p = memo.StartTagCloseDeriv (LValue);
+                       return p.PatternType == RelaxngPatternType.NotAllowed ?
+                               p : p.Group (memo.StartTagCloseDeriv (RValue));
+               }
+
+               public override RelaxngPatternType PatternType {
+                       get { return RelaxngPatternType.Group; }
+               }
+
+               internal override void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept)
+               {
+                       if (dataExcept)
+                               throw new RelaxngException ("interleave is not allowed under except of a data.");
+
+                       LValue.CheckConstraints (attribute, oneOrMore, oneOrMore, oneOrMoreInterleave, list, dataExcept);
+                       RValue.CheckConstraints (attribute, oneOrMore, oneOrMore, oneOrMoreInterleave, list, dataExcept);
+
+                       // 7.3
+                       CheckNameOverlap (false);
+               }
+       }
+
+       public abstract class RdpAbstractSingleContent : RdpPattern
+       {
+               RdpPattern child;
+               bool isExpanded;
+
+               internal override RdpPattern ExpandRef (Hashtable defs)
+               {
+                       if (!isExpanded)
+                               child = child.ExpandRef (defs);
+                       return this;
+               }
+
+               public RdpAbstractSingleContent (RdpPattern p)
+               {
+                       this.child = p;
+               }
+
+               public RdpPattern Child {
+                       get { return child; }
+                       set { child = value; }
+               }
+
+               internal override void MarkReachableDefs () 
+               {
+                       child.MarkReachableDefs ();
+               }
+
+               internal override bool ContainsText()
+               {
+                       return child.ContainsText ();
+               }
+       }
+
+       // OneOrMore
+       public class RdpOneOrMore : RdpAbstractSingleContent
+       {
+               public RdpOneOrMore (RdpPattern p) : base (p)
+               {
+               }
+
+               public override RelaxngPatternType PatternType {
+                       get { return RelaxngPatternType.OneOrMore; }
+               }
+
+               public override RdpContentType ContentType {
+                       get {
+                               if (Child.ContentType == RdpContentType.Simple)
+                                       throw new RelaxngException ("Invalid content type was found.");
+                               return Child.ContentType;
+                       }
+               }
+
+               public override bool Nullable {
+                       get { return Child.Nullable; }
+               }
+
+               internal override bool IsTextValueDependent {
+                       get { return Child.IsTextValueDependent; }
+               }
+
+               internal override bool IsContextDependent {
+                       get { return Child.IsContextDependent; }
+               }
+
+               public override void GetLabels (LabelList elements, LabelList attributes, bool collectNameClass)
+               {
+                       Child.GetLabels (elements, attributes, collectNameClass);
+               }
+
+               internal override RdpPattern ReduceEmptyAndNotAllowed (ref bool result, Hashtable visited)
+               {
+                       if (visited.Contains (this))
+                               return this;
+                       visited.Add (this, this);
+
+                       if (Child.PatternType == RelaxngPatternType.NotAllowed) {
+                               result = true;
+                               return RdpNotAllowed.Instance;
+                       } else if (Child.PatternType == RelaxngPatternType.Empty)
+                               return RdpEmpty.Instance;
+                       else {
+                               Child = Child.ReduceEmptyAndNotAllowed (ref result, visited);
+                               return this;
+                       }
+               }
+
+               public override RdpPattern TextDeriv (string s, XmlReader reader)
+               {
+                       RdpPattern p = Child.TextDeriv (s, reader);
+                       return p.PatternType == RelaxngPatternType.NotAllowed ?
+                               p : p.Group (this.Choice (RdpEmpty.Instance));
+               }
+
+               internal override RdpPattern TextDeriv (string s, XmlReader reader, MemoizationStore memo)
+               {
+                       RdpPattern p = memo.TextDeriv (Child, s, reader);
+                       return p.PatternType == RelaxngPatternType.NotAllowed ?
+                               p : p.Group (this.Choice (RdpEmpty.Instance));
+               }
+
+               internal override RdpPattern EmptyTextDeriv (MemoizationStore memo)
+               {
+                       RdpPattern p = memo.EmptyTextDeriv (Child);
+                       return p.PatternType == RelaxngPatternType.NotAllowed ?
+                               p : p.Group (this.Choice (RdpEmpty.Instance));
+               }
+
+               internal override RdpPattern TextOnlyDeriv ()
+               {
+                       return Child.TextOnlyDeriv ().OneOrMore ();
+               }
+
+               internal override RdpPattern TextOnlyDeriv (MemoizationStore memo)
+               {
+                       return memo.TextOnlyDeriv (Child).OneOrMore ();
+               }
+
+               internal override RdpPattern MixedTextDeriv ()
+               {
+                       RdpPattern p = Child.MixedTextDeriv ();
+                       return p.PatternType == RelaxngPatternType.NotAllowed ?
+                               p : p.Group (this.Choice (RdpEmpty.Instance));
+               }
+
+               internal override RdpPattern MixedTextDeriv (MemoizationStore memo)
+               {
+                       RdpPattern p = memo.MixedTextDeriv (Child);
+                       return p.PatternType == RelaxngPatternType.NotAllowed ?
+                               p : p.Group (this.Choice (RdpEmpty.Instance));
+               }
+
+               // attDeriv cx (OneOrMore p) att =
+               //  group (attDeriv cx p att) (choice (OneOrMore p) Empty)
+               public override RdpPattern AttDeriv (string name, string ns, string value, XmlReader reader)
+               {
+                       RdpPattern p = Child.AttDeriv (name, ns, value, reader);
+                       return p.PatternType == RelaxngPatternType.NotAllowed ?
+                               p : p.Group (Choice (RdpEmpty.Instance));
+               }
+
+               // startTagOpenDeriv (OneOrMore p) qn =
+               //  applyAfter (flip group (choice (OneOrMore p) Empty))
+               //             (startTagOpenDeriv p qn)
+               public override RdpPattern StartTagOpenDeriv (string name, string ns)
+               {
+                       RdpPattern rest = RdpEmpty.Instance.Choice (Child.OneOrMore ());
+                       RdpPattern handled = Child.StartTagOpenDeriv (name, ns);
+                       RdpFlip f = MakeFlip (RdpUtil.GroupFunction, rest);
+                       return handled.ApplyAfter (new RdpApplyAfterHandler (f.Apply));
+               }
+
+               internal override RdpPattern StartTagOpenDeriv (string name, string ns, MemoizationStore memo)
+               {
+                       RdpPattern rest = RdpEmpty.Instance.Choice (Child.OneOrMore ());
+                       RdpPattern handled = memo.StartTagOpenDeriv (Child, name, ns);
+                       RdpFlip f = MakeFlip (RdpUtil.GroupFunction, rest);
+                       return handled.ApplyAfter (new RdpApplyAfterHandler (f.Apply));
+               }
+
+               public override RdpPattern StartAttDeriv (string name, string ns)
+               {
+                       RdpPattern rest = RdpEmpty.Instance.Choice (Child.OneOrMore ());
+                       RdpPattern handled = Child.StartAttDeriv (name, ns);
+                       RdpFlip f = MakeFlip (RdpUtil.GroupFunction, rest);
+                       return handled.ApplyAfter (new RdpApplyAfterHandler (f.Apply));
+               }
+
+               internal override RdpPattern StartAttDeriv (string name, string ns, MemoizationStore memo)
+               {
+                       RdpPattern rest = RdpEmpty.Instance.Choice (Child.OneOrMore ());
+                       RdpPattern handled = memo.StartAttDeriv (Child, name, ns);
+                       RdpFlip f = MakeFlip (RdpUtil.GroupFunction, rest);
+                       return handled.ApplyAfter (new RdpApplyAfterHandler (f.Apply));
+               }
+
+               // startTagCloseDeriv (OneOrMore p) =
+               //  oneOrMore (startTagCloseDeriv p)
+               public override RdpPattern StartTagCloseDeriv ()
+               {
+#if UseStatic
+                       return RdpUtil.OneOrMore (
+                               RdpUtil.StartTagCloseDeriv (children));
+#else
+                       return Child.StartTagCloseDeriv ().OneOrMore ();
+#endif
+               }
+
+               internal override RdpPattern StartTagCloseDeriv (MemoizationStore memo)
+               {
+                       return memo.StartTagCloseDeriv (Child).OneOrMore ();
+               }
+
+               internal override void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept)
+               {
+                       if (dataExcept)
+                               throw new RelaxngException ("oneOrMore is not allowed under except of a data.");
+                       this.Child.CheckConstraints (attribute, true, oneOrMoreGroup, oneOrMoreInterleave, list, dataExcept);
+               }
+       }
+
+       // List
+       public class RdpList : RdpAbstractSingleContent
+       {
+               public RdpList (RdpPattern p) : base (p)
+               {
+               }
+
+               internal override RdpPattern ReduceEmptyAndNotAllowed (ref bool result, Hashtable visited)
+               {
+                       if (visited.Contains (this))
+                               return this;
+                       visited.Add (this, this);
+
+                       if (Child.PatternType == RelaxngPatternType.NotAllowed) {
+                               result = true;
+                               return RdpNotAllowed.Instance;
+                       } else {
+                               Child = Child.ReduceEmptyAndNotAllowed (ref result, visited);
+                               return this;
+                       }
+               }
+
+               public override bool Nullable {
+                       get { return false; }
+               }
+
+               internal override bool IsTextValueDependent {
+                       get { return true; }
+               }
+
+               internal override bool IsContextDependent {
+                       get { return Child.IsContextDependent; }
+               }
+
+               public override RelaxngPatternType PatternType {
+                       get { return RelaxngPatternType.List; }
+               }
+
+               public override RdpContentType ContentType {
+                       get { return RdpContentType.Simple; }
+               }
+
+               public override void GetLabels (LabelList elements, LabelList attributes, bool collectNameClass)
+               {
+                       Child.GetLabels (elements, attributes, collectNameClass);
+               }
+
+               public override RdpPattern TextDeriv (string s, XmlReader reader)
+               {
+                       s = Util.NormalizeWhitespace (s);
+
+                       RdpPattern p = Child.ListDeriv (s.Split (RdpUtil.WhitespaceChars), 0, reader);                  
+                       if (p.Nullable)
+                               return RdpEmpty.Instance;
+                       else
+                               return RdpNotAllowed.Instance;
+               }
+
+               internal override void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept)
+               {
+                       if (list)
+                               throw new RelaxngException ("list is not allowed uner another list.");
+                       if (dataExcept)
+                               throw new RelaxngException ("list is not allowed under except of a data.");
+                       this.Child.CheckConstraints (attribute, oneOrMore, oneOrMoreGroup, oneOrMoreInterleave, true, dataExcept);
+               }
+       }
+
+       // Data
+       public class RdpData : RdpPattern
+       {
+               public RdpData (RdpDatatype dt)
+               {
+                       this.dt = dt;
+               }
+
+               RdpDatatype dt;
+               public RdpDatatype Datatype {
+                       get { return dt; }
+               }
+
+               public override bool Nullable {
+                       get { return false; }
+               }
+
+               internal override bool IsTextValueDependent {
+                       get { return true; }
+               }
+
+               internal override bool IsContextDependent {
+                       get { return dt.IsContextDependent; }
+               }
+
+               public override RelaxngPatternType PatternType {
+                       get { return RelaxngPatternType.Data; }
+               }
+
+               public override RdpContentType ContentType {
+                       get { return RdpContentType.Simple; }
+               }
+
+               public override void GetLabels (LabelList elements, LabelList attributes, bool collectNameClass)
+               {
+                       // do nothing.
+               }
+
+               public override RdpPattern TextDeriv (string s, XmlReader reader)
+               {
+                       if (dt.IsAllowed (s, reader))
+                               return RdpEmpty.Instance;
+                       else
+                               return RdpNotAllowed.Instance;
+               }
+
+               internal override void MarkReachableDefs () 
+               {
+                       // do nothing
+               }
+
+               internal override void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept)
+               {
+                       // do nothing
+               }
+
+               internal override bool ContainsText()
+               {
+                       return false;
+               }
+       }
+
+       // DataExcept
+       public class RdpDataExcept : RdpData
+       {
+               public RdpDataExcept (RdpDatatype dt, RdpPattern except)
+                       : base (dt)
+               {
+                       this.except = except;
+               }
+
+               RdpPattern except;
+               public RdpPattern Except {
+                       get { return except; }
+                       set { except = value; }
+               }
+
+               public override RelaxngPatternType PatternType {
+                       get { return RelaxngPatternType.DataExcept; }
+               }
+
+               public override RdpContentType ContentType {
+                       get {
+                               RdpContentType c = except.ContentType; // conformance required for except pattern.
+                               return RdpContentType.Simple;
+                       }
+               }
+
+               internal override RdpPattern ReduceEmptyAndNotAllowed (ref bool result, Hashtable visited)
+               {
+                       if (visited.Contains (this))
+                               return this;
+                       visited.Add (this, this);
+
+                       if (except.PatternType == RelaxngPatternType.NotAllowed) {
+                               result = true;
+                               return new RdpData (this.Datatype);
+                       } else {
+                               except = except.ReduceEmptyAndNotAllowed (ref result, visited);
+                               return this;
+                       }
+               }
+
+               public override RdpPattern TextDeriv (string s, XmlReader reader)
+               {
+                       if (Datatype.IsAllowed (s, reader) && !except.TextDeriv (s, reader).Nullable)
+                               return RdpEmpty.Instance;
+                       else
+                               return RdpNotAllowed.Instance;
+               }
+
+               internal override void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept)
+               {
+                       this.except.CheckConstraints (attribute, oneOrMore, oneOrMoreGroup, oneOrMoreInterleave, list, true);
+               }
+
+               internal override bool ContainsText()
+               {
+                       return except.ContainsText ();
+               }
+       }
+
+       // Value
+       public class RdpValue : RdpPattern
+       {
+               public RdpValue (RdpDatatype dt, string value)
+               {
+                       this.dt = dt;
+                       this.value = value;
+               }
+
+               RdpDatatype dt;
+               public RdpDatatype Datatype {
+                       get { return dt; }
+               }
+
+               string value;
+               public string Value {
+                       get { return value; }
+               }
+
+               public override bool Nullable {
+                       get { return false; }
+               }
+
+               internal override bool IsTextValueDependent {
+                       get { return true; }
+               }
+
+               internal override bool IsContextDependent {
+                       get { return dt.IsContextDependent; }
+               }
+
+               public override RelaxngPatternType PatternType {
+                       get { return RelaxngPatternType.Value; }
+               }
+
+               public override RdpContentType ContentType {
+                       get { return RdpContentType.Simple; }
+               }
+
+               public override void GetLabels (LabelList elements, LabelList attributes, bool collectNameClass)
+               {
+                       // do nothing
+               }
+
+               string cachedValue;
+               RdpPattern cachedPattern;
+
+               public override RdpPattern TextDeriv (string s, XmlReader reader)
+               {
+                       if (s == cachedValue && !IsContextDependent)
+                               return cachedPattern;
+                       cachedPattern = TextDerivCore (s, reader);
+                       cachedValue = s;
+                       return cachedPattern;
+               }
+
+               RdpPattern TextDerivCore (string s, XmlReader reader)
+               {
+                       if (dt.IsTypeEqual (value, s, reader))
+                               return RdpEmpty.Instance;
+                       else
+                               return RdpNotAllowed.Instance;
+               }
+
+               internal override void MarkReachableDefs () 
+               {
+                       // do nothing
+               }
+
+               internal override void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept) 
+               {
+                       // nothing to be checked
+               }
+
+               internal override bool ContainsText()
+               {
+                       return false;
+               }
+       }
+
+       // Attribute
+       public class RdpAttribute : RdpPattern
+       {
+               public RdpAttribute (RdpNameClass nameClass, RdpPattern p)
+               {
+                       this.nameClass = nameClass;
+                       this.children = p;
+               }
+
+               RdpNameClass nameClass;
+               public RdpNameClass NameClass {
+                       get { return nameClass; }
+               }
+
+               RdpPattern children;
+               public RdpPattern Children {
+                       get { return children; }
+                       set { children = value; }
+               }
+
+               public override bool Nullable {
+                       get { return false; }
+               }
+
+               internal override bool IsTextValueDependent {
+                       get { return false; }
+               }
+
+               internal override bool IsContextDependent {
+                       get { return false; }
+               }
+
+               public override RelaxngPatternType PatternType {
+                       get { return RelaxngPatternType.Attribute; }
+               }
+
+               public override RdpContentType ContentType {
+                       get { return RdpContentType.Empty; }
+               }
+
+               public override void GetLabels (LabelList elements, LabelList attributes, bool collectNameClass)
+               {
+                       if (attributes != null) {
+                               if (collectNameClass)
+                                       attributes [NameClass] = NameClass;
+                               else
+                                       AddNameLabel (attributes, NameClass);
+                       }
+               }
+
+               bool isExpanded;
+               internal override RdpPattern ExpandRef (Hashtable defs)
+               {
+                       if (!isExpanded) {
+                               isExpanded = true;
+                               children = children.ExpandRef (defs);
+                       }
+                       return this;
+               }
+
+               internal override RdpPattern ReduceEmptyAndNotAllowed (ref bool result, Hashtable visited)
+               {
+                       if (visited.Contains (this))
+                               return this;
+                       visited.Add (this, this);
+
+                       if (children.PatternType == RelaxngPatternType.NotAllowed) {
+                               result = true;
+                               return RdpNotAllowed.Instance;
+                       } else {
+                               children = children.ReduceEmptyAndNotAllowed (ref result, visited);
+                               return this;
+                       }
+               }
+
+               // attDeriv cx (Attribute nc p) (AttributeNode qn s) =
+               //  if contains nc qn && valueMatch cx p s then Empty else NotAllowed
+               public override RdpPattern AttDeriv (string name, string ns, string value, XmlReader reader)
+               {
+                       // If value is null, then does not check ValueMatch.
+#if UseStatic
+                       if (RdpUtil.Contains (this.nameClass, att.QName)
+                               && (value == null || RdpUtil.ValueMatch (ctx, this.children, att.Value)))
+                               return RdpEmpty.Instance;
+                       else
+                               return RdpNotAllowed.Instance;
+#else
+                       if (nameClass.Contains (name, ns) &&
+                               (value == null || children.ValueMatch (value, reader)))
+                               return RdpEmpty.Instance;
+                       else
+                               return RdpNotAllowed.Instance;
+#endif
+               }
+
+               public override RdpPattern StartAttDeriv (string name, string ns)
+               {
+                       return nameClass.Contains (name, ns) ?
+                               children.After (RdpEmpty.Instance) : RdpNotAllowed.Instance;
+               }
+
+               internal override RdpPattern StartAttDeriv (string name, string ns, MemoizationStore memo)
+               {
+                       return nameClass.Contains (name, ns) ?
+                               children.After (RdpEmpty.Instance) : RdpNotAllowed.Instance;
+               }
+
+               // startTagCloseDeriv (Attribute _ _) = NotAllowed
+               public override RdpPattern StartTagCloseDeriv ()
+               {
+                       return RdpNotAllowed.Instance;
+               }
+
+               internal override RdpPattern StartTagCloseDeriv (MemoizationStore memo)
+               {
+                       return RdpNotAllowed.Instance;
+               }
+
+               internal override void MarkReachableDefs () 
+               {
+                       children.MarkReachableDefs ();
+               }
+
+               internal override void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept) 
+               {
+                       // 7.1.1 and 7.1.2
+                       if (attribute || oneOrMoreGroup || oneOrMoreInterleave || list || dataExcept)
+                               throw new RelaxngException ("Not allowed attribute occurence was specified in the pattern.");
+
+                       // latter part of 7.3
+                       if (!oneOrMore && NameClass.HasInfiniteName)
+                               throw new RelaxngException ("Attributes that has an infinite name class must be repeatable.");
+
+                       this.Children.CheckConstraints (true, oneOrMore, false, false, false, false);
+               }
+
+               internal override bool ContainsText()
+               {
+                       // This method is to detect text pattern inside interleave child.
+                       // return children.ContainsText ();
+                       return false;
+               }
+       }
+
+       // Element
+       public class RdpElement : RdpPattern
+       {
+               public RdpElement (RdpNameClass nameClass, RdpPattern p)
+               {
+                       this.nameClass = nameClass;
+                       this.children = p;
+               }
+
+               RdpNameClass nameClass;
+               public RdpNameClass NameClass {
+                       get { return nameClass; }
+               }
+
+               RdpPattern children;
+               public RdpPattern Children {
+                       get { return children; }
+                       set { children = value; }
+               }
+
+               public override bool Nullable {
+                       get { return false; }
+               }
+
+               internal override bool IsTextValueDependent {
+                       get { return false; }
+               }
+
+               internal override bool IsContextDependent {
+                       get { return false; }
+               }
+
+               public override RelaxngPatternType PatternType {
+                       get { return RelaxngPatternType.Element; }
+               }
+
+               bool contentTypeCheckDone;
+               public override RdpContentType ContentType {
+                       get {
+                               if (!contentTypeCheckDone) {
+                                       contentTypeCheckDone = true;
+                                       RdpContentType ct = children.ContentType; // conformance required.
+                               }
+                               return RdpContentType.Complex;
+                       }
+               }
+
+               public override void GetLabels (LabelList elements, LabelList attributes, bool collectNameClass)
+               {
+                       if (elements != null) {
+                               if (collectNameClass)
+                                       elements [NameClass] = NameClass;
+                               else
+                                       AddNameLabel (elements, NameClass);
+                       }
+               }
+
+
+               bool isExpanded;
+               short expanding; // FIXME: It is totally not required, but there is
+               // some bugs in simplification and without it it causes infinite loop.
+               internal override RdpPattern ExpandRef (Hashtable defs)
+               {
+                       if (!isExpanded) {
+                               isExpanded = true;
+                               if (expanding == 100)
+                                       throw new RelaxngException (String.Format ("Invalid recursion was found. Name is {0}", nameClass));
+                               expanding++;
+                               children = children.ExpandRef (defs);
+                               expanding--;
+                       }
+                       return this;
+               }
+
+               internal override RdpPattern ReduceEmptyAndNotAllowed (ref bool result, Hashtable visited)
+               {
+                       if (visited.Contains (this))
+                               return this;
+                       visited.Add (this, this);
+
+                       children = children.ReduceEmptyAndNotAllowed (ref result, visited);
+                       return this;
+               }
+
+               internal override RdpPattern TextOnlyDeriv ()
+               {
+                       return RdpNotAllowed.Instance;
+               }
+
+               internal override RdpPattern TextOnlyDeriv (MemoizationStore memo)
+               {
+                       return RdpNotAllowed.Instance;
+               }
+
+               public override RdpPattern StartTagOpenDeriv (string name, string ns)
+               {
+#if UseStatic
+                       if (RdpUtil.Contains (this.nameClass, qname))
+                               return RdpUtil.After (this.Children, RdpEmpty.Instance);
+                       else
+                               return RdpNotAllowed.Instance;
+#else
+                       return nameClass.Contains (name, ns) ?
+                               children.After (RdpEmpty.Instance) :
+                               RdpNotAllowed.Instance;
+#endif
+               }
+
+               internal override RdpPattern StartTagOpenDeriv (string name, string ns, MemoizationStore memo)
+               {
+                       return nameClass.Contains (name, ns) ?
+                               children.After (RdpEmpty.Instance) :
+                               RdpNotAllowed.Instance;
+               }
+
+               internal override void MarkReachableDefs () 
+               {
+                       children.MarkReachableDefs ();
+               }
+
+               bool constraintsChecked;
+               internal override void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept) 
+               {
+                       if (constraintsChecked)
+                               return;
+                       constraintsChecked = true;
+                       if (attribute || list || dataExcept)
+                               throw new RelaxngException ("Not allowed element occurence was specified in the pattern.");
+                       this.Children.CheckConstraints (false, oneOrMore, oneOrMoreGroup, oneOrMoreInterleave, false, false);
+               }
+
+               internal override bool ContainsText()
+               {
+                       return children.ContainsText ();
+               }
+       }
+
+       // After
+       public class RdpAfter : RdpAbstractBinary
+       {
+               public RdpAfter (RdpPattern l, RdpPattern r) : base (l, r)
+               {
+               }
+
+               public override bool Nullable {
+                       get { return false; }
+               }
+
+               internal override bool IsTextValueDependent {
+                       get { return LValue.IsTextValueDependent; }
+               }
+
+               internal override bool IsContextDependent {
+                       get { return LValue.IsContextDependent; }
+               }
+
+               public override void GetLabels (LabelList elements, LabelList attributes, bool collectNameClass)
+               {
+                       LValue.GetLabels (elements, attributes, collectNameClass);
+               }
+
+               public override RdpPattern TextDeriv (string s, XmlReader reader)
+               {
+                       return LValue.TextDeriv (s, reader).After (RValue);
+               }
+
+               internal override RdpPattern TextDeriv (string s, XmlReader reader, MemoizationStore memo)
+               {
+                       return memo.TextDeriv (LValue, s, reader).After (RValue);
+               }
+
+               internal override RdpPattern EmptyTextDeriv (MemoizationStore memo)
+               {
+                       return memo.EmptyTextDeriv (LValue).After (RValue);
+               }
+
+               internal override RdpPattern TextOnlyDeriv ()
+               {
+                       return LValue.TextOnlyDeriv ().After (RValue);
+               }
+
+               internal override RdpPattern TextOnlyDeriv (MemoizationStore memo)
+               {
+                       return memo.TextOnlyDeriv (LValue).After (RValue);
+               }
+
+               internal override RdpPattern MixedTextDeriv ()
+               {
+                       return LValue.MixedTextDeriv ().After (RValue);
+               }
+
+               internal override RdpPattern MixedTextDeriv (MemoizationStore memo)
+               {
+                       return memo.MixedTextDeriv (LValue).After (RValue);
+               }
+
+               // startTagOpenDeriv (After p1 p2) qn =
+               //   applyAfter (flip after p2) (startTagOpenDeriv p1 qn)
+               public override RdpPattern StartTagOpenDeriv (string name, string ns)
+               {
+                       RdpPattern handled = LValue.StartTagOpenDeriv (name, ns);
+                       RdpFlip f = MakeFlip (RdpUtil.AfterFunction, RValue);
+                       return handled.ApplyAfter (new RdpApplyAfterHandler (
+                               f.Apply));
+               }
+
+               internal override RdpPattern StartTagOpenDeriv (string name, string ns, MemoizationStore memo)
+               {
+                       RdpPattern handled = memo.StartTagOpenDeriv (LValue, name, ns);
+                       RdpFlip f = MakeFlip (RdpUtil.AfterFunction, RValue);
+                       return handled.ApplyAfter (new RdpApplyAfterHandler (
+                               f.Apply));
+               }
+
+               public override RdpPattern ApplyAfter (RdpApplyAfterHandler handler)
+               {
+                       return LValue.After (handler (RValue));
+               }
+
+               // attDeriv cx (After p1 p2) att =
+               //  after (attDeriv cx p1 att) p2
+               public override RdpPattern AttDeriv (string name, string ns, string value, XmlReader reader)
+               {
+                       return LValue.AttDeriv (name, ns, value, reader).After (RValue);
+               }
+
+               public override RdpPattern StartAttDeriv (string name, string ns)
+               {
+                       RdpPattern handled = LValue.StartAttDeriv (name, ns);
+                       RdpFlip f = MakeFlip (RdpUtil.AfterFunction, RValue);
+                       return handled.ApplyAfter (new RdpApplyAfterHandler (
+                               f.Apply));
+               }
+
+               internal override RdpPattern StartAttDeriv (string name, string ns, MemoizationStore memo)
+               {
+                       RdpPattern handled = memo.StartAttDeriv (LValue, name, ns);
+                       RdpFlip f = MakeFlip (RdpUtil.AfterFunction, RValue);
+                       return handled.ApplyAfter (new RdpApplyAfterHandler (
+                               f.Apply));
+               }
+
+               public override RdpPattern EndAttDeriv ()
+               {
+                       return LValue.Nullable ? RValue : RdpNotAllowed.Instance;
+               }
+
+               public override RdpPattern StartTagCloseDeriv ()
+               {
+                       return LValue.StartTagCloseDeriv ().After (RValue);
+               }
+
+               internal override RdpPattern StartTagCloseDeriv (MemoizationStore memo)
+               {
+                       return memo.StartTagCloseDeriv (LValue).After (RValue);
+               }
+
+               public override RdpPattern EndTagDeriv ()
+               {
+                       return LValue.Nullable ? RValue : RdpNotAllowed.Instance;
+               }
+
+               public override RelaxngPatternType PatternType {
+                       get { return RelaxngPatternType.After; }
+               }
+
+               internal override void MarkReachableDefs () 
+               {
+                       throw new InvalidOperationException ();
+               }
+
+               internal override void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept) 
+               {
+                       throw new InvalidOperationException ();
+               }
+
+               internal override bool ContainsText ()
+               {
+                       throw new InvalidOperationException ();
+               }
+       }
+}
+