internal override bool ValidateDerivationByRestriction(XmlSchemaParticle baseParticle,
                                                               ValidationEventHandler h, XmlSchema schema, bool raiseError)
        {
            if (this == baseParticle)             // quick check
            {
                return(true);
            }

            XmlSchemaElement el = baseParticle as XmlSchemaElement;

            if (el != null)
            {
                // Forbidden
                if (raiseError)
                {
                    error(h, "Invalid sequence paricle derivation.");
                }
                return(false);
            }

            XmlSchemaSequence seq = baseParticle as XmlSchemaSequence;

            if (seq != null)
            {
                // Recurse
                if (!ValidateOccurenceRangeOK(seq, h, schema, raiseError))
                {
                    return(false);
                }

                // If it is totally optional, then ignore their contents.
                if (seq.ValidatedMinOccurs == 0 && seq.ValidatedMaxOccurs == 0 &&
                    this.ValidatedMinOccurs == 0 && this.ValidatedMaxOccurs == 0)
                {
                    return(true);
                }
                return(ValidateRecurse(seq, h, schema, raiseError));
            }

            XmlSchemaAll all = baseParticle as XmlSchemaAll;

            if (all != null)
            {
                // RecurseUnordered
                XmlSchemaObjectCollection already = new XmlSchemaObjectCollection();
                for (int i = 0; i < this.Items.Count; i++)
                {
                    XmlSchemaElement de = this.Items [i] as XmlSchemaElement;
                    if (de == null)
                    {
                        if (raiseError)
                        {
                            error(h, "Invalid sequence particle derivation by restriction from all.");
                        }
                        return(false);
                    }
                    foreach (XmlSchemaElement e in all.Items)
                    {
                        if (e.QualifiedName == de.QualifiedName)
                        {
                            if (already.Contains(e))
                            {
                                if (raiseError)
                                {
                                    error(h, "Base element particle is mapped to the derived element particle in a sequence two or more times.");
                                }
                                return(false);
                            }
                            else
                            {
                                already.Add(e);
                                if (!de.ValidateDerivationByRestriction(e, h, schema, raiseError))
                                {
                                    return(false);
                                }
                            }
                        }
                    }
                }
                foreach (XmlSchemaElement e in all.Items)
                {
                    if (!already.Contains(e))
                    {
                        if (!e.ValidateIsEmptiable())
                        {
                            if (raiseError)
                            {
                                error(h, "In base -all- particle, mapping-skipped base element which is not emptiable was found.");
                            }
                            return(false);
                        }
                    }
                }
                return(true);
            }
            XmlSchemaAny any = baseParticle as XmlSchemaAny;

            if (any != null)
            {
                // NSRecurseCheckCardinality
                return(ValidateNSRecurseCheckCardinality(any, h, schema, raiseError));
            }
            XmlSchemaChoice choice = baseParticle as XmlSchemaChoice;

            if (choice != null)
            {
                // MapAndSum
                // In fact it is not Recurse, but it looks almost common.
                return(ValidateSeqRecurseMapSumCommon(choice, h, schema, false, true, raiseError));
            }
            return(true);
        }