/*
 * reserved comment block
 * DO NOT REMOVE OR ALTER!
 */
/*
 * Copyright 2001-2005 The Apache Software Foundation.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.sun.org.apache.xerces.internal.impl.dv.xs;

import java.util.AbstractList;
import java.util.Locale;
import java.util.StringTokenizer;
import java.util.Vector;

import com.sun.org.apache.xerces.internal.impl.Constants;
import com.sun.org.apache.xerces.internal.impl.dv.DatatypeException;
import com.sun.org.apache.xerces.internal.impl.dv.InvalidDatatypeFacetException;
import com.sun.org.apache.xerces.internal.impl.dv.InvalidDatatypeValueException;
import com.sun.org.apache.xerces.internal.impl.dv.ValidatedInfo;
import com.sun.org.apache.xerces.internal.impl.dv.ValidationContext;
import com.sun.org.apache.xerces.internal.impl.dv.XSFacets;
import com.sun.org.apache.xerces.internal.impl.dv.XSSimpleType;
import com.sun.org.apache.xerces.internal.impl.xpath.regex.RegularExpression;
import com.sun.org.apache.xerces.internal.impl.xpath.regex.ParseException;
import com.sun.org.apache.xerces.internal.impl.xs.SchemaSymbols;
import com.sun.org.apache.xerces.internal.impl.xs.util.ShortListImpl;
import com.sun.org.apache.xerces.internal.impl.xs.util.StringListImpl;
import com.sun.org.apache.xerces.internal.impl.xs.util.XSObjectListImpl;
import com.sun.org.apache.xerces.internal.util.XMLChar;
import com.sun.org.apache.xerces.internal.xni.NamespaceContext;
import com.sun.org.apache.xerces.internal.xs.ShortList;
import com.sun.org.apache.xerces.internal.xs.StringList;
import com.sun.org.apache.xerces.internal.xs.XSAnnotation;
import com.sun.org.apache.xerces.internal.xs.XSConstants;
import com.sun.org.apache.xerces.internal.xs.XSFacet;
import com.sun.org.apache.xerces.internal.xs.XSMultiValueFacet;
import com.sun.org.apache.xerces.internal.xs.XSNamespaceItem;
import com.sun.org.apache.xerces.internal.xs.XSObjectList;
import com.sun.org.apache.xerces.internal.xs.XSSimpleTypeDefinition;
import com.sun.org.apache.xerces.internal.xs.XSTypeDefinition;
import com.sun.org.apache.xerces.internal.xs.datatypes.ObjectList;
import org.w3c.dom.TypeInfo;

/**
 * @xerces.internal
 *
 * @author Sandy Gao, IBM
 * @author Neeraj Bajaj, Sun Microsystems, inc.
 *
 * @version $Id: XSSimpleTypeDecl.java 3029 2011-04-24 17:50:18Z joehw $
 */
public class XSSimpleTypeDecl implements XSSimpleType, TypeInfo {

    protected static final short DV_STRING        = PRIMITIVE_STRING;
    protected static final short DV_BOOLEAN       = PRIMITIVE_BOOLEAN;
    protected static final short DV_DECIMAL       = PRIMITIVE_DECIMAL;
    protected static final short DV_FLOAT         = PRIMITIVE_FLOAT;
    protected static final short DV_DOUBLE        = PRIMITIVE_DOUBLE;
    protected static final short DV_DURATION      = PRIMITIVE_DURATION;
    protected static final short DV_DATETIME      = PRIMITIVE_DATETIME;
    protected static final short DV_TIME          = PRIMITIVE_TIME;
    protected static final short DV_DATE          = PRIMITIVE_DATE;
    protected static final short DV_GYEARMONTH    = PRIMITIVE_GYEARMONTH;
    protected static final short DV_GYEAR         = PRIMITIVE_GYEAR;
    protected static final short DV_GMONTHDAY     = PRIMITIVE_GMONTHDAY;
    protected static final short DV_GDAY          = PRIMITIVE_GDAY;
    protected static final short DV_GMONTH        = PRIMITIVE_GMONTH;
    protected static final short DV_HEXBINARY     = PRIMITIVE_HEXBINARY;
    protected static final short DV_BASE64BINARY  = PRIMITIVE_BASE64BINARY;
    protected static final short DV_ANYURI        = PRIMITIVE_ANYURI;
    protected static final short DV_QNAME         = PRIMITIVE_QNAME;
    protected static final short DV_PRECISIONDECIMAL = PRIMITIVE_PRECISIONDECIMAL;
    protected static final short DV_NOTATION      = PRIMITIVE_NOTATION;

    protected static final short DV_ANYSIMPLETYPE = 0;
    protected static final short DV_ID            = DV_NOTATION + 1;
    protected static final short DV_IDREF         = DV_NOTATION + 2;
    protected static final short DV_ENTITY        = DV_NOTATION + 3;
    protected static final short DV_INTEGER       = DV_NOTATION + 4;
    protected static final short DV_LIST          = DV_NOTATION + 5;
    protected static final short DV_UNION         = DV_NOTATION + 6;
    protected static final short DV_YEARMONTHDURATION = DV_NOTATION + 7;
    protected static final short DV_DAYTIMEDURATION     = DV_NOTATION + 8;
    protected static final short DV_ANYATOMICTYPE = DV_NOTATION + 9;

    private static final TypeValidator[] gDVs = {
        new AnySimpleDV(),
        new StringDV(),
        new BooleanDV(),
        new DecimalDV(),
        new FloatDV(),
        new DoubleDV(),
        new DurationDV(),
        new DateTimeDV(),
        new TimeDV(),
        new DateDV(),
        new YearMonthDV(),
        new YearDV(),
        new MonthDayDV(),
        new DayDV(),
        new MonthDV(),
        new HexBinaryDV(),
        new Base64BinaryDV(),
        new AnyURIDV(),
        new QNameDV(),
        new PrecisionDecimalDV(), // XML Schema 1.1 type
        new QNameDV(),   // notation use the same one as qname
        new IDDV(),
        new IDREFDV(),
        new EntityDV(),
        new IntegerDV(),
        new ListDV(),
        new UnionDV(),
        new YearMonthDurationDV(), // XML Schema 1.1 type
        new DayTimeDurationDV(), // XML Schema 1.1 type
        new AnyAtomicDV() // XML Schema 1.1 type
    };

    static final short NORMALIZE_NONE = 0;
    static final short NORMALIZE_TRIM = 1;
    static final short NORMALIZE_FULL = 2;
    static final short[] fDVNormalizeType = {
        NORMALIZE_NONE, //AnySimpleDV(),
        NORMALIZE_FULL, //StringDV(),
        NORMALIZE_TRIM, //BooleanDV(),
        NORMALIZE_TRIM, //DecimalDV(),
        NORMALIZE_TRIM, //FloatDV(),
        NORMALIZE_TRIM, //DoubleDV(),
        NORMALIZE_TRIM, //DurationDV(),
        NORMALIZE_TRIM, //DateTimeDV(),
        NORMALIZE_TRIM, //TimeDV(),
        NORMALIZE_TRIM, //DateDV(),
        NORMALIZE_TRIM, //YearMonthDV(),
        NORMALIZE_TRIM, //YearDV(),
        NORMALIZE_TRIM, //MonthDayDV(),
        NORMALIZE_TRIM, //DayDV(),
        NORMALIZE_TRIM, //MonthDV(),
        NORMALIZE_TRIM, //HexBinaryDV(),
        NORMALIZE_NONE, //Base64BinaryDV(),  // Base64 know how to deal with spaces
        NORMALIZE_TRIM, //AnyURIDV(),
        NORMALIZE_TRIM, //QNameDV(),
        NORMALIZE_TRIM, //PrecisionDecimalDV() (Schema 1.1)
        NORMALIZE_TRIM, //QNameDV(),   // notation
        NORMALIZE_TRIM, //IDDV(),
        NORMALIZE_TRIM, //IDREFDV(),
        NORMALIZE_TRIM, //EntityDV(),
        NORMALIZE_TRIM, //IntegerDV(),
        NORMALIZE_FULL, //ListDV(),
        NORMALIZE_NONE, //UnionDV(),
        NORMALIZE_TRIM, //YearMonthDurationDV() (Schema 1.1)
        NORMALIZE_TRIM, //DayTimeDurationDV() (Schema 1.1)
        NORMALIZE_NONE, //AnyAtomicDV() (Schema 1.1)
    };

    static final short SPECIAL_PATTERN_NONE     = 0;
    static final short SPECIAL_PATTERN_NMTOKEN  = 1;
    static final short SPECIAL_PATTERN_NAME     = 2;
    static final short SPECIAL_PATTERN_NCNAME   = 3;

    static final String[] SPECIAL_PATTERN_STRING   = {
        "NONE", "NMTOKEN", "Name", "NCName"
    };

    static final String[] WS_FACET_STRING = {
        "preserve", "replace", "collapse"
    };

    static final String URI_SCHEMAFORSCHEMA = "http://www.w3.org/2001/XMLSchema";
    static final String ANY_TYPE = "anyType";

    // XML Schema 1.1 type constants
    public static final short YEARMONTHDURATION_DT      = 46;
    public static final short DAYTIMEDURATION_DT        = 47;
    public static final short PRECISIONDECIMAL_DT       = 48;
    public static final short ANYATOMICTYPE_DT          = 49;

    // DOM Level 3 TypeInfo Derivation Method constants
    static final int DERIVATION_ANY = 0;
    static final int DERIVATION_RESTRICTION = 1;
    static final int DERIVATION_EXTENSION = 2;
    static final int DERIVATION_UNION = 4;
    static final int DERIVATION_LIST = 8;

    static final ValidationContext fEmptyContext = new ValidationContext() {
        public boolean needFacetChecking() {
            return true;
        }
        public boolean needExtraChecking() {
            return false;
        }
        public boolean needToNormalize() {
            return true;
        }
        public boolean useNamespaces () {
            return true;
        }
        public boolean isEntityDeclared (String name) {
            return false;
        }
        public boolean isEntityUnparsed (String name) {
            return false;
        }
        public boolean isIdDeclared (String name) {
            return false;
        }
        public void addId(String name) {
        }
        public void addIdRef(String name) {
        }
        public String getSymbol (String symbol) {
            return symbol.intern();
        }
        public String getURI(String prefix) {
            return null;
        }
        public Locale getLocale() {
            return Locale.getDefault();
        }
    };

    protected static TypeValidator[] getGDVs() {
        return (TypeValidator[])gDVs.clone();
    }
    private TypeValidator[] fDVs = gDVs;
    protected void setDVs(TypeValidator[] dvs) {
        fDVs = dvs;
    }

    // this will be true if this is a static XSSimpleTypeDecl
    // and hence must remain immutable (i.e., applyFacets
    // may not be permitted to have any effect).
    private boolean fIsImmutable = false;

    private XSSimpleTypeDecl fItemType;
    private XSSimpleTypeDecl[] fMemberTypes;
    // The most specific built-in type kind.
    private short fBuiltInKind;

    private String fTypeName;
    private String fTargetNamespace;
    private short fFinalSet = 0;
    private XSSimpleTypeDecl fBase;
    private short fVariety = -1;
    private short fValidationDV = -1;

    private short fFacetsDefined = 0;
    private short fFixedFacet = 0;

    //for constraining facets
    private short fWhiteSpace = 0;
    private int fLength = -1;
    private int fMinLength = -1;
    private int fMaxLength = -1;
    private int fTotalDigits = -1;
    private int fFractionDigits = -1;
    private Vector fPattern;
    private Vector fPatternStr;
    private Vector fEnumeration;
    private short[] fEnumerationType;
    private ShortList[] fEnumerationItemType;   // used in case fenumerationType value is LIST or LISTOFUNION
    private ShortList fEnumerationTypeList;
    private ObjectList fEnumerationItemTypeList;
    private StringList fLexicalPattern;
    private StringList fLexicalEnumeration;
    private ObjectList fActualEnumeration;
    private Object fMaxInclusive;
    private Object fMaxExclusive;
    private Object fMinExclusive;
    private Object fMinInclusive;

    // annotations for constraining facets
    public XSAnnotation lengthAnnotation;
    public XSAnnotation minLengthAnnotation;
    public XSAnnotation maxLengthAnnotation;
    public XSAnnotation whiteSpaceAnnotation;
    public XSAnnotation totalDigitsAnnotation;
    public XSAnnotation fractionDigitsAnnotation;
    public XSObjectListImpl patternAnnotations;
    public XSObjectList enumerationAnnotations;
    public XSAnnotation maxInclusiveAnnotation;
    public XSAnnotation maxExclusiveAnnotation;
    public XSAnnotation minInclusiveAnnotation;
    public XSAnnotation minExclusiveAnnotation;

    // facets as objects
    private XSObjectListImpl fFacets;

    // enumeration and pattern facets
    private XSObjectListImpl fMultiValueFacets;

    // simpleType annotations
    private XSObjectList fAnnotations = null;

    private short fPatternType = SPECIAL_PATTERN_NONE;

    // for fundamental facets
    private short fOrdered;
    private boolean fFinite;
    private boolean fBounded;
    private boolean fNumeric;

    // The namespace schema information item corresponding to the target namespace
    // of the simple type definition, if it is globally declared; or null otherwise.
    private XSNamespaceItem fNamespaceItem = null;

    // default constructor
    public XSSimpleTypeDecl(){}

    //Create a new built-in primitive types (and id/idref/entity/integer/yearMonthDuration)
    protected XSSimpleTypeDecl(XSSimpleTypeDecl base, String name, short validateDV,
            short ordered, boolean bounded, boolean finite,
            boolean numeric, boolean isImmutable, short builtInKind) {
        fIsImmutable = isImmutable;
        fBase = base;
        fTypeName = name;
        fTargetNamespace = URI_SCHEMAFORSCHEMA;
        // To simplify the code for anySimpleType, we treat it as an atomic type
        fVariety = VARIETY_ATOMIC;
        fValidationDV = validateDV;
        fFacetsDefined = FACET_WHITESPACE;
        if (validateDV == DV_ANYSIMPLETYPE ||
            validateDV == DV_ANYATOMICTYPE ||
            validateDV == DV_STRING) {
            fWhiteSpace = WS_PRESERVE;
        }
        else {
            fWhiteSpace = WS_COLLAPSE;
            fFixedFacet = FACET_WHITESPACE;
        }
        this.fOrdered = ordered;
        this.fBounded = bounded;
        this.fFinite = finite;
        this.fNumeric = numeric;
        fAnnotations = null;

        // Specify the build in kind for this primitive type
        fBuiltInKind = builtInKind;
    }

    //Create a new simple type for restriction for built-in types
    protected XSSimpleTypeDecl(XSSimpleTypeDecl base, String name, String uri, short finalSet, boolean isImmutable,
            XSObjectList annotations, short builtInKind) {
        this(base, name, uri, finalSet, isImmutable, annotations);
        // Specify the build in kind for this built-in type
        fBuiltInKind = builtInKind;
    }

    //Create a new simple type for restriction.
    protected XSSimpleTypeDecl(XSSimpleTypeDecl base, String name, String uri, short finalSet, boolean isImmutable,
            XSObjectList annotations) {
        fBase = base;
        fTypeName = name;
        fTargetNamespace = uri;
        fFinalSet = finalSet;
        fAnnotations = annotations;

        fVariety = fBase.fVariety;
        fValidationDV = fBase.fValidationDV;
        switch (fVariety) {
            case VARIETY_ATOMIC:
                break;
            case VARIETY_LIST:
                fItemType = fBase.fItemType;
                break;
            case VARIETY_UNION:
                fMemberTypes = fBase.fMemberTypes;
                break;
        }

        // always inherit facets from the base.
        // in case a type is created, but applyFacets is not called
        fLength = fBase.fLength;
        fMinLength = fBase.fMinLength;
        fMaxLength = fBase.fMaxLength;
        fPattern = fBase.fPattern;
        fPatternStr = fBase.fPatternStr;
        fEnumeration = fBase.fEnumeration;
        fEnumerationType = fBase.fEnumerationType;
        fEnumerationItemType = fBase.fEnumerationItemType;
        fWhiteSpace = fBase.fWhiteSpace;
        fMaxExclusive = fBase.fMaxExclusive;
        fMaxInclusive = fBase.fMaxInclusive;
        fMinExclusive = fBase.fMinExclusive;
        fMinInclusive = fBase.fMinInclusive;
        fTotalDigits = fBase.fTotalDigits;
        fFractionDigits = fBase.fFractionDigits;
        fPatternType = fBase.fPatternType;
        fFixedFacet = fBase.fFixedFacet;
        fFacetsDefined = fBase.fFacetsDefined;

        // always inherit facet annotations in case applyFacets is not called.
        lengthAnnotation = fBase.lengthAnnotation;
        minLengthAnnotation = fBase.minLengthAnnotation;
        maxLengthAnnotation = fBase.maxLengthAnnotation;
        patternAnnotations = fBase.patternAnnotations;
        enumerationAnnotations = fBase.enumerationAnnotations;
        whiteSpaceAnnotation = fBase.whiteSpaceAnnotation;
        maxExclusiveAnnotation = fBase.maxExclusiveAnnotation;
        maxInclusiveAnnotation = fBase.maxInclusiveAnnotation;
        minExclusiveAnnotation = fBase.minExclusiveAnnotation;
        minInclusiveAnnotation = fBase.minInclusiveAnnotation;
        totalDigitsAnnotation = fBase.totalDigitsAnnotation;
        fractionDigitsAnnotation = fBase.fractionDigitsAnnotation;

        //we also set fundamental facets information in case applyFacets is not called.
        calcFundamentalFacets();
        fIsImmutable = isImmutable;

        // Inherit from the base type
        fBuiltInKind = base.fBuiltInKind;
    }

    //Create a new simple type for list.
    protected XSSimpleTypeDecl(String name, String uri, short finalSet, XSSimpleTypeDecl itemType, boolean isImmutable,
            XSObjectList annotations) {
        fBase = fAnySimpleType;
        fTypeName = name;
        fTargetNamespace = uri;
        fFinalSet = finalSet;
        fAnnotations = annotations;

        fVariety = VARIETY_LIST;
        fItemType = (XSSimpleTypeDecl)itemType;
        fValidationDV = DV_LIST;
        fFacetsDefined = FACET_WHITESPACE;
        fFixedFacet = FACET_WHITESPACE;
        fWhiteSpace = WS_COLLAPSE;

        //setting fundamental facets
        calcFundamentalFacets();
        fIsImmutable = isImmutable;

        // Values of this type are lists
        fBuiltInKind = XSConstants.LIST_DT;
    }

    //Create a new simple type for union.
    protected XSSimpleTypeDecl(String name, String uri, short finalSet, XSSimpleTypeDecl[] memberTypes,
            XSObjectList annotations) {
        fBase = fAnySimpleType;
        fTypeName = name;
        fTargetNamespace = uri;
        fFinalSet = finalSet;
        fAnnotations = annotations;

        fVariety = VARIETY_UNION;
        fMemberTypes = memberTypes;
        fValidationDV = DV_UNION;
        // even for union, we set whitespace to something
        // this will never be used, but we can use fFacetsDefined to check
        // whether applyFacets() is allwwed: it's not allowed
        // if fFacetsDefined != 0
        fFacetsDefined = FACET_WHITESPACE;
        fWhiteSpace = WS_COLLAPSE;

        //setting fundamental facets
        calcFundamentalFacets();
        // none of the schema-defined types are unions, so just set
        // fIsImmutable to false.
        fIsImmutable = false;

        // No value can be of this type, so it's unavailable.
        fBuiltInKind = XSConstants.UNAVAILABLE_DT;
    }

    //set values for restriction.
    protected XSSimpleTypeDecl setRestrictionValues(XSSimpleTypeDecl base, String name, String uri, short finalSet,
            XSObjectList annotations) {
        //decline to do anything if the object is immutable.
        if(fIsImmutable) return null;
        fBase = base;
        fAnonymous = false;
        fTypeName = name;
        fTargetNamespace = uri;
        fFinalSet = finalSet;
        fAnnotations = annotations;

        fVariety = fBase.fVariety;
        fValidationDV = fBase.fValidationDV;
        switch (fVariety) {
            case VARIETY_ATOMIC:
                break;
            case VARIETY_LIST:
                fItemType = fBase.fItemType;
                break;
            case VARIETY_UNION:
                fMemberTypes = fBase.fMemberTypes;
                break;
        }

        // always inherit facets from the base.
        // in case a type is created, but applyFacets is not called
        fLength = fBase.fLength;
        fMinLength = fBase.fMinLength;
        fMaxLength = fBase.fMaxLength;
        fPattern = fBase.fPattern;
        fPatternStr = fBase.fPatternStr;
        fEnumeration = fBase.fEnumeration;
        fEnumerationType = fBase.fEnumerationType;
        fEnumerationItemType = fBase.fEnumerationItemType;
        fWhiteSpace = fBase.fWhiteSpace;
        fMaxExclusive = fBase.fMaxExclusive;
        fMaxInclusive = fBase.fMaxInclusive;
        fMinExclusive = fBase.fMinExclusive;
        fMinInclusive = fBase.fMinInclusive;
        fTotalDigits = fBase.fTotalDigits;
        fFractionDigits = fBase.fFractionDigits;
        fPatternType = fBase.fPatternType;
        fFixedFacet = fBase.fFixedFacet;
        fFacetsDefined = fBase.fFacetsDefined;

        //we also set fundamental facets information in case applyFacets is not called.
        calcFundamentalFacets();

        // Inherit from the base type
        fBuiltInKind = base.fBuiltInKind;

        return this;
    }

    //set values for list.
    protected XSSimpleTypeDecl setListValues(String name, String uri, short finalSet, XSSimpleTypeDecl itemType,
            XSObjectList annotations) {
        //decline to do anything if the object is immutable.
        if(fIsImmutable) return null;
        fBase = fAnySimpleType;
        fAnonymous = false;
        fTypeName = name;
        fTargetNamespace = uri;
        fFinalSet = finalSet;
        fAnnotations = annotations;

        fVariety = VARIETY_LIST;
        fItemType = (XSSimpleTypeDecl)itemType;
        fValidationDV = DV_LIST;
        fFacetsDefined = FACET_WHITESPACE;
        fFixedFacet = FACET_WHITESPACE;
        fWhiteSpace = WS_COLLAPSE;

        //setting fundamental facets
        calcFundamentalFacets();

        // Values of this type are lists
        fBuiltInKind = XSConstants.LIST_DT;

        return this;
    }

    //set values for union.
    protected XSSimpleTypeDecl setUnionValues(String name, String uri, short finalSet, XSSimpleTypeDecl[] memberTypes,
            XSObjectList annotations) {
        //decline to do anything if the object is immutable.
        if(fIsImmutable) return null;
        fBase = fAnySimpleType;
        fAnonymous = false;
        fTypeName = name;
        fTargetNamespace = uri;
        fFinalSet = finalSet;
        fAnnotations = annotations;

        fVariety = VARIETY_UNION;
        fMemberTypes = memberTypes;
        fValidationDV = DV_UNION;
        // even for union, we set whitespace to something
        // this will never be used, but we can use fFacetsDefined to check
        // whether applyFacets() is allwwed: it's not allowed
        // if fFacetsDefined != 0
        fFacetsDefined = FACET_WHITESPACE;
        fWhiteSpace = WS_COLLAPSE;

        //setting fundamental facets
        calcFundamentalFacets();

        // No value can be of this type, so it's unavailable.
        fBuiltInKind = XSConstants.UNAVAILABLE_DT;

        return this;
    }

    public short getType () {
        return XSConstants.TYPE_DEFINITION;
    }

    public short getTypeCategory () {
        return SIMPLE_TYPE;
    }

    public String getName() {
        return getAnonymous()?null:fTypeName;
    }

    public String getTypeName() {
        return fTypeName;
    }

    public String getNamespace() {
        return fTargetNamespace;
    }

    public short getFinal(){
        return fFinalSet;
    }

    public boolean isFinal(short derivation) {
        return (fFinalSet & derivation) != 0;
    }

    public XSTypeDefinition getBaseType(){
        return fBase;
    }

    public boolean getAnonymous() {
        return fAnonymous || (fTypeName == null);
    }

    public short getVariety(){
        // for anySimpleType, return absent variaty
        return fValidationDV == DV_ANYSIMPLETYPE ? VARIETY_ABSENT : fVariety;
    }

    public boolean isIDType(){
        switch (fVariety) {
            case VARIETY_ATOMIC:
                return fValidationDV == DV_ID;
            case VARIETY_LIST:
                return fItemType.isIDType();
            case VARIETY_UNION:
                for (int i = 0; i < fMemberTypes.length; i++) {
                    if (fMemberTypes[i].isIDType())
                        return true;
                }
        }
        return false;
    }

    public short getWhitespace() throws DatatypeException{
        if (fVariety == VARIETY_UNION) {
            throw new DatatypeException("dt-whitespace", new Object[]{fTypeName});
        }
        return fWhiteSpace;
    }

    public short getPrimitiveKind() {
        if (fVariety == VARIETY_ATOMIC && fValidationDV != DV_ANYSIMPLETYPE) {
            if (fValidationDV == DV_ID || fValidationDV == DV_IDREF || fValidationDV == DV_ENTITY) {
                return DV_STRING;
            }
            else if (fValidationDV == DV_INTEGER) {
                return DV_DECIMAL;
            }
            else if (Constants.SCHEMA_1_1_SUPPORT && (fValidationDV == DV_YEARMONTHDURATION || fValidationDV == DV_DAYTIMEDURATION)) {
                return DV_DURATION;
            }
            else {
                return fValidationDV;
            }
        }
        else {
            // REVISIT: error situation. runtime exception?
            return (short)0;
        }
    }

    /**
     * Returns the closest built-in type category this type represents or
     * derived from. For example, if this simple type is a built-in derived
     * type integer the <code>INTEGER_DV</code> is returned.
     */
    public short getBuiltInKind() {
        return this.fBuiltInKind;
    }

    /**
     * If variety is <code>atomic</code> the primitive type definition (a
     * built-in primitive datatype definition or the simple ur-type
     * definition) is available, otherwise <code>null</code>.
     */
    public XSSimpleTypeDefinition getPrimitiveType() {
        if (fVariety == VARIETY_ATOMIC && fValidationDV != DV_ANYSIMPLETYPE) {
            XSSimpleTypeDecl pri = this;
            // recursively get base, until we reach anySimpleType
            while (pri.fBase != fAnySimpleType)
                pri = pri.fBase;
            return pri;
        }
        else {
            // REVISIT: error situation. runtime exception?
            return null;
        }
    }

    /**
     * If variety is <code>list</code> the item type definition (an atomic or
     * union simple type definition) is available, otherwise
     * <code>null</code>.
     */
    public XSSimpleTypeDefinition getItemType() {
        if (fVariety == VARIETY_LIST) {
            return fItemType;
        }
        else {
            // REVISIT: error situation. runtime exception?
            return null;
        }
    }

    /**
     * If variety is <code>union</code> the list of member type definitions (a
     * non-empty sequence of simple type definitions) is available,
     * otherwise an empty <code>XSObjectList</code>.
     */
    public XSObjectList getMemberTypes() {
        if (fVariety == VARIETY_UNION) {
            return new XSObjectListImpl(fMemberTypes, fMemberTypes.length);
        }
        else {
            return XSObjectListImpl.EMPTY_LIST;
        }
    }

    /**
     * If <restriction> is chosen
     */
    public void applyFacets(XSFacets facets, short presentFacet, short fixedFacet, ValidationContext context)
    throws InvalidDatatypeFacetException {
        if (context == null) {
            context = fEmptyContext;
        }
        applyFacets(facets, presentFacet, fixedFacet, SPECIAL_PATTERN_NONE, context);
    }

    /**
     * built-in derived types by restriction
     */
    void applyFacets1(XSFacets facets, short presentFacet, short fixedFacet) {

        try {
            applyFacets(facets, presentFacet, fixedFacet, SPECIAL_PATTERN_NONE, fDummyContext);
        } catch (InvalidDatatypeFacetException e) {
            // should never gets here, internel error
            throw new RuntimeException("internal error");
        }
        // we've now applied facets; so lock this object:
        fIsImmutable = true;
    }

    /**
     * built-in derived types by restriction
     */
    void applyFacets1(XSFacets facets, short presentFacet, short fixedFacet, short patternType) {

        try {
            applyFacets(facets, presentFacet, fixedFacet, patternType, fDummyContext);
        } catch (InvalidDatatypeFacetException e) {
            // should never gets here, internel error
            throw new RuntimeException("internal error");
        }
        // we've now applied facets; so lock this object:
        fIsImmutable = true;
    }

    /**
     * If <restriction> is chosen, or built-in derived types by restriction
     */
    void applyFacets(XSFacets facets, short presentFacet, short fixedFacet, short patternType, ValidationContext context)
    throws InvalidDatatypeFacetException {

        // if the object is immutable, should not apply facets...
        if(fIsImmutable) return;
        ValidatedInfo tempInfo = new ValidatedInfo();

        // clear facets. because we always inherit facets in the constructor
        // REVISIT: in fact, we don't need to clear them.
        // we can convert 5 string values (4 bounds + 1 enum) to actual values,
        // store them somewhere, then do facet checking at once, instead of
        // going through the following steps. (lots of checking are redundant:
        // for example, ((presentFacet & FACET_XXX) != 0))

        fFacetsDefined = 0;
        fFixedFacet = 0;

        int result = 0 ;

        // step 1: parse present facets
        short allowedFacet = fDVs[fValidationDV].getAllowedFacets();

        // length
        if ((presentFacet & FACET_LENGTH) != 0) {
            if ((allowedFacet & FACET_LENGTH) == 0) {
                reportError("cos-applicable-facets", new Object[]{"length", fTypeName});
            } else {
                fLength = facets.length;
                lengthAnnotation = facets.lengthAnnotation;
                fFacetsDefined |= FACET_LENGTH;
                if ((fixedFacet & FACET_LENGTH) != 0)
                    fFixedFacet |= FACET_LENGTH;
            }
        }
        // minLength
        if ((presentFacet & FACET_MINLENGTH) != 0) {
            if ((allowedFacet & FACET_MINLENGTH) == 0) {
                reportError("cos-applicable-facets", new Object[]{"minLength", fTypeName});
            } else {
                fMinLength = facets.minLength;
                minLengthAnnotation = facets.minLengthAnnotation;
                fFacetsDefined |= FACET_MINLENGTH;
                if ((fixedFacet & FACET_MINLENGTH) != 0)
                    fFixedFacet |= FACET_MINLENGTH;
            }
        }
        // maxLength
        if ((presentFacet & FACET_MAXLENGTH) != 0) {
            if ((allowedFacet & FACET_MAXLENGTH) == 0) {
                reportError("cos-applicable-facets", new Object[]{"maxLength", fTypeName});
            } else {
                fMaxLength = facets.maxLength;
                maxLengthAnnotation = facets.maxLengthAnnotation;
                fFacetsDefined |= FACET_MAXLENGTH;
                if ((fixedFacet & FACET_MAXLENGTH) != 0)
                    fFixedFacet |= FACET_MAXLENGTH;
            }
        }
        // pattern
        if ((presentFacet & FACET_PATTERN) != 0) {
            if ((allowedFacet & FACET_PATTERN) == 0) {
                reportError("cos-applicable-facets", new Object[]{"pattern", fTypeName});
            } else {
                patternAnnotations = facets.patternAnnotations;
                RegularExpression regex = null;
                try {
                    regex = new RegularExpression(facets.pattern, "X", context.getLocale());
                } catch (Exception e) {
                    reportError("InvalidRegex", new Object[]{facets.pattern, e.getLocalizedMessage()});
                }
                if (regex != null) {
                    fPattern = new Vector();
                    fPattern.addElement(regex);
                    fPatternStr = new Vector();
                    fPatternStr.addElement(facets.pattern);
                    fFacetsDefined |= FACET_PATTERN;
                    if ((fixedFacet & FACET_PATTERN) != 0)
                        fFixedFacet |= FACET_PATTERN;
                }
            }
        }

        // whiteSpace
        if ((presentFacet & FACET_WHITESPACE) != 0) {
            if ((allowedFacet & FACET_WHITESPACE) == 0) {
                reportError("cos-applicable-facets", new Object[]{"whiteSpace", fTypeName});
            } else {
                fWhiteSpace = facets.whiteSpace;
                whiteSpaceAnnotation = facets.whiteSpaceAnnotation;
                fFacetsDefined |= FACET_WHITESPACE;
                if ((fixedFacet & FACET_WHITESPACE) != 0)
                    fFixedFacet |= FACET_WHITESPACE;
            }
        }
        // enumeration
        if ((presentFacet & FACET_ENUMERATION) != 0) {
            if ((allowedFacet & FACET_ENUMERATION) == 0) {
                reportError("cos-applicable-facets", new Object[]{"enumeration", fTypeName});
            } else {
                fEnumeration = new Vector();
                Vector enumVals = facets.enumeration;
                fEnumerationType = new short[enumVals.size()];
                fEnumerationItemType = new ShortList[enumVals.size()];
                Vector enumNSDecls = facets.enumNSDecls;
                ValidationContextImpl ctx = new ValidationContextImpl(context);
                enumerationAnnotations = facets.enumAnnotations;
                for (int i = 0; i < enumVals.size(); i++) {
                    if (enumNSDecls != null)
                        ctx.setNSContext((NamespaceContext)enumNSDecls.elementAt(i));
                    try {
                        ValidatedInfo info = getActualEnumValue((String)enumVals.elementAt(i), ctx, tempInfo);
                        // check 4.3.5.c0 must: enumeration values from the value space of base
                        fEnumeration.addElement(info.actualValue);
                        fEnumerationType[i] = info.actualValueType;
                        fEnumerationItemType[i] = info.itemValueTypes;
                    } catch (InvalidDatatypeValueException ide) {
                        reportError("enumeration-valid-restriction", new Object[]{enumVals.elementAt(i), this.getBaseType().getName()});
                    }
                }
                fFacetsDefined |= FACET_ENUMERATION;
                if ((fixedFacet & FACET_ENUMERATION) != 0)
                    fFixedFacet |= FACET_ENUMERATION;
            }
        }

        // maxInclusive
        if ((presentFacet & FACET_MAXINCLUSIVE) != 0) {
            if ((allowedFacet & FACET_MAXINCLUSIVE) == 0) {
                reportError("cos-applicable-facets", new Object[]{"maxInclusive", fTypeName});
            } else {
                maxInclusiveAnnotation = facets.maxInclusiveAnnotation;
                try {
                    fMaxInclusive = fBase.getActualValue(facets.maxInclusive, context, tempInfo, true);
                    fFacetsDefined |= FACET_MAXINCLUSIVE;
                    if ((fixedFacet & FACET_MAXINCLUSIVE) != 0)
                        fFixedFacet |= FACET_MAXINCLUSIVE;
                } catch (InvalidDatatypeValueException ide) {
                    reportError(ide.getKey(), ide.getArgs());
                    reportError("FacetValueFromBase", new Object[]{fTypeName, facets.maxInclusive,
                            "maxInclusive", fBase.getName()});
                }

                // check against fixed value in base
                if (((fBase.fFacetsDefined & FACET_MAXINCLUSIVE) != 0)) {
                    if ((fBase.fFixedFacet & FACET_MAXINCLUSIVE) != 0) {
                        if (fDVs[fValidationDV].compare(fMaxInclusive, fBase.fMaxInclusive) != 0)
                            reportError( "FixedFacetValue", new Object[]{"maxInclusive", fMaxInclusive, fBase.fMaxInclusive, fTypeName});
                    }
                }
                // maxInclusive from base
                try {
                    fBase.validate(context, tempInfo);
                } catch (InvalidDatatypeValueException ide) {
                    reportError(ide.getKey(), ide.getArgs());
                    reportError("FacetValueFromBase", new Object[]{fTypeName, facets.maxInclusive,
                            "maxInclusive", fBase.getName()});
                }
            }
        }

        // maxExclusive
        boolean needCheckBase = true;
        if ((presentFacet & FACET_MAXEXCLUSIVE) != 0) {
            if ((allowedFacet & FACET_MAXEXCLUSIVE) == 0) {
                reportError("cos-applicable-facets", new Object[]{"maxExclusive", fTypeName});
            } else {
                maxExclusiveAnnotation = facets.maxExclusiveAnnotation;
                try {
                    fMaxExclusive = fBase.getActualValue(facets.maxExclusive, context, tempInfo, true);
                    fFacetsDefined |= FACET_MAXEXCLUSIVE;
                    if ((fixedFacet & FACET_MAXEXCLUSIVE) != 0)
                        fFixedFacet |= FACET_MAXEXCLUSIVE;
                } catch (InvalidDatatypeValueException ide) {
                    reportError(ide.getKey(), ide.getArgs());
                    reportError("FacetValueFromBase", new Object[]{fTypeName, facets.maxExclusive,
                            "maxExclusive", fBase.getName()});
                }

                // check against fixed value in base
                if (((fBase.fFacetsDefined & FACET_MAXEXCLUSIVE) != 0)) {
                    result = fDVs[fValidationDV].compare(fMaxExclusive, fBase.fMaxExclusive);
                    if ((fBase.fFixedFacet & FACET_MAXEXCLUSIVE) != 0 && result != 0) {
                        reportError( "FixedFacetValue", new Object[]{"maxExclusive", facets.maxExclusive, fBase.fMaxExclusive, fTypeName});
                    }
                    if (result == 0) {
                        needCheckBase = false;
                    }
                }
                // maxExclusive from base
                if (needCheckBase) {
                    try {
                        fBase.validate(context, tempInfo);
                    } catch (InvalidDatatypeValueException ide) {
                        reportError(ide.getKey(), ide.getArgs());
                        reportError("FacetValueFromBase", new Object[]{fTypeName, facets.maxExclusive,
                                "maxExclusive", fBase.getName()});
                    }
                }
                // If maxExclusive == base.maxExclusive, then we only need to check
                // maxExclusive <= base.maxInclusive
                else if (((fBase.fFacetsDefined & FACET_MAXINCLUSIVE) != 0)) {
                    if (fDVs[fValidationDV].compare(fMaxExclusive, fBase.fMaxInclusive) > 0) {
                        reportError( "maxExclusive-valid-restriction.2", new Object[]{facets.maxExclusive, fBase.fMaxInclusive});
                    }
                }
            }
        }
        // minExclusive
        needCheckBase = true;
        if ((presentFacet & FACET_MINEXCLUSIVE) != 0) {
            if ((allowedFacet & FACET_MINEXCLUSIVE) == 0) {
                reportError("cos-applicable-facets", new Object[]{"minExclusive", fTypeName});
            } else {
                minExclusiveAnnotation = facets.minExclusiveAnnotation;
                try {
                    fMinExclusive = fBase.getActualValue(facets.minExclusive, context, tempInfo, true);
                    fFacetsDefined |= FACET_MINEXCLUSIVE;
                    if ((fixedFacet & FACET_MINEXCLUSIVE) != 0)
                        fFixedFacet |= FACET_MINEXCLUSIVE;
                } catch (InvalidDatatypeValueException ide) {
                    reportError(ide.getKey(), ide.getArgs());
                    reportError("FacetValueFromBase", new Object[]{fTypeName, facets.minExclusive,
                            "minExclusive", fBase.getName()});
                }

                // check against fixed value in base
                if (((fBase.fFacetsDefined & FACET_MINEXCLUSIVE) != 0)) {
                    result = fDVs[fValidationDV].compare(fMinExclusive, fBase.fMinExclusive);
                    if ((fBase.fFixedFacet & FACET_MINEXCLUSIVE) != 0 && result != 0) {
                        reportError( "FixedFacetValue", new Object[]{"minExclusive", facets.minExclusive, fBase.fMinExclusive, fTypeName});
                    }
                    if (result == 0) {
                        needCheckBase = false;
                    }
                }
                // minExclusive from base
                if (needCheckBase) {
                    try {
                        fBase.validate(context, tempInfo);
                    } catch (InvalidDatatypeValueException ide) {
                        reportError(ide.getKey(), ide.getArgs());
                        reportError("FacetValueFromBase", new Object[]{fTypeName, facets.minExclusive,
                                "minExclusive", fBase.getName()});
                    }
                }
                // If minExclusive == base.minExclusive, then we only need to check
                // minExclusive >= base.minInclusive
                else if (((fBase.fFacetsDefined & FACET_MININCLUSIVE) != 0)) {
                    if (fDVs[fValidationDV].compare(fMinExclusive, fBase.fMinInclusive) < 0) {
                        reportError( "minExclusive-valid-restriction.3", new Object[]{facets.minExclusive, fBase.fMinInclusive});
                    }
                }
            }
        }
        // minInclusive
        if ((presentFacet & FACET_MININCLUSIVE) != 0) {
            if ((allowedFacet & FACET_MININCLUSIVE) == 0) {
                reportError("cos-applicable-facets", new Object[]{"minInclusive", fTypeName});
            } else {
                minInclusiveAnnotation = facets.minInclusiveAnnotation;
                try {
                    fMinInclusive = fBase.getActualValue(facets.minInclusive, context, tempInfo, true);
                    fFacetsDefined |= FACET_MININCLUSIVE;
                    if ((fixedFacet & FACET_MININCLUSIVE) != 0)
                        fFixedFacet |= FACET_MININCLUSIVE;
                } catch (InvalidDatatypeValueException ide) {
                    reportError(ide.getKey(), ide.getArgs());
                    reportError("FacetValueFromBase", new Object[]{fTypeName, facets.minInclusive,
                            "minInclusive", fBase.getName()});
                }

                // check against fixed value in base
                if (((fBase.fFacetsDefined & FACET_MININCLUSIVE) != 0)) {
                    if ((fBase.fFixedFacet & FACET_MININCLUSIVE) != 0) {
                        if (fDVs[fValidationDV].compare(fMinInclusive, fBase.fMinInclusive) != 0)
                            reportError( "FixedFacetValue", new Object[]{"minInclusive", facets.minInclusive, fBase.fMinInclusive, fTypeName});
                    }
                }
                // minInclusive from base
                try {
                    fBase.validate(context, tempInfo);
                } catch (InvalidDatatypeValueException ide) {
                    reportError(ide.getKey(), ide.getArgs());
                    reportError("FacetValueFromBase", new Object[]{fTypeName, facets.minInclusive,
                            "minInclusive", fBase.getName()});
                }
            }
        }

        // totalDigits
        if ((presentFacet & FACET_TOTALDIGITS) != 0) {
            if ((allowedFacet & FACET_TOTALDIGITS) == 0) {
                reportError("cos-applicable-facets", new Object[]{"totalDigits", fTypeName});
            } else {
                totalDigitsAnnotation = facets.totalDigitsAnnotation;
                fTotalDigits = facets.totalDigits;
                fFacetsDefined |= FACET_TOTALDIGITS;
                if ((fixedFacet & FACET_TOTALDIGITS) != 0)
                    fFixedFacet |= FACET_TOTALDIGITS;
            }
        }
        // fractionDigits
        if ((presentFacet & FACET_FRACTIONDIGITS) != 0) {
            if ((allowedFacet & FACET_FRACTIONDIGITS) == 0) {
                reportError("cos-applicable-facets", new Object[]{"fractionDigits", fTypeName});
            } else {
                fFractionDigits = facets.fractionDigits;
                fractionDigitsAnnotation = facets.fractionDigitsAnnotation;
                fFacetsDefined |= FACET_FRACTIONDIGITS;
                if ((fixedFacet & FACET_FRACTIONDIGITS) != 0)
                    fFixedFacet |= FACET_FRACTIONDIGITS;
            }
        }

        // token type: internal use, so do less checking
        if (patternType != SPECIAL_PATTERN_NONE) {
            fPatternType = patternType;
        }

        // step 2: check facets against each other: length, bounds
        if(fFacetsDefined != 0) {

            // check 4.3.2.c1 must: minLength <= maxLength
            if(((fFacetsDefined & FACET_MINLENGTH ) != 0 ) && ((fFacetsDefined & FACET_MAXLENGTH) != 0))
            {
                if(fMinLength > fMaxLength)
                    reportError("minLength-less-than-equal-to-maxLength", new Object[]{Integer.toString(fMinLength), Integer.toString(fMaxLength), fTypeName});
            }

            // check 4.3.8.c1 error: maxInclusive + maxExclusive
            if (((fFacetsDefined & FACET_MAXEXCLUSIVE) != 0) && ((fFacetsDefined & FACET_MAXINCLUSIVE) != 0)) {
                reportError( "maxInclusive-maxExclusive", new Object[]{fMaxInclusive, fMaxExclusive, fTypeName});
            }

            // check 4.3.9.c1 error: minInclusive + minExclusive
            if (((fFacetsDefined & FACET_MINEXCLUSIVE) != 0) && ((fFacetsDefined & FACET_MININCLUSIVE) != 0)) {
                reportError("minInclusive-minExclusive", new Object[]{fMinInclusive, fMinExclusive, fTypeName});
            }

            // check 4.3.7.c1 must: minInclusive <= maxInclusive
            if (((fFacetsDefined &  FACET_MAXINCLUSIVE) != 0) && ((fFacetsDefined & FACET_MININCLUSIVE) != 0)) {
                result = fDVs[fValidationDV].compare(fMinInclusive, fMaxInclusive);
                if (result != -1 && result != 0)
                    reportError("minInclusive-less-than-equal-to-maxInclusive", new Object[]{fMinInclusive, fMaxInclusive, fTypeName});
            }

            // check 4.3.8.c2 must: minExclusive <= maxExclusive ??? minExclusive < maxExclusive
            if (((fFacetsDefined & FACET_MAXEXCLUSIVE) != 0) && ((fFacetsDefined & FACET_MINEXCLUSIVE) != 0)) {
                result = fDVs[fValidationDV].compare(fMinExclusive, fMaxExclusive);
                if (result != -1 && result != 0)
                    reportError( "minExclusive-less-than-equal-to-maxExclusive", new Object[]{fMinExclusive, fMaxExclusive, fTypeName});
            }

            // check 4.3.9.c2 must: minExclusive < maxInclusive
            if (((fFacetsDefined & FACET_MAXINCLUSIVE) != 0) && ((fFacetsDefined & FACET_MINEXCLUSIVE) != 0)) {
                if (fDVs[fValidationDV].compare(fMinExclusive, fMaxInclusive) != -1)
                    reportError( "minExclusive-less-than-maxInclusive", new Object[]{fMinExclusive, fMaxInclusive, fTypeName});
            }

            // check 4.3.10.c1 must: minInclusive < maxExclusive
            if (((fFacetsDefined & FACET_MAXEXCLUSIVE) != 0) && ((fFacetsDefined & FACET_MININCLUSIVE) != 0)) {
                if (fDVs[fValidationDV].compare(fMinInclusive, fMaxExclusive) != -1)
                    reportError( "minInclusive-less-than-maxExclusive", new Object[]{fMinInclusive, fMaxExclusive, fTypeName});
            }

            // check 4.3.12.c1 must: fractionDigits <= totalDigits
            if (((fFacetsDefined & FACET_FRACTIONDIGITS) != 0) &&
                    ((fFacetsDefined & FACET_TOTALDIGITS) != 0)) {
                if (fFractionDigits > fTotalDigits)
                    reportError( "fractionDigits-totalDigits", new Object[]{Integer.toString(fFractionDigits), Integer.toString(fTotalDigits), fTypeName});
            }

            // step 3: check facets against base
            // check 4.3.1.c1 error: length & (fBase.maxLength | fBase.minLength)
            if((fFacetsDefined & FACET_LENGTH) != 0 ){
                if ((fBase.fFacetsDefined & FACET_MINLENGTH) != 0 &&
                        fLength < fBase.fMinLength) {
                    // length, fBase.minLength and fBase.maxLength defined
                    reportError("length-minLength-maxLength.1.1", new Object[]{fTypeName, Integer.toString(fLength), Integer.toString(fBase.fMinLength)});
                }
                if ((fBase.fFacetsDefined & FACET_MAXLENGTH) != 0 &&
                        fLength > fBase.fMaxLength) {
                    // length and fBase.maxLength defined
                    reportError("length-minLength-maxLength.2.1", new Object[]{fTypeName, Integer.toString(fLength), Integer.toString(fBase.fMaxLength)});
                }
                if ( (fBase.fFacetsDefined & FACET_LENGTH) != 0 ) {
                    // check 4.3.1.c2 error: length != fBase.length
                    if ( fLength != fBase.fLength )
                        reportError( "length-valid-restriction", new Object[]{Integer.toString(fLength), Integer.toString(fBase.fLength), fTypeName});
                }
            }

            // check 4.3.1.c1 error: fBase.length & (maxLength | minLength)
            if((fBase.fFacetsDefined & FACET_LENGTH) != 0 || (fFacetsDefined & FACET_LENGTH) != 0){
                if ((fFacetsDefined & FACET_MINLENGTH) != 0){
                    if (fBase.fLength < fMinLength) {
                        // fBase.length, minLength and maxLength defined
                        reportError("length-minLength-maxLength.1.1", new Object[]{fTypeName, Integer.toString(fBase.fLength), Integer.toString(fMinLength)});
                    }
                    if ((fBase.fFacetsDefined & FACET_MINLENGTH) == 0){
                        reportError("length-minLength-maxLength.1.2.a", new Object[]{fTypeName});
                    }
                    if (fMinLength != fBase.fMinLength){
                        reportError("length-minLength-maxLength.1.2.b", new Object[]{fTypeName, Integer.toString(fMinLength), Integer.toString(fBase.fMinLength)});
                    }
                }
                if ((fFacetsDefined & FACET_MAXLENGTH) != 0){
                    if (fBase.fLength > fMaxLength) {
                        // fBase.length, minLength and maxLength defined
                        reportError("length-minLength-maxLength.2.1", new Object[]{fTypeName, Integer.toString(fBase.fLength), Integer.toString(fMaxLength)});
                    }
                    if ((fBase.fFacetsDefined & FACET_MAXLENGTH) == 0){
                        reportError("length-minLength-maxLength.2.2.a", new Object[]{fTypeName});
                    }
                    if (fMaxLength != fBase.fMaxLength){
                        reportError("length-minLength-maxLength.2.2.b", new Object[]{fTypeName, Integer.toString(fMaxLength), Integer.toString(fBase.fBase.fMaxLength)});
                    }
                }
            }

            // check 4.3.2.c1 must: minLength <= fBase.maxLength
            if ( ((fFacetsDefined & FACET_MINLENGTH ) != 0 ) ) {
                if ( (fBase.fFacetsDefined & FACET_MAXLENGTH ) != 0 ) {
                    if ( fMinLength > fBase.fMaxLength ) {
                        reportError("minLength-less-than-equal-to-maxLength", new Object[]{Integer.toString(fMinLength), Integer.toString(fBase.fMaxLength), fTypeName});
                    }
                }
                else if ( (fBase.fFacetsDefined & FACET_MINLENGTH) != 0 ) {
                    if ( (fBase.fFixedFacet & FACET_MINLENGTH) != 0 && fMinLength != fBase.fMinLength ) {
                        reportError( "FixedFacetValue", new Object[]{"minLength", Integer.toString(fMinLength), Integer.toString(fBase.fMinLength), fTypeName});
                    }

                    // check 4.3.2.c2 error: minLength < fBase.minLength
                    if ( fMinLength < fBase.fMinLength ) {
                        reportError( "minLength-valid-restriction", new Object[]{Integer.toString(fMinLength), Integer.toString(fBase.fMinLength), fTypeName});
                    }
                }
            }


            // check 4.3.2.c1 must: maxLength < fBase.minLength
            if ( ((fFacetsDefined & FACET_MAXLENGTH ) != 0 ) && ((fBase.fFacetsDefined & FACET_MINLENGTH ) != 0 )) {
                if ( fMaxLength < fBase.fMinLength) {
                    reportError("minLength-less-than-equal-to-maxLength", new Object[]{Integer.toString(fBase.fMinLength), Integer.toString(fMaxLength)});
                }
            }

            // check 4.3.3.c1 error: maxLength > fBase.maxLength
            if ( (fFacetsDefined & FACET_MAXLENGTH) != 0 ) {
                if ( (fBase.fFacetsDefined & FACET_MAXLENGTH) != 0 ){
                    if(( (fBase.fFixedFacet & FACET_MAXLENGTH) != 0 )&& fMaxLength != fBase.fMaxLength ) {
                        reportError( "FixedFacetValue", new Object[]{"maxLength", Integer.toString(fMaxLength), Integer.toString(fBase.fMaxLength), fTypeName});
                    }
                    if ( fMaxLength > fBase.fMaxLength ) {
                        reportError( "maxLength-valid-restriction", new Object[]{Integer.toString(fMaxLength), Integer.toString(fBase.fMaxLength), fTypeName});
                    }
                }
            }

            /*          // check 4.3.7.c2 error:
                         // maxInclusive > fBase.maxInclusive
                          // maxInclusive >= fBase.maxExclusive
                           // maxInclusive < fBase.minInclusive
                            // maxInclusive <= fBase.minExclusive

                             if (((fFacetsDefined & FACET_MAXINCLUSIVE) != 0)) {
                             if (((fBase.fFacetsDefined & FACET_MAXINCLUSIVE) != 0)) {
                             result = fDVs[fValidationDV].compare(fMaxInclusive, fBase.fMaxInclusive);
                             if ((fBase.fFixedFacet & FACET_MAXINCLUSIVE) != 0 && result != 0) {
                             reportError( "FixedFacetValue", new Object[]{"maxInclusive", fMaxInclusive, fBase.fMaxInclusive, fTypeName});
                             }
                             if (result != -1 && result != 0) {
                             reportError( "maxInclusive-valid-restriction.1", new Object[]{fMaxInclusive, fBase.fMaxInclusive, fTypeName});
                             }
                             }
                             if (((fBase.fFacetsDefined & FACET_MAXEXCLUSIVE) != 0) &&
                             fDVs[fValidationDV].compare(fMaxInclusive, fBase.fMaxExclusive) != -1){
                             reportError( "maxInclusive-valid-restriction.1", new Object[]{fMaxInclusive, fBase.fMaxExclusive, fTypeName});
                             }

                             if ((( fBase.fFacetsDefined & FACET_MININCLUSIVE) != 0)) {
                             result = fDVs[fValidationDV].compare(fMaxInclusive, fBase.fMinInclusive);
                             if (result != 1 && result != 0) {
                             reportError( "maxInclusive-valid-restriction.1", new Object[]{fMaxInclusive, fBase.fMinInclusive, fTypeName});
                             }
                             }

                             if ((( fBase.fFacetsDefined & FACET_MINEXCLUSIVE) != 0) &&
                             fDVs[fValidationDV].compare(fMaxInclusive, fBase.fMinExclusive ) != 1)
                             reportError( "maxInclusive-valid-restriction.1", new Object[]{fMaxInclusive, fBase.fMinExclusive, fTypeName});
                             }

                             // check 4.3.8.c3 error:
                              // maxExclusive > fBase.maxExclusive
                               // maxExclusive > fBase.maxInclusive
                                // maxExclusive <= fBase.minInclusive
                                 // maxExclusive <= fBase.minExclusive
                                  if (((fFacetsDefined & FACET_MAXEXCLUSIVE) != 0)) {
                                  if ((( fBase.fFacetsDefined & FACET_MAXEXCLUSIVE) != 0)) {
                                  result= fDVs[fValidationDV].compare(fMaxExclusive, fBase.fMaxExclusive);
                                  if ((fBase.fFixedFacet & FACET_MAXEXCLUSIVE) != 0 &&  result != 0) {
                                  reportError( "FixedFacetValue", new Object[]{"maxExclusive", fMaxExclusive, fBase.fMaxExclusive, fTypeName});
                                  }
                                  if (result != -1 && result != 0) {
                                  reportError( "maxExclusive-valid-restriction.1", new Object[]{fMaxExclusive, fBase.fMaxExclusive, fTypeName});
                                  }
                                  }

                                  if ((( fBase.fFacetsDefined & FACET_MAXINCLUSIVE) != 0)) {
                                  result= fDVs[fValidationDV].compare(fMaxExclusive, fBase.fMaxInclusive);
                                  if (result != -1 && result != 0) {
                                  reportError( "maxExclusive-valid-restriction.2", new Object[]{fMaxExclusive, fBase.fMaxInclusive, fTypeName});
                                  }
                                  }

                                  if ((( fBase.fFacetsDefined & FACET_MINEXCLUSIVE) != 0) &&
                                  fDVs[fValidationDV].compare(fMaxExclusive, fBase.fMinExclusive ) != 1)
                                  reportError( "maxExclusive-valid-restriction.3", new Object[]{fMaxExclusive, fBase.fMinExclusive, fTypeName});

                                  if ((( fBase.fFacetsDefined & FACET_MININCLUSIVE) != 0) &&
                                  fDVs[fValidationDV].compare(fMaxExclusive, fBase.fMinInclusive) != 1)
                                  reportError( "maxExclusive-valid-restriction.4", new Object[]{fMaxExclusive, fBase.fMinInclusive, fTypeName});
                                  }

                                  // check 4.3.9.c3 error:
                                   // minExclusive < fBase.minExclusive
                                    // minExclusive > fBase.maxInclusive
                                     // minExclusive < fBase.minInclusive
                                      // minExclusive >= fBase.maxExclusive
                                       if (((fFacetsDefined & FACET_MINEXCLUSIVE) != 0)) {
                                       if ((( fBase.fFacetsDefined & FACET_MINEXCLUSIVE) != 0)) {
                                       result= fDVs[fValidationDV].compare(fMinExclusive, fBase.fMinExclusive);
                                       if ((fBase.fFixedFacet & FACET_MINEXCLUSIVE) != 0 && result != 0) {
                                       reportError( "FixedFacetValue", new Object[]{"minExclusive", fMinExclusive, fBase.fMinExclusive, fTypeName});
                                       }
                                       if (result != 1 && result != 0) {
                                       reportError( "minExclusive-valid-restriction.1", new Object[]{fMinExclusive, fBase.fMinExclusive, fTypeName});
                                       }
                                       }

                                       if ((( fBase.fFacetsDefined & FACET_MAXINCLUSIVE) != 0)) {
                                       result=fDVs[fValidationDV].compare(fMinExclusive, fBase.fMaxInclusive);

                                       if (result != -1 && result != 0) {
                                       reportError( "minExclusive-valid-restriction.2", new Object[]{fMinExclusive, fBase.fMaxInclusive, fTypeName});
                                       }
                                       }

                                       if ((( fBase.fFacetsDefined & FACET_MININCLUSIVE) != 0)) {
                                       result = fDVs[fValidationDV].compare(fMinExclusive, fBase.fMinInclusive);

                                       if (result != 1 && result != 0) {
                                       reportError( "minExclusive-valid-restriction.3", new Object[]{fMinExclusive, fBase.fMinInclusive, fTypeName});
                                       }
                                       }

                                       if ((( fBase.fFacetsDefined & FACET_MAXEXCLUSIVE) != 0) &&
                                       fDVs[fValidationDV].compare(fMinExclusive, fBase.fMaxExclusive) != -1)
                                       reportError( "minExclusive-valid-restriction.4", new Object[]{fMinExclusive, fBase.fMaxExclusive, fTypeName});
                                       }

                                       // check 4.3.10.c2 error:
                                        // minInclusive < fBase.minInclusive
                                         // minInclusive > fBase.maxInclusive
                                          // minInclusive <= fBase.minExclusive
                                           // minInclusive >= fBase.maxExclusive
                                            if (((fFacetsDefined & FACET_MININCLUSIVE) != 0)) {
                                            if (((fBase.fFacetsDefined & FACET_MININCLUSIVE) != 0)) {
                                            result = fDVs[fValidationDV].compare(fMinInclusive, fBase.fMinInclusive);

                                            if ((fBase.fFixedFacet & FACET_MININCLUSIVE) != 0 && result != 0) {
                                            reportError( "FixedFacetValue", new Object[]{"minInclusive", fMinInclusive, fBase.fMinInclusive, fTypeName});
                                            }
                                            if (result != 1 && result != 0) {
                                            reportError( "minInclusive-valid-restriction.1", new Object[]{fMinInclusive, fBase.fMinInclusive, fTypeName});
                                            }
                                            }
                                            if ((( fBase.fFacetsDefined & FACET_MAXINCLUSIVE) != 0)) {
                                            result=fDVs[fValidationDV].compare(fMinInclusive, fBase.fMaxInclusive);
                                            if (result != -1 && result != 0) {
                                            reportError( "minInclusive-valid-restriction.2", new Object[]{fMinInclusive, fBase.fMaxInclusive, fTypeName});
                                            }
                                            }
                                            if ((( fBase.fFacetsDefined & FACET_MINEXCLUSIVE) != 0) &&
                                            fDVs[fValidationDV].compare(fMinInclusive, fBase.fMinExclusive ) != 1)
                                            reportError( "minInclusive-valid-restriction.3", new Object[]{fMinInclusive, fBase.fMinExclusive, fTypeName});
                                            if ((( fBase.fFacetsDefined & FACET_MAXEXCLUSIVE) != 0) &&
                                            fDVs[fValidationDV].compare(fMinInclusive, fBase.fMaxExclusive) != -1)
                                            reportError( "minInclusive-valid-restriction.4", new Object[]{fMinInclusive, fBase.fMaxExclusive, fTypeName});
                                            }
             */
            // check 4.3.11.c1 error: totalDigits > fBase.totalDigits
            if (((fFacetsDefined & FACET_TOTALDIGITS) != 0)) {
                if ((( fBase.fFacetsDefined & FACET_TOTALDIGITS) != 0)) {
                    if ((fBase.fFixedFacet & FACET_TOTALDIGITS) != 0 && fTotalDigits != fBase.fTotalDigits) {
                        reportError("FixedFacetValue", new Object[]{"totalDigits", Integer.toString(fTotalDigits), Integer.toString(fBase.fTotalDigits), fTypeName});
                    }
                    if (fTotalDigits > fBase.fTotalDigits) {
                        reportError( "totalDigits-valid-restriction", new Object[]{Integer.toString(fTotalDigits), Integer.toString(fBase.fTotalDigits), fTypeName});
                    }
                }
            }

            // check 4.3.12.c1 must: fractionDigits <= base.totalDigits
            if ((fFacetsDefined & FACET_FRACTIONDIGITS) != 0) {
                if ((fBase.fFacetsDefined & FACET_TOTALDIGITS) != 0) {
                    if (fFractionDigits > fBase.fTotalDigits)
                        reportError( "fractionDigits-totalDigits", new Object[]{Integer.toString(fFractionDigits), Integer.toString(fTotalDigits), fTypeName});
                }
            }

            // check 4.3.12.c2 error: fractionDigits > fBase.fractionDigits
            // check fixed value for fractionDigits
            if (((fFacetsDefined & FACET_FRACTIONDIGITS) != 0)) {
                if ((( fBase.fFacetsDefined & FACET_FRACTIONDIGITS) != 0)) {
                    if (((fBase.fFixedFacet & FACET_FRACTIONDIGITS) != 0 && fFractionDigits != fBase.fFractionDigits) ||
                            (fValidationDV == DV_INTEGER && fFractionDigits != 0)) {
                        reportError("FixedFacetValue", new Object[]{"fractionDigits", Integer.toString(fFractionDigits), Integer.toString(fBase.fFractionDigits), fTypeName});
                    }
                    if (fFractionDigits > fBase.fFractionDigits) {
                        reportError( "fractionDigits-valid-restriction", new Object[]{Integer.toString(fFractionDigits), Integer.toString(fBase.fFractionDigits), fTypeName});
                    }
                }
                else if (fValidationDV == DV_INTEGER && fFractionDigits != 0) {
                    reportError("FixedFacetValue", new Object[]{"fractionDigits", Integer.toString(fFractionDigits), "0", fTypeName});
                }
            }

            // check 4.3.6.c1 error:
            // (whiteSpace = preserve || whiteSpace = replace) && fBase.whiteSpace = collapese or
            // whiteSpace = preserve && fBase.whiteSpace = replace

            if ( (fFacetsDefined & FACET_WHITESPACE) != 0 && (fBase.fFacetsDefined & FACET_WHITESPACE) != 0 ){
                if ( (fBase.fFixedFacet & FACET_WHITESPACE) != 0 &&  fWhiteSpace != fBase.fWhiteSpace ) {
                    reportError( "FixedFacetValue", new Object[]{"whiteSpace", whiteSpaceValue(fWhiteSpace), whiteSpaceValue(fBase.fWhiteSpace), fTypeName});
                }

                if ( fWhiteSpace == WS_PRESERVE &&  fBase.fWhiteSpace == WS_COLLAPSE ){
                    reportError( "whiteSpace-valid-restriction.1", new Object[]{fTypeName, "preserve"});
                }
                if ( fWhiteSpace == WS_REPLACE &&  fBase.fWhiteSpace == WS_COLLAPSE ){
                    reportError( "whiteSpace-valid-restriction.1", new Object[]{fTypeName, "replace"});
                }
                if ( fWhiteSpace == WS_PRESERVE &&  fBase.fWhiteSpace == WS_REPLACE ){
                    reportError( "whiteSpace-valid-restriction.2", new Object[]{fTypeName});
                }
            }
        }//fFacetsDefined != null

        // step 4: inherit other facets from base (including fTokeyType)

        // inherit length
        if ( (fFacetsDefined & FACET_LENGTH) == 0  && (fBase.fFacetsDefined & FACET_LENGTH) != 0 ) {
            fFacetsDefined |= FACET_LENGTH;
            fLength = fBase.fLength;
            lengthAnnotation = fBase.lengthAnnotation;
        }
        // inherit minLength
        if ( (fFacetsDefined & FACET_MINLENGTH) == 0 && (fBase.fFacetsDefined & FACET_MINLENGTH) != 0 ) {
            fFacetsDefined |= FACET_MINLENGTH;
            fMinLength = fBase.fMinLength;
            minLengthAnnotation = fBase.minLengthAnnotation;
        }
        // inherit maxLength
        if ((fFacetsDefined & FACET_MAXLENGTH) == 0 &&  (fBase.fFacetsDefined & FACET_MAXLENGTH) != 0 ) {
            fFacetsDefined |= FACET_MAXLENGTH;
            fMaxLength = fBase.fMaxLength;
            maxLengthAnnotation = fBase.maxLengthAnnotation;
        }
        // inherit pattern
        if ( (fBase.fFacetsDefined & FACET_PATTERN) != 0 ) {
            if ((fFacetsDefined & FACET_PATTERN) == 0) {
                fFacetsDefined |= FACET_PATTERN;
                fPattern = fBase.fPattern;
                fPatternStr = fBase.fPatternStr;
                patternAnnotations = fBase.patternAnnotations;
            }
            else {
                for (int i = fBase.fPattern.size()-1; i >= 0; --i) {
                    fPattern.addElement(fBase.fPattern.elementAt(i));
                    fPatternStr.addElement(fBase.fPatternStr.elementAt(i));
                }
                if (fBase.patternAnnotations != null) {
                    if (patternAnnotations != null) {
                        for (int i = fBase.patternAnnotations.getLength()-1; i >= 0; --i) {
                            patternAnnotations.addXSObject(fBase.patternAnnotations.item(i));
                        }
                    }
                    else {
                        patternAnnotations = fBase.patternAnnotations;
                    }
                }
            }
        }
        // inherit whiteSpace
        if ( (fFacetsDefined & FACET_WHITESPACE) == 0 &&  (fBase.fFacetsDefined & FACET_WHITESPACE) != 0 ) {
            fFacetsDefined |= FACET_WHITESPACE;
            fWhiteSpace = fBase.fWhiteSpace;
            whiteSpaceAnnotation = fBase.whiteSpaceAnnotation;
        }
        // inherit enumeration
        if ((fFacetsDefined & FACET_ENUMERATION) == 0 && (fBase.fFacetsDefined & FACET_ENUMERATION) != 0) {
            fFacetsDefined |= FACET_ENUMERATION;
            fEnumeration = fBase.fEnumeration;
            enumerationAnnotations = fBase.enumerationAnnotations;
        }
        // inherit maxExclusive
        if ((( fBase.fFacetsDefined & FACET_MAXEXCLUSIVE) != 0) &&
                !((fFacetsDefined & FACET_MAXEXCLUSIVE) != 0) && !((fFacetsDefined & FACET_MAXINCLUSIVE) != 0)) {
            fFacetsDefined |= FACET_MAXEXCLUSIVE;
            fMaxExclusive = fBase.fMaxExclusive;
            maxExclusiveAnnotation = fBase.maxExclusiveAnnotation;
        }
        // inherit maxInclusive
        if ((( fBase.fFacetsDefined & FACET_MAXINCLUSIVE) != 0) &&
                !((fFacetsDefined & FACET_MAXEXCLUSIVE) != 0) && !((fFacetsDefined & FACET_MAXINCLUSIVE) != 0)) {
            fFacetsDefined |= FACET_MAXINCLUSIVE;
            fMaxInclusive = fBase.fMaxInclusive;
            maxInclusiveAnnotation = fBase.maxInclusiveAnnotation;
        }
        // inherit minExclusive
        if ((( fBase.fFacetsDefined & FACET_MINEXCLUSIVE) != 0) &&
                !((fFacetsDefined & FACET_MINEXCLUSIVE) != 0) && !((fFacetsDefined & FACET_MININCLUSIVE) != 0)) {
            fFacetsDefined |= FACET_MINEXCLUSIVE;
            fMinExclusive = fBase.fMinExclusive;
            minExclusiveAnnotation = fBase.minExclusiveAnnotation;
        }
        // inherit minExclusive
        if ((( fBase.fFacetsDefined & FACET_MININCLUSIVE) != 0) &&
                !((fFacetsDefined & FACET_MINEXCLUSIVE) != 0) && !((fFacetsDefined & FACET_MININCLUSIVE) != 0)) {
            fFacetsDefined |= FACET_MININCLUSIVE;
            fMinInclusive = fBase.fMinInclusive;
            minInclusiveAnnotation = fBase.minInclusiveAnnotation;
        }
        // inherit totalDigits
        if ((( fBase.fFacetsDefined & FACET_TOTALDIGITS) != 0) &&
                !((fFacetsDefined & FACET_TOTALDIGITS) != 0)) {
            fFacetsDefined |= FACET_TOTALDIGITS;
            fTotalDigits = fBase.fTotalDigits;
            totalDigitsAnnotation = fBase.totalDigitsAnnotation;
        }
        // inherit fractionDigits
        if ((( fBase.fFacetsDefined & FACET_FRACTIONDIGITS) != 0)
                && !((fFacetsDefined & FACET_FRACTIONDIGITS) != 0)) {
            fFacetsDefined |= FACET_FRACTIONDIGITS;
            fFractionDigits = fBase.fFractionDigits;
            fractionDigitsAnnotation = fBase.fractionDigitsAnnotation;
        }
        //inherit tokeytype
        if ((fPatternType == SPECIAL_PATTERN_NONE ) && (fBase.fPatternType != SPECIAL_PATTERN_NONE)) {
            fPatternType = fBase.fPatternType ;
        }

        // step 5: mark fixed values
        fFixedFacet |= fBase.fFixedFacet;

        //step 6: setting fundamental facets
        calcFundamentalFacets();

    } //applyFacets()

    /**
     * validate a value, and return the compiled form
     */
    public Object validate(String content, ValidationContext context, ValidatedInfo validatedInfo) throws InvalidDatatypeValueException {

        if (context == null)
            context = fEmptyContext;

        if (validatedInfo == null)
            validatedInfo = new ValidatedInfo();
        else
            validatedInfo.memberType = null;

        // first normalize string value, and convert it to actual value
        boolean needNormalize = context==null||context.needToNormalize();
        Object ob = getActualValue(content, context, validatedInfo, needNormalize);

        validate(context, validatedInfo);

        return ob;

    }

    protected ValidatedInfo getActualEnumValue(String lexical, ValidationContext ctx, ValidatedInfo info)
    throws InvalidDatatypeValueException {
        return fBase.validateWithInfo(lexical, ctx, info);
    }

    /**
     * validate a value, and return the compiled form
     */
    public ValidatedInfo validateWithInfo(String content, ValidationContext context, ValidatedInfo validatedInfo) throws InvalidDatatypeValueException {

        if (context == null)
            context = fEmptyContext;

        if (validatedInfo == null)
            validatedInfo = new ValidatedInfo();
        else
            validatedInfo.memberType = null;

        // first normalize string value, and convert it to actual value
        boolean needNormalize = context==null||context.needToNormalize();
        getActualValue(content, context, validatedInfo, needNormalize);

        validate(context, validatedInfo);

        return validatedInfo;

    }

    /**
     * validate a value, and return the compiled form
     */
    public Object validate(Object content, ValidationContext context, ValidatedInfo validatedInfo) throws InvalidDatatypeValueException {

        if (context == null)
            context = fEmptyContext;

        if (validatedInfo == null)
            validatedInfo = new ValidatedInfo();
        else
            validatedInfo.memberType = null;

        // first normalize string value, and convert it to actual value
        boolean needNormalize = context==null||context.needToNormalize();
        Object ob = getActualValue(content, context, validatedInfo, needNormalize);

        validate(context, validatedInfo);

        return ob;

    }

    /**
     * validate an actual value against this DV
     *
     * @param context       the validation context
     * @param validatedInfo used to provide the actual value and member types
     */
    public void validate(ValidationContext context, ValidatedInfo validatedInfo)
        throws InvalidDatatypeValueException {

        if (context == null)
            context = fEmptyContext;

        // then validate the actual value against the facets
        if (context.needFacetChecking() &&
                (fFacetsDefined != 0 && fFacetsDefined != FACET_WHITESPACE)) {
            checkFacets(validatedInfo);
        }

        // now check extra rules: for ID/IDREF/ENTITY
        if (context.needExtraChecking()) {
            checkExtraRules(context, validatedInfo);
        }

    }

    private void checkFacets(ValidatedInfo validatedInfo) throws InvalidDatatypeValueException {

        Object ob = validatedInfo.actualValue;
        String content = validatedInfo.normalizedValue;
        short type = validatedInfo.actualValueType;
        ShortList itemType = validatedInfo.itemValueTypes;

        // For QName and NOTATION types, we don't check length facets
        if (fValidationDV != DV_QNAME && fValidationDV != DV_NOTATION) {
            int length = fDVs[fValidationDV].getDataLength(ob);

            // maxLength
            if ( (fFacetsDefined & FACET_MAXLENGTH) != 0 ) {
                if ( length > fMaxLength ) {
                    throw new InvalidDatatypeValueException("cvc-maxLength-valid",
                            new Object[]{content, Integer.toString(length), Integer.toString(fMaxLength), fTypeName});
                }
            }

            //minLength
            if ( (fFacetsDefined & FACET_MINLENGTH) != 0 ) {
                if ( length < fMinLength ) {
                    throw new InvalidDatatypeValueException("cvc-minLength-valid",
                            new Object[]{content, Integer.toString(length), Integer.toString(fMinLength), fTypeName});
                }
            }

            //length
            if ( (fFacetsDefined & FACET_LENGTH) != 0 ) {
                if ( length != fLength ) {
                    throw new InvalidDatatypeValueException("cvc-length-valid",
                            new Object[]{content, Integer.toString(length), Integer.toString(fLength), fTypeName});
                }
            }
        }

        //enumeration
        if ( ((fFacetsDefined & FACET_ENUMERATION) != 0 ) ) {
            boolean present = false;
            final int enumSize = fEnumeration.size();
            final short primitiveType1 = convertToPrimitiveKind(type);
            for (int i = 0; i < enumSize; i++) {
                final short primitiveType2 = convertToPrimitiveKind(fEnumerationType[i]);
                if ((primitiveType1 == primitiveType2 ||
                        primitiveType1 == XSConstants.ANYSIMPLETYPE_DT && primitiveType2 == XSConstants.STRING_DT ||
                        primitiveType1 == XSConstants.STRING_DT && primitiveType2 == XSConstants.ANYSIMPLETYPE_DT)
                        && fEnumeration.elementAt(i).equals(ob)) {
                    if (primitiveType1 == XSConstants.LIST_DT || primitiveType1 == XSConstants.LISTOFUNION_DT) {
                        ShortList enumItemType = fEnumerationItemType[i];
                        final int typeList1Length = itemType != null ? itemType.getLength() : 0;
                        final int typeList2Length = enumItemType != null ? enumItemType.getLength() : 0;
                        if (typeList1Length == typeList2Length) {
                            int j;
                            for (j = 0; j < typeList1Length; ++j) {
                                final short primitiveItem1 = convertToPrimitiveKind(itemType.item(j));
                                final short primitiveItem2 = convertToPrimitiveKind(enumItemType.item(j));
                                if (primitiveItem1 != primitiveItem2) {
                                    if (primitiveItem1 == XSConstants.ANYSIMPLETYPE_DT && primitiveItem2 == XSConstants.STRING_DT ||
                                            primitiveItem1 == XSConstants.STRING_DT && primitiveItem2 == XSConstants.ANYSIMPLETYPE_DT) {
                                        continue;
                                    }
                                    break;
                                }
                            }
                            if (j == typeList1Length) {
                                present = true;
                                break;
                            }
                        }
                    }
                    else {
                        present = true;
                        break;
                    }
                }
            }
            if(!present){
                throw new InvalidDatatypeValueException("cvc-enumeration-valid",
                        new Object [] {content, fEnumeration.toString()});
            }
        }

        //fractionDigits
        if ((fFacetsDefined & FACET_FRACTIONDIGITS) != 0) {
            int scale = fDVs[fValidationDV].getFractionDigits(ob);
            if (scale > fFractionDigits) {
                throw new InvalidDatatypeValueException("cvc-fractionDigits-valid",
                        new Object[] {content, Integer.toString(scale), Integer.toString(fFractionDigits)});
            }
        }

        //totalDigits
        if ((fFacetsDefined & FACET_TOTALDIGITS)!=0) {
            int totalDigits = fDVs[fValidationDV].getTotalDigits(ob);
            if (totalDigits > fTotalDigits) {
                throw new InvalidDatatypeValueException("cvc-totalDigits-valid",
                        new Object[] {content, Integer.toString(totalDigits), Integer.toString(fTotalDigits)});
            }
        }

        int compare;

        //maxinclusive
        if ( (fFacetsDefined & FACET_MAXINCLUSIVE) != 0 ) {
            compare = fDVs[fValidationDV].compare(ob, fMaxInclusive);
            if (compare != -1 && compare != 0) {
                throw new InvalidDatatypeValueException("cvc-maxInclusive-valid",
                        new Object[] {content, fMaxInclusive, fTypeName});
            }
        }

        //maxExclusive
        if ( (fFacetsDefined & FACET_MAXEXCLUSIVE) != 0 ) {
            compare = fDVs[fValidationDV].compare(ob, fMaxExclusive );
            if (compare != -1) {
                throw new InvalidDatatypeValueException("cvc-maxExclusive-valid",
                        new Object[] {content, fMaxExclusive, fTypeName});
            }
        }

        //minInclusive
        if ( (fFacetsDefined & FACET_MININCLUSIVE) != 0 ) {
            compare = fDVs[fValidationDV].compare(ob, fMinInclusive);
            if (compare != 1 && compare != 0) {
                throw new InvalidDatatypeValueException("cvc-minInclusive-valid",
                        new Object[] {content, fMinInclusive, fTypeName});
            }
        }

        //minExclusive
        if ( (fFacetsDefined & FACET_MINEXCLUSIVE) != 0 ) {
            compare = fDVs[fValidationDV].compare(ob, fMinExclusive);
            if (compare != 1) {
                throw new InvalidDatatypeValueException("cvc-minExclusive-valid",
                        new Object[] {content, fMinExclusive, fTypeName});
            }
        }

    }

    private void checkExtraRules(ValidationContext context, ValidatedInfo validatedInfo) throws InvalidDatatypeValueException {

        Object ob = validatedInfo.actualValue;

        if (fVariety == VARIETY_ATOMIC) {

            fDVs[fValidationDV].checkExtraRules(ob, context);

        } else if (fVariety == VARIETY_LIST) {

            ListDV.ListData values = (ListDV.ListData)ob;
            XSSimpleType memberType = validatedInfo.memberType;
            int len = values.getLength();
            try {
                if (fItemType.fVariety == VARIETY_UNION) {
                    XSSimpleTypeDecl[] memberTypes = (XSSimpleTypeDecl[])validatedInfo.memberTypes;
                    for (int i = len-1; i >= 0; i--) {
                        validatedInfo.actualValue = values.item(i);
                        validatedInfo.memberType = memberTypes[i];
                        fItemType.checkExtraRules(context, validatedInfo);
                    }
                } else { // (fVariety == VARIETY_ATOMIC)
                    for (int i = len-1; i >= 0; i--) {
                        validatedInfo.actualValue = values.item(i);
                        fItemType.checkExtraRules(context, validatedInfo);
                    }
                }
            }
            finally {
                validatedInfo.actualValue = values;
                validatedInfo.memberType = memberType;
            }

        } else { // (fVariety == VARIETY_UNION)

            ((XSSimpleTypeDecl)validatedInfo.memberType).checkExtraRules(context, validatedInfo);

        }

    }// checkExtraRules()

    //we can still return object for internal use.
    private Object getActualValue(Object content, ValidationContext context,
            ValidatedInfo validatedInfo, boolean needNormalize)
    throws InvalidDatatypeValueException{

        String nvalue;
        if (needNormalize) {
            nvalue = normalize(content, fWhiteSpace);
        } else {
            nvalue = content.toString();
        }
        if ( (fFacetsDefined & FACET_PATTERN ) != 0 ) {
            if (fPattern.size()==0 && nvalue.length()>0) {
                        throw new InvalidDatatypeValueException("cvc-pattern-valid",
                                new Object[]{content,
                                "(empty string)",
                                fTypeName});
            }
            RegularExpression regex;
            for (int idx = fPattern.size()-1; idx >= 0; idx--) {
                regex = (RegularExpression)fPattern.elementAt(idx);
                if (!regex.matches(nvalue)){
                    throw new InvalidDatatypeValueException("cvc-pattern-valid",
                            new Object[]{content,
                            fPatternStr.elementAt(idx),
                            fTypeName});
                }
            }
        }

        if (fVariety == VARIETY_ATOMIC) {

            // validate special kinds of token, in place of old pattern matching
            if (fPatternType != SPECIAL_PATTERN_NONE) {

                boolean seenErr = false;
                if (fPatternType == SPECIAL_PATTERN_NMTOKEN) {
                    // PATTERN "\\c+"
                    seenErr = !XMLChar.isValidNmtoken(nvalue);
                }
                else if (fPatternType == SPECIAL_PATTERN_NAME) {
                    // PATTERN "\\i\\c*"
                    seenErr = !XMLChar.isValidName(nvalue);
                }
                else if (fPatternType == SPECIAL_PATTERN_NCNAME) {
                    // PATTERN "[\\i-[:]][\\c-[:]]*"
                    seenErr = !XMLChar.isValidNCName(nvalue);
                }
                if (seenErr) {
                    throw new InvalidDatatypeValueException("cvc-datatype-valid.1.2.1",
                            new Object[]{nvalue, SPECIAL_PATTERN_STRING[fPatternType]});
                }
            }

            validatedInfo.normalizedValue = nvalue;
            Object avalue = fDVs[fValidationDV].getActualValue(nvalue, context);
            validatedInfo.actualValue = avalue;
            validatedInfo.actualValueType = fBuiltInKind;

            return avalue;

        } else if (fVariety == VARIETY_LIST) {

            StringTokenizer parsedList = new StringTokenizer(nvalue, " ");
            int countOfTokens = parsedList.countTokens() ;
            Object[] avalue = new Object[countOfTokens];
            boolean isUnion = fItemType.getVariety() == VARIETY_UNION;
            short[] itemTypes = new short[isUnion ? countOfTokens : 1];
            if (!isUnion)
                itemTypes[0] = fItemType.fBuiltInKind;
            XSSimpleTypeDecl[] memberTypes = new XSSimpleTypeDecl[countOfTokens];
            for(int i = 0 ; i < countOfTokens ; i ++){
                // we can't call fItemType.validate(), otherwise checkExtraRules()
                // will be called twice: once in fItemType.validate, once in
                // validate method of this type.
                // so we take two steps to get the actual value:
                // 1. fItemType.getActualValue()
                // 2. fItemType.chekcFacets()
                avalue[i] = fItemType.getActualValue(parsedList.nextToken(), context, validatedInfo, false);
                if (context.needFacetChecking() &&
                        (fItemType.fFacetsDefined != 0 && fItemType.fFacetsDefined != FACET_WHITESPACE)) {
                    fItemType.checkFacets(validatedInfo);
                }
                memberTypes[i] = (XSSimpleTypeDecl)validatedInfo.memberType;
                if (isUnion)
                    itemTypes[i] = memberTypes[i].fBuiltInKind;
            }

            ListDV.ListData v = new ListDV.ListData(avalue);
            validatedInfo.actualValue = v;
            validatedInfo.actualValueType = isUnion ? XSConstants.LISTOFUNION_DT : XSConstants.LIST_DT;
            validatedInfo.memberType = null;
            validatedInfo.memberTypes = memberTypes;
            validatedInfo.itemValueTypes = new ShortListImpl(itemTypes, itemTypes.length);
            validatedInfo.normalizedValue = nvalue;

            return v;

        } else { // (fVariety == VARIETY_UNION)
            final Object _content = (fMemberTypes.length > 1 && content != null) ? content.toString() : content;
            for (int i = 0; i < fMemberTypes.length; i++) {
                try {
                    // we can't call fMemberType[i].validate(), otherwise checkExtraRules()
                    // will be called twice: once in fMemberType[i].validate, once in
                    // validate method of this type.
                    // so we take two steps to get the actual value:
                    // 1. fMemberType[i].getActualValue()
                    // 2. fMemberType[i].chekcFacets()
                    Object aValue = fMemberTypes[i].getActualValue(_content, context, validatedInfo, true);
                    if (context.needFacetChecking() &&
                            (fMemberTypes[i].fFacetsDefined != 0 && fMemberTypes[i].fFacetsDefined != FACET_WHITESPACE)) {
                        fMemberTypes[i].checkFacets(validatedInfo);
                    }
                    validatedInfo.memberType = fMemberTypes[i];
                    return aValue;
                } catch(InvalidDatatypeValueException invalidValue) {
                }
            }
            StringBuffer typesBuffer = new StringBuffer();
            XSSimpleTypeDecl decl;
            for(int i = 0;i < fMemberTypes.length; i++) {
                if(i != 0)
                    typesBuffer.append(" | ");
                decl = fMemberTypes[i];
                if(decl.fTargetNamespace != null) {
                    typesBuffer.append('{');
                    typesBuffer.append(decl.fTargetNamespace);
                    typesBuffer.append('}');
                }
                typesBuffer.append(decl.fTypeName);
                if(decl.fEnumeration != null) {
                    Vector v = decl.fEnumeration;
                    typesBuffer.append(" : [");
                    for(int j = 0;j < v.size(); j++) {
                        if(j != 0)
                            typesBuffer.append(',');
                        typesBuffer.append(v.elementAt(j));
                    }
                    typesBuffer.append(']');
                }
            }
            throw new InvalidDatatypeValueException("cvc-datatype-valid.1.2.3",
                    new Object[]{content, fTypeName, typesBuffer.toString()});
        }

    }//getActualValue()

    public boolean isEqual(Object value1, Object value2) {
        if (value1 == null) {
            return false;
        }
        return value1.equals(value2);
    }//isEqual()

    // determine whether the two values are identical
    public boolean isIdentical (Object value1, Object value2) {
        if (value1 == null) {
            return false;
        }
        return fDVs[fValidationDV].isIdentical(value1, value2);
    }//isIdentical()

    // normalize the string according to the whiteSpace facet
    public static String normalize(String content, short ws) {
        int len = content == null ? 0 : content.length();
        if (len == 0 || ws == WS_PRESERVE)
            return content;

        StringBuffer sb = new StringBuffer();
        if (ws == WS_REPLACE) {
            char ch;
            // when it's replace, just replace #x9, #xa, #xd by #x20
            for (int i = 0; i < len; i++) {
                ch = content.charAt(i);
                if (ch != 0x9 && ch != 0xa && ch != 0xd)
                    sb.append(ch);
                else
                    sb.append((char)0x20);
            }
        } else {
            char ch;
            int i;
            boolean isLeading = true;
            // when it's collapse
            for (i = 0; i < len; i++) {
                ch = content.charAt(i);
                // append real characters, so we passed leading ws
                if (ch != 0x9 && ch != 0xa && ch != 0xd && ch != 0x20) {
                    sb.append(ch);
                    isLeading = false;
                }
                else {
                    // for whitespaces, we skip all following ws
                    for (; i < len-1; i++) {
                        ch = content.charAt(i+1);
                        if (ch != 0x9 && ch != 0xa && ch != 0xd && ch != 0x20)
                            break;
                    }
                    // if it's not a leading or tailing ws, then append a space
                    if (i < len - 1 && !isLeading)
                        sb.append((char)0x20);
                }
            }
        }

        return sb.toString();
    }

    // normalize the string according to the whiteSpace facet
    protected String normalize(Object content, short ws) {
        if (content == null)
            return null;

        // If pattern is not defined, we can skip some of the normalization.
        // Otherwise we have to normalize the data for correct result of
        // pattern validation.
        if ( (fFacetsDefined & FACET_PATTERN ) == 0 ) {
            short norm_type = fDVNormalizeType[fValidationDV];
            if (norm_type == NORMALIZE_NONE) {
                return content.toString();
            }
            else if (norm_type == NORMALIZE_TRIM) {
                return XMLChar.trim(content.toString());
            }
        }

        if (!(content instanceof StringBuffer)) {
            String strContent = content.toString();
            return normalize(strContent, ws);
        }

        StringBuffer sb = (StringBuffer)content;
        int len = sb.length();
        if (len == 0)
            return "";
        if (ws == WS_PRESERVE)
            return sb.toString();

        if (ws == WS_REPLACE) {
            char ch;
            // when it's replace, just replace #x9, #xa, #xd by #x20
            for (int i = 0; i < len; i++) {
                ch = sb.charAt(i);
                if (ch == 0x9 || ch == 0xa || ch == 0xd)
                    sb.setCharAt(i, (char)0x20);
            }
        } else {
            char ch;
            int i, j = 0;
            boolean isLeading = true;
            // when it's collapse
            for (i = 0; i < len; i++) {
                ch = sb.charAt(i);
                // append real characters, so we passed leading ws
                if (ch != 0x9 && ch != 0xa && ch != 0xd && ch != 0x20) {
                    sb.setCharAt(j++, ch);
                    isLeading = false;
                }
                else {
                    // for whitespaces, we skip all following ws
                    for (; i < len-1; i++) {
                        ch = sb.charAt(i+1);
                        if (ch != 0x9 && ch != 0xa && ch != 0xd && ch != 0x20)
                            break;
                    }
                    // if it's not a leading or tailing ws, then append a space
                    if (i < len - 1 && !isLeading)
                        sb.setCharAt(j++, (char)0x20);
                }
            }
            sb.setLength(j);
        }

        return sb.toString();
    }

    void reportError(String key, Object[] args) throws InvalidDatatypeFacetException {
        throw new InvalidDatatypeFacetException(key, args);
    }


    private String whiteSpaceValue(short ws){
        return WS_FACET_STRING[ws];
    }

    /**
     *  Fundamental Facet: ordered.
     */
    public short getOrdered() {
        return fOrdered;
    }

    /**
     * Fundamental Facet: bounded.
     */
    public boolean getBounded(){
        return fBounded;
    }

    /**
     * Fundamental Facet: cardinality.
     */
    public boolean getFinite(){
        return fFinite;
    }

    /**
     * Fundamental Facet: numeric.
     */
    public boolean getNumeric(){
        return fNumeric;
    }

    /**
     * Convenience method. [Facets]: check whether a facet is defined on this
     * type.
     * @param facetName  The name of the facet.
     * @return  True if the facet is defined, false otherwise.
     */
    public boolean isDefinedFacet(short facetName) {
        if (fValidationDV == DV_ANYSIMPLETYPE ||
            fValidationDV == DV_ANYATOMICTYPE) {
            return false;
        }
        if ((fFacetsDefined & facetName) != 0) {
            return true;
        }
        if (fPatternType != SPECIAL_PATTERN_NONE) {
            return facetName == FACET_PATTERN;
        }
        if (fValidationDV == DV_INTEGER) {
            return facetName == FACET_PATTERN || facetName == FACET_FRACTIONDIGITS;
        }
        return false;
    }

    /**
     * [facets]: all facets defined on this type. The value is a bit
     * combination of FACET_XXX constants of all defined facets.
     */
    public short getDefinedFacets() {
        if (fValidationDV == DV_ANYSIMPLETYPE ||
            fValidationDV == DV_ANYATOMICTYPE) {
            return FACET_NONE;
        }
        if (fPatternType != SPECIAL_PATTERN_NONE) {
            return (short)(fFacetsDefined | FACET_PATTERN);
        }
        if (fValidationDV == DV_INTEGER) {
            return (short)(fFacetsDefined | FACET_PATTERN | FACET_FRACTIONDIGITS);
        }
        return fFacetsDefined;
    }

    /**
     * Convenience method. [Facets]: check whether a facet is defined and
     * fixed on this type.
     * @param facetName  The name of the facet.
     * @return  True if the facet is fixed, false otherwise.
     */
    public boolean isFixedFacet(short facetName) {
        if ((fFixedFacet & facetName) != 0)
            return true;
        if (fValidationDV == DV_INTEGER)
            return facetName == FACET_FRACTIONDIGITS;
        return false;
    }

    /**
     * [facets]: all defined facets for this type which are fixed.
     */
    public short getFixedFacets() {
        if (fValidationDV == DV_INTEGER)
            return (short)(fFixedFacet | FACET_FRACTIONDIGITS);
        return fFixedFacet;
    }

    /**
     * Convenience method. Returns a value of a single constraining facet for
     * this simple type definition. This method must not be used to retrieve
     * values for <code>enumeration</code> and <code>pattern</code> facets.
     * @param facetName The name of the facet, i.e.
     *   <code>FACET_LENGTH, FACET_TOTALDIGITS </code> (see
     *   <code>XSConstants</code>). To retrieve the value for a pattern or
     *   an enumeration, see <code>enumeration</code> and
     *   <code>pattern</code>.
     * @return A value of the facet specified in <code>facetName</code> for
     *   this simple type definition or <code>null</code>.
     */
    public String getLexicalFacetValue(short facetName) {
        switch (facetName) {
            case FACET_LENGTH:
                return (fLength == -1)?null:Integer.toString(fLength);
            case FACET_MINLENGTH:
                return (fMinLength == -1)?null:Integer.toString(fMinLength);
            case FACET_MAXLENGTH:
                return (fMaxLength == -1)?null:Integer.toString(fMaxLength);
            case FACET_WHITESPACE:
                if (fValidationDV == DV_ANYSIMPLETYPE ||
                    fValidationDV == DV_ANYATOMICTYPE) {
                    return null;
                }
                return WS_FACET_STRING[fWhiteSpace];
            case FACET_MAXINCLUSIVE:
                return (fMaxInclusive == null)?null:fMaxInclusive.toString();
            case FACET_MAXEXCLUSIVE:
                return (fMaxExclusive == null)?null:fMaxExclusive.toString();
            case FACET_MINEXCLUSIVE:
                return (fMinExclusive == null)?null:fMinExclusive.toString();
            case FACET_MININCLUSIVE:
                return (fMinInclusive == null)?null:fMinInclusive.toString();
            case FACET_TOTALDIGITS:
                return (fTotalDigits == -1)?null:Integer.toString(fTotalDigits);
            case FACET_FRACTIONDIGITS:
                if (fValidationDV == DV_INTEGER) {
                    return "0";
                }
                return (fFractionDigits == -1)?null:Integer.toString(fFractionDigits);
        }
        return null;
    }

    /**
     * A list of enumeration values if it exists, otherwise an empty
     * <code>StringList</code>.
     */
    public StringList getLexicalEnumeration() {
        if (fLexicalEnumeration == null){
            if (fEnumeration == null)
                return StringListImpl.EMPTY_LIST;
            int size = fEnumeration.size();
            String[] strs = new String[size];
            for (int i = 0; i < size; i++)
                strs[i] = fEnumeration.elementAt(i).toString();
            fLexicalEnumeration = new StringListImpl(strs, size);
        }
        return fLexicalEnumeration;
    }

    /**
     * A list of actual enumeration values if it exists, otherwise an empty
     * <code>ObjectList</code>.
     */
    public ObjectList getActualEnumeration() {
        if (fActualEnumeration == null) {
            fActualEnumeration = new AbstractObjectList() {
                public int getLength() {
                    return (fEnumeration != null) ? fEnumeration.size() : 0;
                }
                public boolean contains(Object item) {
                    return (fEnumeration != null && fEnumeration.contains(item));
                }
                public Object item(int index) {
                    if (index < 0 || index >= getLength()) {
                        return null;
                    }
                    return fEnumeration.elementAt(index);
                }
            };
        }
        return fActualEnumeration;
    }

    /**
     * A list of enumeration type values (as a list of ShortList objects) if it exists, otherwise returns
     * null
     */
    public ObjectList getEnumerationItemTypeList() {
        if (fEnumerationItemTypeList == null) {
            if(fEnumerationItemType == null)
                return null;
            fEnumerationItemTypeList = new AbstractObjectList() {
                public int getLength() {
                    return (fEnumerationItemType != null) ? fEnumerationItemType.length : 0;
                }
                public boolean contains(Object item) {
                    if(fEnumerationItemType == null || !(item instanceof ShortList))
                        return false;
                    for(int i = 0;i < fEnumerationItemType.length; i++)
                        if(fEnumerationItemType[i] == item)
                            return true;
                    return false;
                }
                public Object item(int index) {
                    if (index < 0 || index >= getLength()) {
                        return null;
                    }
                    return fEnumerationItemType[index];
                }
            };
        }
        return fEnumerationItemTypeList;
    }

    public ShortList getEnumerationTypeList() {
        if (fEnumerationTypeList == null) {
            if (fEnumerationType == null) {
                return ShortListImpl.EMPTY_LIST;
            }
            fEnumerationTypeList = new ShortListImpl (fEnumerationType, fEnumerationType.length);
        }
        return fEnumerationTypeList;
    }

    /**
     * A list of pattern values if it exists, otherwise an empty
     * <code>StringList</code>.
     */
    public StringList getLexicalPattern() {
        if (fPatternType == SPECIAL_PATTERN_NONE && fValidationDV != DV_INTEGER && fPatternStr == null)
            return StringListImpl.EMPTY_LIST;
        if (fLexicalPattern == null){
            int size = fPatternStr == null ? 0 : fPatternStr.size();
            String[] strs;
            if (fPatternType == SPECIAL_PATTERN_NMTOKEN) {
                strs = new String[size+1];
                strs[size] = "\\c+";
            }
            else if (fPatternType == SPECIAL_PATTERN_NAME) {
                strs = new String[size+1];
                strs[size] = "\\i\\c*";
            }
            else if (fPatternType == SPECIAL_PATTERN_NCNAME) {
                strs = new String[size+2];
                strs[size] = "\\i\\c*";
                strs[size+1] = "[\\i-[:]][\\c-[:]]*";
            }
            else if (fValidationDV == DV_INTEGER) {
                strs = new String[size+1];
                strs[size] = "[\\-+]?[0-9]+";
            }
            else {
                strs = new String[size];
            }
            for (int i = 0; i < size; i++)
                strs[i] = (String)fPatternStr.elementAt(i);
            fLexicalPattern = new StringListImpl(strs, strs.length);
        }
        return fLexicalPattern;
    }

    /**
     * [annotations]: a set of annotations for this simple type component if
     * it exists, otherwise an empty <code>XSObjectList</code>.
     */
    public XSObjectList getAnnotations() {
        return (fAnnotations != null) ? fAnnotations : XSObjectListImpl.EMPTY_LIST;
    }

    private void calcFundamentalFacets() {
        setOrdered();
        setNumeric();
        setBounded();
        setCardinality();
    }

    private void setOrdered(){

        // When {variety} is atomic, {value} is inherited from {value} of {base type definition}. For all "primitive" types {value} is as specified in the table in Fundamental Facets (C.1).
        if(fVariety == VARIETY_ATOMIC){
            this.fOrdered = fBase.fOrdered;
        }

        // When {variety} is list, {value} is false.
        else if(fVariety == VARIETY_LIST){
            this.fOrdered = ORDERED_FALSE;
        }

        // When {variety} is union, the {value} is partial unless one of the following:
        // 1. If every member of {member type definitions} is derived from a common ancestor other than the simple ur-type, then {value} is the same as that ancestor's ordered facet.
        // 2. If every member of {member type definitions} has a {value} of false for the ordered facet, then {value} is false.
        else if(fVariety == VARIETY_UNION){
            int length = fMemberTypes.length;
            // REVISIT: is the length possible to be 0?
            if (length == 0) {
                this.fOrdered = ORDERED_PARTIAL;
                return;
            }
            // we need to process the first member type before entering the loop
            short ancestorId = getPrimitiveDV(fMemberTypes[0].fValidationDV);
            boolean commonAnc = ancestorId != DV_ANYSIMPLETYPE;
            boolean allFalse = fMemberTypes[0].fOrdered == ORDERED_FALSE;
            // for the other member types, check whether the value is false
            // and whether they have the same ancestor as the first one
            for (int i = 1; i < fMemberTypes.length && (commonAnc || allFalse); i++) {
                if (commonAnc)
                    commonAnc = ancestorId == getPrimitiveDV(fMemberTypes[i].fValidationDV);
                if (allFalse)
                    allFalse = fMemberTypes[i].fOrdered == ORDERED_FALSE;
            }
            if (commonAnc) {
                // REVISIT: all member types should have the same ordered value
                //          just use the first one. Can we assume this?
                this.fOrdered = fMemberTypes[0].fOrdered;
            } else if (allFalse) {
                this.fOrdered = ORDERED_FALSE;
            } else {
                this.fOrdered = ORDERED_PARTIAL;
            }
        }

    }//setOrdered

    private void setNumeric(){
        if(fVariety == VARIETY_ATOMIC){
            this.fNumeric = fBase.fNumeric;
        }
        else if(fVariety == VARIETY_LIST){
            this.fNumeric = false;
        }
        else if(fVariety == VARIETY_UNION){
            XSSimpleType[] memberTypes = fMemberTypes;
            for(int i = 0 ; i < memberTypes.length ; i++){
                if(!memberTypes[i].getNumeric() ){
                    this.fNumeric = false;
                    return;
                }
            }
            this.fNumeric = true;
        }

    }//setNumeric

    private void setBounded(){
        if(fVariety == VARIETY_ATOMIC){
            if( (((this.fFacetsDefined & FACET_MININCLUSIVE) != 0)  || ((this.fFacetsDefined & FACET_MINEXCLUSIVE) != 0))
                    &&  (((this.fFacetsDefined & FACET_MAXINCLUSIVE) != 0)  || ((this.fFacetsDefined & FACET_MAXEXCLUSIVE) != 0)) ){
                this.fBounded = true;
            }
            else{
                this.fBounded = false;
            }
        }
        else if(fVariety == VARIETY_LIST){
            if( ((this.fFacetsDefined & FACET_LENGTH) != 0 ) || ( ((this.fFacetsDefined & FACET_MINLENGTH) != 0 )
                    &&  ((this.fFacetsDefined & FACET_MAXLENGTH) != 0 )) ){
                this.fBounded = true;
            }
            else{
                this.fBounded = false;
            }

        }
        else if(fVariety == VARIETY_UNION){

            XSSimpleTypeDecl [] memberTypes = this.fMemberTypes;
            short ancestorId = 0 ;

            if(memberTypes.length > 0){
                ancestorId = getPrimitiveDV(memberTypes[0].fValidationDV);
            }

            for(int i = 0 ; i < memberTypes.length ; i++){
                if(!memberTypes[i].getBounded() || (ancestorId != getPrimitiveDV(memberTypes[i].fValidationDV)) ){
                    this.fBounded = false;
                    return;
                }
            }
            this.fBounded = true;
        }

    }//setBounded

    private boolean specialCardinalityCheck(){
        if( (fBase.fValidationDV == XSSimpleTypeDecl.DV_DATE) || (fBase.fValidationDV == XSSimpleTypeDecl.DV_GYEARMONTH)
                || (fBase.fValidationDV == XSSimpleTypeDecl.DV_GYEAR) || (fBase.fValidationDV == XSSimpleTypeDecl.DV_GMONTHDAY)
                || (fBase.fValidationDV == XSSimpleTypeDecl.DV_GDAY) || (fBase.fValidationDV == XSSimpleTypeDecl.DV_GMONTH) ){
            return true;
        }
        return false;

    } //specialCardinalityCheck()

    private void setCardinality(){
        if(fVariety == VARIETY_ATOMIC){
            if(fBase.fFinite){
                this.fFinite = true;
            }
            else {// (!fBase.fFinite)
                if ( ((this.fFacetsDefined & FACET_LENGTH) != 0 ) || ((this.fFacetsDefined & FACET_MAXLENGTH) != 0 )
                        || ((this.fFacetsDefined & FACET_TOTALDIGITS) != 0 ) ){
                    this.fFinite = true;
                }
                else if( (((this.fFacetsDefined & FACET_MININCLUSIVE) != 0 ) || ((this.fFacetsDefined & FACET_MINEXCLUSIVE) != 0 ))
                        && (((this.fFacetsDefined & FACET_MAXINCLUSIVE) != 0 ) || ((this.fFacetsDefined & FACET_MAXEXCLUSIVE) != 0 )) ){
                    if( ((this.fFacetsDefined & FACET_FRACTIONDIGITS) != 0 ) || specialCardinalityCheck()){
                        this.fFinite = true;
                    }
                    else{
                        this.fFinite = false;
                    }
                }
                else{
                    this.fFinite = false;
                }
            }
        }
        else if(fVariety == VARIETY_LIST){
            if( ((this.fFacetsDefined & FACET_LENGTH) != 0 ) || ( ((this.fFacetsDefined & FACET_MINLENGTH) != 0 )
                    && ((this.fFacetsDefined & FACET_MAXLENGTH) != 0 )) ){
                this.fFinite = true;
            }
            else{
                this.fFinite = false;
            }

        }
        else if(fVariety == VARIETY_UNION){
            XSSimpleType [] memberTypes = fMemberTypes;
            for(int i = 0 ; i < memberTypes.length ; i++){
                if(!(memberTypes[i].getFinite()) ){
                    this.fFinite = false;
                    return;
                }
            }
            this.fFinite = true;
        }

    }//setCardinality

    private short getPrimitiveDV(short validationDV){

        if (validationDV == DV_ID || validationDV == DV_IDREF || validationDV == DV_ENTITY){
            return DV_STRING;
        }
        else if (validationDV == DV_INTEGER) {
            return DV_DECIMAL;
        }
        else if (Constants.SCHEMA_1_1_SUPPORT && (validationDV == DV_YEARMONTHDURATION || validationDV == DV_DAYTIMEDURATION)) {
            return DV_DURATION;
        }
        else {
            return validationDV;
        }

    }//getPrimitiveDV()

    public boolean derivedFromType(XSTypeDefinition ancestor, short derivation) {
        // REVISIT: implement according to derivation

        // ancestor is null, return false
        if (ancestor == null) {
            return false;
        }
        // extract the actual XSTypeDefinition if the given ancestor is a delegate.
        while (ancestor instanceof XSSimpleTypeDelegate) {
            ancestor = ((XSSimpleTypeDelegate) ancestor).type;
        }
        // ancestor is anyType, return true
        // anyType is the only type whose base type is itself
        if (ancestor.getBaseType() == ancestor) {
            return true;
        }
        // recursively get base, and compare it with ancestor
        XSTypeDefinition type = this;
        while (type != ancestor &&                      // compare with ancestor
                type != fAnySimpleType) {  // reached anySimpleType
            type = type.getBaseType();
        }
        return type == ancestor;
    }

    public boolean derivedFrom(String ancestorNS, String ancestorName, short derivation) {
        // REVISIT: implement according to derivation

        // ancestor is null, retur false
        if (ancestorName == null)
            return false;
        // ancestor is anyType, return true
        if (URI_SCHEMAFORSCHEMA.equals(ancestorNS) &&
                ANY_TYPE.equals(ancestorName)) {
            return true;
        }

        // recursively get base, and compare it with ancestor
        XSTypeDefinition type = this;
        while (!(ancestorName.equals(type.getName()) &&
                ((ancestorNS == null && type.getNamespace() == null) ||
                        (ancestorNS != null && ancestorNS.equals(type.getNamespace())))) &&   // compare with ancestor
                        type != fAnySimpleType) {  // reached anySimpleType
            type = (XSTypeDefinition)type.getBaseType();
        }

        return type != fAnySimpleType;
    }

    /**
     * Checks if a type is derived from another by restriction, given the name
     * and namespace. See:
     * http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#TypeInfo-isDerivedFrom
     *
     * @param ancestorNS
     *            The namspace of the ancestor type declaration
     * @param ancestorName
     *            The name of the ancestor type declaration
     * @param derivationMethod
     *            The derivation method
     *
     * @return boolean True if the ancestor type is derived from the reference type by the specifiied derivation method.
     */
    public boolean isDOMDerivedFrom(String ancestorNS, String ancestorName, int derivationMethod) {

        // ancestor is null, return false
        if (ancestorName == null)
            return false;

        // ancestor is anyType, return true
        if (SchemaSymbols.URI_SCHEMAFORSCHEMA.equals(ancestorNS)
                && SchemaSymbols.ATTVAL_ANYTYPE.equals(ancestorName)
                && (((derivationMethod  & DERIVATION_RESTRICTION) != 0)
                        || (derivationMethod  == DERIVATION_ANY))) {
            return true;
        }

        // restriction
        if ((derivationMethod & DERIVATION_RESTRICTION) != 0) {
            if (isDerivedByRestriction(ancestorNS, ancestorName, this)) {
                return true;
            }
        }

        // list
        if ((derivationMethod & DERIVATION_LIST) != 0) {
            if (isDerivedByList(ancestorNS, ancestorName, this)) {
                return true;
            }
        }

        // union
        if ((derivationMethod & DERIVATION_UNION) != 0) {
            if (isDerivedByUnion(ancestorNS, ancestorName, this)) {
                return true;
            }
        }

        // extension
        if (((derivationMethod & DERIVATION_EXTENSION) != 0)
                && (((derivationMethod & DERIVATION_RESTRICTION) == 0)
                        && ((derivationMethod & DERIVATION_LIST) == 0)
                        && ((derivationMethod & DERIVATION_UNION) == 0))) {
            return false;
        }

        // If the value of the parameter is 0 i.e. no bit (corresponding to
        // restriction, list, extension or union) is set to 1 for the
        // derivationMethod parameter.
        if (((derivationMethod & DERIVATION_EXTENSION) == 0)
                && (((derivationMethod & DERIVATION_RESTRICTION) == 0)
                        && ((derivationMethod & DERIVATION_LIST) == 0)
                        && ((derivationMethod & DERIVATION_UNION) == 0))) {
            return isDerivedByAny(ancestorNS, ancestorName, this);
        }

        return false;
    }


    /**
     * Checks if a type is derived from another by any combination of restriction, list ir union. See:
     * http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#TypeInfo-isDerivedFrom
     *
     * @param ancestorNS
     *            The namspace of the ancestor type declaration
     * @param ancestorName
     *            The name of the ancestor type declaration
     * @param type
     *            The reference type definition
     *
     * @return boolean True if the type is derived by restriciton for the reference type
     */
    private boolean isDerivedByAny(String ancestorNS, String ancestorName,
            XSTypeDefinition type) {

        boolean derivedFrom = false;
        XSTypeDefinition oldType = null;
        // for each base, item or member type
        while (type != null && type != oldType)  {

            // If the ancestor type is reached or is the same as this type.
            if ((ancestorName.equals(type.getName()))
                    && ((ancestorNS == null && type.getNamespace() == null)
                            || (ancestorNS != null && ancestorNS.equals(type.getNamespace())))) {
                derivedFrom = true;
                break;
            }

            // check if derived by restriction or list or union
            if (isDerivedByRestriction(ancestorNS, ancestorName, type)) {
                return true;
            } else if (isDerivedByList(ancestorNS, ancestorName, type)) {
                return true;
            } else  if (isDerivedByUnion(ancestorNS, ancestorName, type)) {
                return true;
            }
            oldType = type;
            // get the base, item or member type depending on the variety
            if (((XSSimpleTypeDecl) type).getVariety() == VARIETY_ABSENT
                    || ((XSSimpleTypeDecl) type).getVariety() == VARIETY_ATOMIC) {
                type = type.getBaseType();
            } else if (((XSSimpleTypeDecl) type).getVariety() == VARIETY_UNION) {
                for (int i = 0; i < ((XSSimpleTypeDecl) type).getMemberTypes().getLength(); i++) {
                    return isDerivedByAny(ancestorNS, ancestorName,
                            (XSTypeDefinition) ((XSSimpleTypeDecl) type)
                            .getMemberTypes().item(i));
                }
            } else if (((XSSimpleTypeDecl) type).getVariety() == VARIETY_LIST) {
                type = ((XSSimpleTypeDecl) type).getItemType();
            }
        }

        return derivedFrom;
    }

    /**
     * DOM Level 3
     * Checks if a type is derived from another by restriction. See:
     * http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#TypeInfo-isDerivedFrom
     *
     * @param ancestorNS
     *            The namspace of the ancestor type declaration
     * @param ancestorName
     *            The name of the ancestor type declaration
     * @param type
     *            The reference type definition
     *
     * @return boolean True if the type is derived by restriciton for the
     *         reference type
     */
    private boolean isDerivedByRestriction (String ancestorNS, String ancestorName, XSTypeDefinition type) {
        XSTypeDefinition oldType = null;
        while (type != null && type != oldType) {
            if ((ancestorName.equals(type.getName()))
                    && ((ancestorNS != null && ancestorNS.equals(type.getNamespace()))
                            || (type.getNamespace() == null && ancestorNS == null))) {

                return true;
            }
            oldType = type;
            type = type.getBaseType();
        }

        return false;
    }

    /**
     * Checks if a type is derived from another by list. See:
     * http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#TypeInfo-isDerivedFrom
     *
     * @param ancestorNS
     *            The namspace of the ancestor type declaration
     * @param ancestorName
     *            The name of the ancestor type declaration
     * @param type
     *            The reference type definition
     *
     * @return boolean True if the type is derived by list for the reference type
     */
    private boolean isDerivedByList (String ancestorNS, String ancestorName, XSTypeDefinition type) {
        // If the variety is union
        if (type !=null && ((XSSimpleTypeDefinition)type).getVariety() == VARIETY_LIST) {

            // get the {item type}
            XSTypeDefinition itemType = ((XSSimpleTypeDefinition)type).getItemType();

            // T2 is the {item type definition}
            if (itemType != null) {

                // T2 is derived from the other type definition by DERIVATION_RESTRICTION
                if (isDerivedByRestriction(ancestorNS, ancestorName, itemType)) {
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * Checks if a type is derived from another by union.  See:
     * http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#TypeInfo-isDerivedFrom
     *
     * @param ancestorNS
     *            The namspace of the ancestor type declaration
     * @param ancestorName
     *            The name of the ancestor type declaration
     * @param type
     *            The reference type definition
     *
     * @return boolean True if the type is derived by union for the reference type
     */
    private boolean isDerivedByUnion (String ancestorNS, String ancestorName, XSTypeDefinition type) {

        // If the variety is union
        if (type !=null && ((XSSimpleTypeDefinition)type).getVariety() == VARIETY_UNION) {

            // get member types
            XSObjectList memberTypes = ((XSSimpleTypeDefinition)type).getMemberTypes();

            for (int i = 0; i < memberTypes.getLength(); i++) {
                // One of the {member type definitions} is T2.
                if (memberTypes.item(i) != null) {
                    // T2 is derived from the other type definition by DERIVATION_RESTRICTION
                    if (isDerivedByRestriction(ancestorNS, ancestorName,(XSSimpleTypeDefinition)memberTypes.item(i))) {
                        return true;
                    }
                }
            }
        }
        return false;
    }


    static final XSSimpleTypeDecl fAnySimpleType = new XSSimpleTypeDecl(null, "anySimpleType", DV_ANYSIMPLETYPE, ORDERED_FALSE, false, true, false, true, XSConstants.ANYSIMPLETYPE_DT);

    static final XSSimpleTypeDecl fAnyAtomicType = new XSSimpleTypeDecl(fAnySimpleType, "anyAtomicType", DV_ANYATOMICTYPE, ORDERED_FALSE, false, true, false, true, XSSimpleTypeDecl.ANYATOMICTYPE_DT);

    /**
     * Validation context used to validate facet values.
     */
    static final ValidationContext fDummyContext = new ValidationContext() {
        public boolean needFacetChecking() {
            return true;
        }

        public boolean needExtraChecking() {
            return false;
        }
        public boolean needToNormalize() {
            return false;
        }
        public boolean useNamespaces() {
            return true;
        }

        public boolean isEntityDeclared(String name) {
            return false;
        }

        public boolean isEntityUnparsed(String name) {
            return false;
        }

        public boolean isIdDeclared(String name) {
            return false;
        }

        public void addId(String name) {
        }

        public void addIdRef(String name) {
        }

        public String getSymbol (String symbol) {
            return symbol.intern();
        }

        public String getURI(String prefix) {
            return null;
        }

        public Locale getLocale() {
            return Locale.getDefault();
        }
    };

    private boolean fAnonymous = false;

    /**
     * A wrapper of ValidationContext, to provide a way of switching to a
     * different Namespace declaration context.
     */
    static final class ValidationContextImpl implements ValidationContext {

        final ValidationContext fExternal;

        ValidationContextImpl(ValidationContext external) {
            fExternal = external;
        }

        NamespaceContext fNSContext;
        void setNSContext(NamespaceContext nsContext) {
            fNSContext = nsContext;
        }

        public boolean needFacetChecking() {
            return fExternal.needFacetChecking();
        }

        public boolean needExtraChecking() {
            return fExternal.needExtraChecking();
        }
        public boolean needToNormalize() {
            return fExternal.needToNormalize();
        }
        // schema validation is predicated upon namespaces
        public boolean useNamespaces() {
            return true;
        }

        public boolean isEntityDeclared (String name) {
            return fExternal.isEntityDeclared(name);
        }

        public boolean isEntityUnparsed (String name) {
            return fExternal.isEntityUnparsed(name);
        }

        public boolean isIdDeclared (String name) {
            return fExternal.isIdDeclared(name);
        }

        public void addId(String name) {
            fExternal.addId(name);
        }

        public void addIdRef(String name) {
            fExternal.addIdRef(name);
        }

        public String getSymbol (String symbol) {
            return fExternal.getSymbol(symbol);
        }

        public String getURI(String prefix) {
            if (fNSContext == null) {
                return fExternal.getURI(prefix);
            }
            else {
                return fNSContext.getURI(prefix);
            }
        }

        public Locale getLocale() {
            return fExternal.getLocale();
        }
    }

    public void reset(){

        // if it's immutable, can't be reset:
        if (fIsImmutable) return;
        fItemType = null;
        fMemberTypes = null;

        fTypeName = null;
        fTargetNamespace = null;
        fFinalSet = 0;
        fBase = null;
        fVariety = -1;
        fValidationDV = -1;

        fFacetsDefined = 0;
        fFixedFacet = 0;

        //for constraining facets
        fWhiteSpace = 0;
        fLength = -1;
        fMinLength = -1;
        fMaxLength = -1;
        fTotalDigits = -1;
        fFractionDigits = -1;
        fPattern = null;
        fPatternStr = null;
        fEnumeration = null;
        fEnumerationType = null;
        fEnumerationItemType = null;
        fLexicalPattern = null;
        fLexicalEnumeration = null;
        fMaxInclusive = null;
        fMaxExclusive = null;
        fMinExclusive = null;
        fMinInclusive = null;
        lengthAnnotation = null;
        minLengthAnnotation = null;
        maxLengthAnnotation = null;
        whiteSpaceAnnotation = null;
        totalDigitsAnnotation = null;
        fractionDigitsAnnotation = null;
        patternAnnotations = null;
        enumerationAnnotations = null;
        maxInclusiveAnnotation = null;
        maxExclusiveAnnotation = null;
        minInclusiveAnnotation = null;
        minExclusiveAnnotation = null;

        fPatternType = SPECIAL_PATTERN_NONE;
        fAnnotations = null;
        fFacets = null;

        // REVISIT: reset for fundamental facets
    }

    /**
     * @see com.sun.org.apache.xerces.internal.xs.XSObject#getNamespaceItem()
     */
    public XSNamespaceItem getNamespaceItem() {
        return fNamespaceItem;
    }

    public void setNamespaceItem(XSNamespaceItem namespaceItem) {
        fNamespaceItem = namespaceItem;
    }

    /**
     * @see java.lang.Object#toString()
     */
    public String toString() {
        return this.fTargetNamespace+"," +this.fTypeName;
    }

    /**
     *  A list of constraining facets if it exists, otherwise an empty
     * <code>XSObjectList</code>. Note: This method must not be used to
     * retrieve values for <code>enumeration</code> and <code>pattern</code>
     * facets.
     */
    public XSObjectList getFacets() {
        if (fFacets == null &&
                (fFacetsDefined != 0 || fValidationDV == DV_INTEGER)) {

            XSFacetImpl[] facets = new XSFacetImpl[10];
            int count = 0;
            if ((fFacetsDefined & FACET_WHITESPACE) != 0 &&
                fValidationDV != DV_ANYSIMPLETYPE &&
                fValidationDV != DV_ANYATOMICTYPE) {
                facets[count] =
                    new XSFacetImpl(
                            FACET_WHITESPACE,
                            WS_FACET_STRING[fWhiteSpace],
                            (fFixedFacet & FACET_WHITESPACE) != 0,
                            whiteSpaceAnnotation);
                count++;
            }
            if (fLength != -1) {
                facets[count] =
                    new XSFacetImpl(
                            FACET_LENGTH,
                            Integer.toString(fLength),
                            (fFixedFacet & FACET_LENGTH) != 0,
                            lengthAnnotation);
                count++;
            }
            if (fMinLength != -1) {
                facets[count] =
                    new XSFacetImpl(
                            FACET_MINLENGTH,
                            Integer.toString(fMinLength),
                            (fFixedFacet & FACET_MINLENGTH) != 0,
                            minLengthAnnotation);
                count++;
            }
            if (fMaxLength != -1) {
                facets[count] =
                    new XSFacetImpl(
                            FACET_MAXLENGTH,
                            Integer.toString(fMaxLength),
                            (fFixedFacet & FACET_MAXLENGTH) != 0,
                            maxLengthAnnotation);
                count++;
            }
            if (fTotalDigits != -1) {
                facets[count] =
                    new XSFacetImpl(
                            FACET_TOTALDIGITS,
                            Integer.toString(fTotalDigits),
                            (fFixedFacet & FACET_TOTALDIGITS) != 0,
                            totalDigitsAnnotation);
                count++;
            }
            if (fValidationDV == DV_INTEGER) {
                facets[count] =
                    new XSFacetImpl(
                            FACET_FRACTIONDIGITS,
                            "0",
                            true,
                            fractionDigitsAnnotation);
                count++;
            }
            else if (fFractionDigits != -1) {
                facets[count] =
                    new XSFacetImpl(
                            FACET_FRACTIONDIGITS,
                            Integer.toString(fFractionDigits),
                            (fFixedFacet & FACET_FRACTIONDIGITS) != 0,
                            fractionDigitsAnnotation);
                count++;
            }
            if (fMaxInclusive != null) {
                facets[count] =
                    new XSFacetImpl(
                            FACET_MAXINCLUSIVE,
                            fMaxInclusive.toString(),
                            (fFixedFacet & FACET_MAXINCLUSIVE) != 0,
                            maxInclusiveAnnotation);
                count++;
            }
            if (fMaxExclusive != null) {
                facets[count] =
                    new XSFacetImpl(
                            FACET_MAXEXCLUSIVE,
                            fMaxExclusive.toString(),
                            (fFixedFacet & FACET_MAXEXCLUSIVE) != 0,
                            maxExclusiveAnnotation);
                count++;
            }
            if (fMinExclusive != null) {
                facets[count] =
                    new XSFacetImpl(
                            FACET_MINEXCLUSIVE,
                            fMinExclusive.toString(),
                            (fFixedFacet & FACET_MINEXCLUSIVE) != 0,
                            minExclusiveAnnotation);
                count++;
            }
            if (fMinInclusive != null) {
                facets[count] =
                    new XSFacetImpl(
                            FACET_MININCLUSIVE,
                            fMinInclusive.toString(),
                            (fFixedFacet & FACET_MININCLUSIVE) != 0,
                            minInclusiveAnnotation);
                count++;
            }
            fFacets = (count > 0) ? new XSObjectListImpl(facets, count) : XSObjectListImpl.EMPTY_LIST;
        }
        return (fFacets != null) ? fFacets : XSObjectListImpl.EMPTY_LIST;
    }

    /**
     *  A list of enumeration and pattern constraining facets if it exists,
     * otherwise an empty <code>XSObjectList</code>.
     */
    public XSObjectList getMultiValueFacets() {
        if (fMultiValueFacets == null &&
                ((fFacetsDefined & FACET_ENUMERATION) != 0 ||
                        (fFacetsDefined & FACET_PATTERN) != 0 ||
                        fPatternType != SPECIAL_PATTERN_NONE ||
                        fValidationDV == DV_INTEGER)) {

            XSMVFacetImpl[] facets = new XSMVFacetImpl[2];
            int count = 0;
            if ((fFacetsDefined & FACET_PATTERN) != 0 ||
                    fPatternType != SPECIAL_PATTERN_NONE ||
                    fValidationDV == DV_INTEGER) {
                facets[count] =
                    new XSMVFacetImpl(
                            FACET_PATTERN,
                            this.getLexicalPattern(),
                            patternAnnotations);
                count++;
            }
            if (fEnumeration != null) {
                facets[count] =
                    new XSMVFacetImpl(
                            FACET_ENUMERATION,
                            this.getLexicalEnumeration(),
                            enumerationAnnotations);
                count++;
            }
            fMultiValueFacets = new XSObjectListImpl(facets, count);
        }
        return (fMultiValueFacets != null) ?
                fMultiValueFacets : XSObjectListImpl.EMPTY_LIST;
    }

    public Object getMinInclusiveValue() {
        return fMinInclusive;
    }

    public Object getMinExclusiveValue() {
        return fMinExclusive;
    }

    public Object getMaxInclusiveValue() {
        return fMaxInclusive;
    }

    public Object getMaxExclusiveValue() {
        return fMaxExclusive;
    }

    public void setAnonymous(boolean anon) {
        fAnonymous = anon;
    }

    private static final class XSFacetImpl implements XSFacet {
        final short kind;
        final String value;
        final boolean fixed;
        final XSObjectList annotations;

        public XSFacetImpl(short kind, String value, boolean fixed, XSAnnotation annotation) {
            this.kind = kind;
            this.value = value;
            this.fixed = fixed;

            if (annotation != null) {
                this.annotations = new XSObjectListImpl();
                ((XSObjectListImpl)this.annotations).addXSObject(annotation);
            }
            else {
                this.annotations =  XSObjectListImpl.EMPTY_LIST;
            }
        }

        /*
         * (non-Javadoc)
         *
         * @see com.sun.org.apache.xerces.internal.xs.XSFacet#getAnnotation()
         */
        /**
         * Optional. Annotation.
         */
        public XSAnnotation getAnnotation() {
            return (XSAnnotation) annotations.item(0);
        }

        /*
         * (non-Javadoc)
         *
         * @see com.sun.org.apache.xerces.internal.xs.XSFacet#getAnnotations()
         */
        /**
         * Optional. Annotations.
         */
        public XSObjectList getAnnotations() {
            return annotations;
        }

        /* (non-Javadoc)
         * @see com.sun.org.apache.xerces.internal.xs.XSFacet#getFacetKind()
         */
        public short getFacetKind() {
            return kind;
        }

        /* (non-Javadoc)
         * @see com.sun.org.apache.xerces.internal.xs.XSFacet#getLexicalFacetValue()
         */
        public String getLexicalFacetValue() {
            return value;
        }

        /* (non-Javadoc)
         * @see com.sun.org.apache.xerces.internal.xs.XSFacet#isFixed()
         */
        public boolean getFixed() {
            return fixed;
        }

        /* (non-Javadoc)
         * @see com.sun.org.apache.xerces.internal.xs.XSObject#getName()
         */
        public String getName() {
            return null;
        }

        /* (non-Javadoc)
         * @see com.sun.org.apache.xerces.internal.xs.XSObject#getNamespace()
         */
        public String getNamespace() {
            return null;
        }

        /* (non-Javadoc)
         * @see com.sun.org.apache.xerces.internal.xs.XSObject#getNamespaceItem()
         */
        public XSNamespaceItem getNamespaceItem() {
            // REVISIT: implement
            return null;
        }

        /* (non-Javadoc)
         * @see com.sun.org.apache.xerces.internal.xs.XSObject#getType()
         */
        public short getType() {
            return XSConstants.FACET;
        }

    }

    private static final class XSMVFacetImpl implements XSMultiValueFacet {
        final short kind;
        final XSObjectList annotations;
        final StringList values;

        public XSMVFacetImpl(short kind, StringList values, XSObjectList annotations) {
            this.kind = kind;
            this.values = values;
            this.annotations = (annotations != null) ? annotations : XSObjectListImpl.EMPTY_LIST;
        }

        /* (non-Javadoc)
         * @see com.sun.org.apache.xerces.internal.xs.XSFacet#getFacetKind()
         */
        public short getFacetKind() {
            return kind;
        }

        /* (non-Javadoc)
         * @see com.sun.org.apache.xerces.internal.xs.XSMultiValueFacet#getAnnotations()
         */
        public XSObjectList getAnnotations() {
            return annotations;
        }

        /* (non-Javadoc)
         * @see com.sun.org.apache.xerces.internal.xs.XSMultiValueFacet#getLexicalFacetValues()
         */
        public StringList getLexicalFacetValues() {
            return values;
        }

        /* (non-Javadoc)
         * @see com.sun.org.apache.xerces.internal.xs.XSObject#getName()
         */
        public String getName() {
            return null;
        }

        /* (non-Javadoc)
         * @see com.sun.org.apache.xerces.internal.xs.XSObject#getNamespace()
         */
        public String getNamespace() {
            return null;
        }

        /* (non-Javadoc)
         * @see com.sun.org.apache.xerces.internal.xs.XSObject#getNamespaceItem()
         */
        public XSNamespaceItem getNamespaceItem() {
            // REVISIT: implement
            return null;
        }

        /* (non-Javadoc)
         * @see com.sun.org.apache.xerces.internal.xs.XSObject#getType()
         */
        public short getType() {
            return XSConstants.MULTIVALUE_FACET;
        }
    }

    private static abstract class AbstractObjectList extends AbstractList implements ObjectList {
        public Object get(int index) {
            if (index >= 0 && index < getLength()) {
                return item(index);
            }
            throw new IndexOutOfBoundsException("Index: " + index);
        }
        public int size() {
            return getLength();
        }
    }

    public String getTypeNamespace() {
        return getNamespace();
    }

    public boolean isDerivedFrom(String typeNamespaceArg, String typeNameArg, int derivationMethod) {
        return isDOMDerivedFrom(typeNamespaceArg, typeNameArg, derivationMethod);
    }

    private short convertToPrimitiveKind(short valueType) {
        /** Primitive datatypes. */
        if (valueType <= XSConstants.NOTATION_DT) {
            return valueType;
        }
        /** Types derived from string. */
        if (valueType <= XSConstants.ENTITY_DT) {
            return XSConstants.STRING_DT;
        }
        /** Types derived from decimal. */
        if (valueType <= XSConstants.POSITIVEINTEGER_DT) {
            return XSConstants.DECIMAL_DT;
        }
        /** Other types. */
        return valueType;
    }

} // class XSSimpleTypeDecl
