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

    public void reset(){

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

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

        fFacetsDefined = 0;
        fFixedFacet = 0;

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

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

        // REVISIT: reset for fundamental facets
    }

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

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

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

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

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

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

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

    public Object getMinInclusiveValue() {
        return fMinInclusive;
    }

    public Object getMinExclusiveValue() {
        return fMinExclusive;
    }

    public Object getMaxInclusiveValue() {
        return fMaxInclusive;
    }

    public Object getMaxExclusiveValue() {
        return fMaxExclusive;
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

    }

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

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

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

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

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

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

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

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

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

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

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

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

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