/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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 org.apache.jena.ext.xerces.impl.dv.xs;

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

import org.apache.jena.ext.xerces.impl.Constants;
import org.apache.jena.ext.xerces.impl.dv.*;
import org.apache.jena.ext.xerces.impl.xpath.regex.RegularExpression;
import org.apache.jena.ext.xerces.impl.xs.SchemaSymbols;
import org.apache.jena.ext.xerces.impl.xs.util.ObjectListImpl;
import org.apache.jena.ext.xerces.impl.xs.util.ShortListImpl;
import org.apache.jena.ext.xerces.impl.xs.util.StringListImpl;
import org.apache.jena.ext.xerces.impl.xs.util.XSObjectListImpl;
import org.apache.jena.ext.xerces.util.XMLChar;
import org.apache.jena.ext.xerces.xni.NamespaceContext;
import org.apache.jena.ext.xerces.xs.*;
import org.apache.jena.ext.xerces.xs.datatypes.ObjectList;
import org.w3c.dom.TypeInfo;

/**
 * {@literal @xerces.internal}
 *  
 * @author Sandy Gao, IBM
 * @author Neeraj Bajaj, Sun Microsystems, inc.
 *
 * @version $Id: XSSimpleTypeDecl.java 1026362 2010-10-22 15:15:18Z sandygao $
 */
@SuppressWarnings("all")
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;
    protected static final short DV_DATETIMESTAMP = DV_NOTATION + 10;

    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
        new DateTimeStampDV()       // 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;
    public static final short DATETIMESTAMP_DT          = 50;

    // 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() {
        @Override
        public boolean needFacetChecking() {
            return true;
        }
        @Override
        public boolean needExtraChecking() {
            return false;
        }
        @Override
        public boolean needToNormalize() {
            return true;
        }
        @Override
        public boolean useNamespaces () {
            return true;
        }
        @Override
        public boolean isEntityDeclared (String name) {
            return false;
        }
        @Override
        public boolean isEntityUnparsed (String name) {
            return false;
        }
        @Override
        public boolean isIdDeclared (String name) {
            return false;
        }
        @Override
        public void addId(String name) {
        }
        @Override
        public void addIdRef(String name) {
        }
        @Override
        public String getSymbol (String symbol) {
            return symbol.intern();
        }
        @Override
        public String getURI(String prefix) {
            return null;
        }
        @Override
        public Locale getLocale() {
            return Locale.getDefault();
        }
    };

    protected static TypeValidator[] getGDVs() {
        return 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 ValidatedInfo[] fEnumeration;
    private int fEnumerationSize;
    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;
        fEnumerationSize = fBase.fEnumerationSize;
        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 = 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;
        fEnumerationSize = fBase.fEnumerationSize;
        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 = 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;
    }

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

    @Override
    public short getTypeCategory () {
        return SIMPLE_TYPE;
    }

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

    @Override
    public String getTypeName() {
        return fTypeName;
    }

    @Override
    public String getNamespace() {
        return fTargetNamespace;
    }

    @Override
    public short getFinal(){
        return fFinalSet;
    }

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

    @Override
    public XSTypeDefinition getBaseType(){
        return fBase;
    }

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

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

    @Override
    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;
    }

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

    @Override
    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.
     */
    @Override
    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>.
     */
    @Override
    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>.
     */
    @Override
    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>.
     */
    @Override
    public XSObjectList getMemberTypes() {
        if (fVariety == VARIETY_UNION) {
            return new XSObjectListImpl(fMemberTypes, fMemberTypes.length);
        }
        else {
            return XSObjectListImpl.EMPTY_LIST;
        }
    }

    /**
     * If <restriction> is chosen
     */
    @Override
    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 {
                Vector enumVals = facets.enumeration;
                int size = enumVals.size();
                fEnumeration = new ValidatedInfo[size];
                Vector enumNSDecls = facets.enumNSDecls;
                ValidationContextImpl ctx = new ValidationContextImpl(context);
                enumerationAnnotations = facets.enumAnnotations;
                fEnumerationSize = 0;
                for (int i = 0; i < size; i++) {
                    if (enumNSDecls != null)
                        ctx.setNSContext((NamespaceContext)enumNSDecls.elementAt(i));
                    try {
                        ValidatedInfo info = getActualEnumValue((String)enumVals.elementAt(i), ctx, null);
                        // check 4.3.5.c0 must: enumeration values from the value space of base
                        fEnumeration[fEnumerationSize++] = info;
                    } 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;
            fEnumerationSize = fBase.fEnumerationSize;
            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
     */
    @Override
    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
     */
    @Override
    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
     */
    @Override
    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 = fEnumerationSize;
            final short primitiveType1 = convertToPrimitiveKind(type);
            for (int i = 0; i < enumSize; i++) {
                final short primitiveType2 = convertToPrimitiveKind(fEnumeration[i].actualValueType);
                if ((primitiveType1 == primitiveType2 ||
                        primitiveType1 == XSConstants.ANYSIMPLETYPE_DT && primitiveType2 == XSConstants.STRING_DT ||
                        primitiveType1 == XSConstants.STRING_DT && primitiveType2 == XSConstants.ANYSIMPLETYPE_DT)
                        && fEnumeration[i].actualValue.equals(ob)) {
                    if (primitiveType1 == XSConstants.LIST_DT || primitiveType1 == XSConstants.LISTOFUNION_DT) {
                        ShortList enumItemType = fEnumeration[i].itemValueTypes;
                        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){
                StringBuffer sb = new StringBuffer();
                appendEnumString(sb);
                throw new InvalidDatatypeValueException("cvc-enumeration-valid",
                        new Object [] {content, sb.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 ) {
            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;
            validatedInfo.actualType = this;

            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;
            // Need to set it here or it will become the item type
            validatedInfo.actualType = this;

            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];
                    // Need to set it here or it will become the member type
                    validatedInfo.actualType = this;
                    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) {
                    typesBuffer.append(" : ");
                    decl.appendEnumString(typesBuffer);
                }             
            }
            throw new InvalidDatatypeValueException("cvc-datatype-valid.1.2.3",
                    new Object[]{content, fTypeName, typesBuffer.toString()});
        }

    }//getActualValue()

    @Override
    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.
     */
    @Override
    public short getOrdered() {
        return fOrdered;
    }

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

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

    /**
     * Fundamental Facet: numeric.
     */
    @Override
    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.
     */
    @Override
    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.
     */
    @Override
    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.
     */
    @Override
    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.
     */
    @Override
    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>.
     */
    @Override
    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>.
     */
    @Override
    public StringList getLexicalEnumeration() {
        if (fLexicalEnumeration == null){
            if (fEnumeration == null)
                return StringListImpl.EMPTY_LIST;
            int size = fEnumerationSize;
            String[] strs = new String[size];
            for (int i = 0; i < size; i++)
                strs[i] = fEnumeration[i].normalizedValue;
            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() {
                @Override
                public int getLength() {
                    return (fEnumeration != null) ? fEnumerationSize : 0;
                }
                @Override
                public boolean contains(Object item) {
                    if (fEnumeration == null) {
                        return false;
                    }
                    for (int i = 0; i < fEnumerationSize; i++) {
                        if (fEnumeration[i].getActualValue().equals(item)) {
                            return true;
                        }
                    }
                    return false;
                }
                @Override
                public Object item(int index) {
                    if (index < 0 || index >= getLength()) {
                        return null;
                    }
                    return fEnumeration[index].getActualValue();
                }
            };
        }
        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 (fEnumeration == null) {
                return null;
            }
            fEnumerationItemTypeList = new AbstractObjectList() {
                @Override
                public int getLength() {
                    return (fEnumeration != null) ? fEnumerationSize : 0;
                }
                @Override
                public boolean contains(Object item) {
                    if (fEnumeration == null || !(item instanceof ShortList))
                        return false;
                    for (int i = 0;i < fEnumerationSize; i++)
                        if (fEnumeration[i].itemValueTypes == item)
                            return true;
                    return false;
                }
                @Override
                public Object item(int index) {
                    if (index < 0 || index >= getLength()) {
                        return null;
                    }
                    return fEnumeration[index].itemValueTypes;
                }
            };
        }
        return fEnumerationItemTypeList;
    }

    public ShortList getEnumerationTypeList() {
        if (fEnumerationTypeList == null) {
            if (fEnumeration == null) {
                return ShortListImpl.EMPTY_LIST;
            }
            short[] list = new short[fEnumerationSize];
            for (int i = 0; i < fEnumerationSize; i++) {
                list[i] = fEnumeration[i].actualValueType;
            }
            fEnumerationTypeList = new ShortListImpl(list, fEnumerationSize);
        }
        return fEnumerationTypeList;
    }

    /**
     * A list of pattern values if it exists, otherwise an empty
     * <code>StringList</code>.
     */
    @Override
    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>.
     */
    @Override
    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()

    @Override
    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;
    }

    @Override
    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 = 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() {
        @Override
        public boolean needFacetChecking() {
            return true;
        }

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

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

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

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

        @Override
        public void addId(String name) {
        }

        @Override
        public void addIdRef(String name) {
        }

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

        @Override
        public String getURI(String prefix) {
            return null;
        }
        
        @Override
        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;
        }

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

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

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

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

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

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

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

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

        @Override
        public String getURI(String prefix) {
            if (fNSContext == null) {
                return fExternal.getURI(prefix);
            }
            else {
                return fNSContext.getURI(prefix);
            }
        }
        
        @Override
        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;
        fLexicalPattern = null;
        fLexicalEnumeration = null;
        fActualEnumeration = null;
        fEnumerationTypeList = null;
        fEnumerationItemTypeList = 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 org.apache.jena.ext.xerces.xs.XSObject#getNamespaceItem()
     */
    @Override
    public XSNamespaceItem getNamespaceItem() {
        return fNamespaceItem;
    }
    
    public void setNamespaceItem(XSNamespaceItem namespaceItem) {
        fNamespaceItem = namespaceItem;
    }

    /**
     * @see java.lang.Object#toString()
     */
    @Override
    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.
     */
    @Override
    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],
                            0,
                            null,
                            (fFixedFacet & FACET_WHITESPACE) != 0,
                            whiteSpaceAnnotation);
                count++;
            }
            if (fLength != -1) {
                facets[count] =
                    new XSFacetImpl(
                            FACET_LENGTH,
                            Integer.toString(fLength),
                            fLength,
                            null,
                            (fFixedFacet & FACET_LENGTH) != 0,
                            lengthAnnotation);
                count++;
            }
            if (fMinLength != -1) {
                facets[count] =
                    new XSFacetImpl(
                            FACET_MINLENGTH,
                            Integer.toString(fMinLength),
                            fMinLength,
                            null,
                            (fFixedFacet & FACET_MINLENGTH) != 0,
                            minLengthAnnotation);
                count++;
            }
            if (fMaxLength != -1) {
                facets[count] =
                    new XSFacetImpl(
                            FACET_MAXLENGTH,
                            Integer.toString(fMaxLength),
                            fMaxLength,
                            null,
                            (fFixedFacet & FACET_MAXLENGTH) != 0,
                            maxLengthAnnotation);
                count++;
            }
            if (fTotalDigits != -1) {
                facets[count] =
                    new XSFacetImpl(
                            FACET_TOTALDIGITS,
                            Integer.toString(fTotalDigits),
                            fTotalDigits,
                            null,
                            (fFixedFacet & FACET_TOTALDIGITS) != 0,
                            totalDigitsAnnotation);
                count++;
            }
            if (fValidationDV == DV_INTEGER) {
                facets[count] =
                    new XSFacetImpl(
                            FACET_FRACTIONDIGITS,
                            "0",
                            0,
                            null,
                            true,
                            fractionDigitsAnnotation);
                count++;
            }
            else if (fFractionDigits != -1) {
                facets[count] =
                    new XSFacetImpl(
                            FACET_FRACTIONDIGITS,
                            Integer.toString(fFractionDigits),
                            fFractionDigits,
                            null,
                            (fFixedFacet & FACET_FRACTIONDIGITS) != 0,
                            fractionDigitsAnnotation);
                count++;
            }
            if (fMaxInclusive != null) {
                facets[count] =
                    new XSFacetImpl(
                            FACET_MAXINCLUSIVE,
                            fMaxInclusive.toString(),
                            0,
                            fMaxInclusive,
                            (fFixedFacet & FACET_MAXINCLUSIVE) != 0,
                            maxInclusiveAnnotation);
                count++;
            }
            if (fMaxExclusive != null) {
                facets[count] =
                    new XSFacetImpl(
                            FACET_MAXEXCLUSIVE,
                            fMaxExclusive.toString(),
                            0,
                            fMaxExclusive,
                            (fFixedFacet & FACET_MAXEXCLUSIVE) != 0,
                            maxExclusiveAnnotation);
                count++;
            }
            if (fMinExclusive != null) {
                facets[count] =
                    new XSFacetImpl(
                            FACET_MINEXCLUSIVE,
                            fMinExclusive.toString(),
                            0,
                            fMinExclusive,
                            (fFixedFacet & FACET_MINEXCLUSIVE) != 0,
                            minExclusiveAnnotation);
                count++;
            }
            if (fMinInclusive != null) {
                facets[count] =
                    new XSFacetImpl(
                            FACET_MININCLUSIVE,
                            fMinInclusive.toString(),
                            0,
                            fMinInclusive,
                            (fFixedFacet & FACET_MININCLUSIVE) != 0,
                            minInclusiveAnnotation);
                count++;
            }
            fFacets = (count > 0) ? new XSObjectListImpl(facets, count) : XSObjectListImpl.EMPTY_LIST;
        }
        return (fFacets != null) ? fFacets : XSObjectListImpl.EMPTY_LIST;
    }

    @Override
    public XSObject getFacet(int facetType) {
        if (facetType == FACET_ENUMERATION || facetType == FACET_PATTERN) {
            XSObjectList list = getMultiValueFacets();
            for (int i = 0; i < list.getLength(); i++) {
                XSMultiValueFacet f = (XSMultiValueFacet)list.item(i);
                if (f.getFacetKind() == facetType) {
                    return f;
                }
            }
        }
        else {
            XSObjectList list = getFacets();
            for (int i = 0; i < list.getLength(); i++) {
                XSFacet f = (XSFacet)list.item(i);
                if (f.getFacetKind() == facetType) {
                    return f;
                }
            }
        }
        return null;
    }
    
    /**
     *  A list of enumeration and pattern constraining facets if it exists,
     * otherwise an empty <code>XSObjectList</code>.
     */
    @Override
    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(),
                            null,
                            patternAnnotations);
                count++;
            }
            if (fEnumeration != null) {
                facets[count] =
                    new XSMVFacetImpl(
                            FACET_ENUMERATION,
                            this.getLexicalEnumeration(),
                            new ObjectListImpl(fEnumeration, fEnumerationSize),
                            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 svalue;
        final int ivalue;
        Object avalue;
        final boolean fixed;
        final XSObjectList annotations;  

        public XSFacetImpl(short kind, String svalue, int ivalue, Object avalue, boolean fixed, XSAnnotation annotation) {
            this.kind = kind;
            this.svalue = svalue;
            this.ivalue = ivalue;
            this.avalue = avalue;
            this.fixed = fixed;

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

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

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

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

        /* (non-Javadoc)
         * @see org.apache.xerces.xs.XSFacet#getLexicalFacetValue()
         */
        @Override
        public String getLexicalFacetValue() {
            return svalue;
        }

        @Override
        public Object getActualFacetValue() {
            if (avalue == null) {
                if (kind == FACET_WHITESPACE) {
                    avalue = svalue;
                }
                else {
                    // Must a facet with an integer value. Use BigInteger.
                    avalue = BigInteger.valueOf(ivalue);
                }
            }
            return avalue;
        }
        
        @Override
        public int getIntFacetValue() {
            return ivalue;
        }
        
        /* (non-Javadoc)
         * @see org.apache.xerces.xs.XSFacet#isFixed()
         */
        @Override
        public boolean getFixed() {
            return fixed;
        }

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

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

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

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

    }

    private static final class XSMVFacetImpl implements XSMultiValueFacet {
        final short kind;
        final XSObjectList annotations;
        final StringList svalues;
        final ObjectList avalues;

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

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

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

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

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

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

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

        /* (non-Javadoc)
         * @see org.apache.xerces.xs.XSObject#getType()
         */
        public short getType() {
            return XSConstants.MULTIVALUE_FACET;
        }
    }
    
    private static abstract class AbstractObjectList extends AbstractList<Object> 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;
    }

    private void appendEnumString(StringBuffer sb) {
        sb.append('[');
        for (int i = 0; i < fEnumerationSize; i++) {
            if (i != 0) {
                sb.append(", ");
            }
            sb.append(fEnumeration[i].actualValue);
        }
        sb.append(']');
    }
} // class XSSimpleTypeDecl

