/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 2003 The Apache Software Foundation.  All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
*    notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
*    notice, this list of conditions and the following disclaimer in
*    the documentation and/or other materials provided with the
*    distribution.
*
* 3. The end-user documentation included with the redistribution,
*    if any, must include the following acknowledgment:
*       "This product includes software developed by the
*        Apache Software Foundation (http://www.apache.org/)."
*    Alternately, this acknowledgment may appear in the software itself,
*    if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Apache" and "Apache Software Foundation" must
*    not be used to endorse or promote products derived from this
*    software without prior written permission. For written
*    permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache
*    XMLBeans", nor may "Apache" appear in their name, without prior
*    written permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation and was
* originally based on software copyright (c) 2000-2003 BEA Systems
* Inc., <http://www.bea.com/>. For more information on the Apache Software
* Foundation, please see <http://www.apache.org/>.
*/

package org.apache.xmlbeans.impl.schema;

import org.apache.xmlbeans.impl.values.*;
import org.apache.xmlbeans.impl.regex.RegularExpression;
import org.apache.xmlbeans.impl.common.QNameHelper;
import org.apache.xmlbeans.XmlObject;
import org.apache.xmlbeans.SchemaGlobalElement;
import org.apache.xmlbeans.SchemaComponent;
import org.apache.xmlbeans.SchemaField;
import org.apache.xmlbeans.SchemaType;
import org.apache.xmlbeans.SchemaParticle;
import org.apache.xmlbeans.SchemaGlobalAttribute;
import org.apache.xmlbeans.SchemaAttributeModel;
import org.apache.xmlbeans.SchemaTypeSystem;
import org.apache.xmlbeans.SchemaProperty;
import org.apache.xmlbeans.QNameSet;
import org.apache.xmlbeans.SchemaLocalAttribute;
import org.apache.xmlbeans.SchemaLocalElement;
import org.apache.xmlbeans.XmlAnySimpleType;
import org.apache.xmlbeans.StringEnumAbstractBase;
import org.apache.xmlbeans.SchemaStringEnumEntry;
import org.apache.xmlbeans.SchemaTypeLoader;

import java.lang.reflect.Constructor;
import java.util.*;
import java.math.BigInteger;

import javax.xml.namespace.QName;

public final class SchemaTypeImpl implements SchemaType, TypeStoreUserFactory
{
    // global types have names
    private QName _name;

    // compilation support
    private int _resolvePhase;
    private static final int UNRESOLVED = 0;
    private static final int RESOLVING_SGS = 1; // For document types only
    private static final int RESOLVED_SGS = 2;  // For document types only
    private static final int RESOLVING = 3;
    private static final int RESOLVED = 4;
    private static final int JAVAIZING = 5;
    private static final int JAVAIZED = 6;

    // anonymous type support
    private SchemaType.Ref _outerSchemaTypeRef;
    private volatile SchemaComponent.Ref _containerFieldRef;
    private volatile SchemaField _containerField;
    private volatile int _containerFieldCode;
    private volatile int _containerFieldIndex;
    private SchemaType.Ref[] _anonymousTyperefs;
    private boolean _isDocumentType;
    private boolean _isAttributeType;
    // private boolean _skippedAnonymousType;

    // compiletime java type support
    private boolean _isCompiled;
    private String _shortJavaName;
    private String _fullJavaName;
    private String _shortJavaImplName;
    private String _fullJavaImplName;

    // runtime java type support: volatile because they're cached
    private volatile Class _javaClass;
    private volatile Class _javaEnumClass;
    private volatile Class _javaImplClass;
    private volatile Constructor _javaImplConstructor;
    private volatile Constructor _javaImplConstructor2;
    private volatile boolean _implNotAvailable;

    private final Object[] _ctrArgs = new Object[] { this };

    // reflective support
    private SchemaTypeSystem _typeSystem;
    private String _filename;

    // complex content support
    private SchemaParticle _contentModel;
    private volatile SchemaLocalElement[] _localElts; // lazily computed
    private volatile Map _eltToIndexMap; // lazily computed
    private volatile Map _attrToIndexMap; // lazily computed
    private Map _propertyModelByElementName;
    private Map _propertyModelByAttributeName;
    private boolean _hasAllContent;
    private boolean _orderSensitive;
    private QNameSet _typedWildcardElements;
    private QNameSet _typedWildcardAttributes;
    private boolean _hasWildcardElements;
    private boolean _hasWildcardAttributes;
    // set of valid QNames that can be substituted for a property
    private Set _validSubstitutions = Collections.EMPTY_SET;

    // simple content support
    private int _complexTypeVariety;
    private SchemaAttributeModel _attributeModel;

    // simple type support
    private int _builtinTypeCode;

    private int _simpleTypeVariety;
    private boolean _isSimpleType;

    private SchemaType.Ref _baseTyperef; // via restriction or extension
    private int _baseDepth; // how many inheritance steps to AnyType
    private int _derivationType;

    // facets
    private XmlValueRef[] _facetArray;
    private boolean[] _fixedFacetArray;

    // fundamental facets
    private int _ordered;
    private boolean _isFinite;
    private boolean _isBounded;
    private boolean _isNumeric;

    private boolean _abs;
    private boolean _finalExt;
    private boolean _finalRest;
    private boolean _finalList;
    private boolean _finalUnion;
    private boolean _blockExt;
    private boolean _blockRest;

    // whitespace facet
    private int _whiteSpaceRule;

    // regex patterns
    private boolean _hasPatterns; // also takes into account base classes
    private org.apache.xmlbeans.impl.regex.RegularExpression[] _patterns;

    // enumerated values
    private XmlValueRef[] _enumerationValues;
    private SchemaType.Ref _baseEnumTyperef;
    private boolean _stringEnumEnsured;
    private volatile Map _lookupStringEnum;
    private volatile List _listOfStringEnum;
    private volatile Map _lookupStringEnumEntry;
    private SchemaStringEnumEntry[] _stringEnumEntries;

    // for lists only
    private SchemaType.Ref _listItemTyperef;

    // for unions only
    private boolean _isUnionOfLists;
    private SchemaType.Ref[] _unionMemberTyperefs;
    private int _anonymousUnionMemberOrdinal;
    private volatile SchemaType[] _unionConstituentTypes;
    private volatile SchemaType[] _unionSubTypes;
    private volatile SchemaType _unionCommonBaseType;

    // for atomic types only
    private SchemaType.Ref _primitiveTypeRef;

    // for decimal restrictions only
    private int _decimalSize;

    // lazy loading support
    private volatile boolean _unloaded;

    // for document types only - only valid during compilation
    private QName _sg;
    private List _sgMembers = new ArrayList();

    public boolean isUnloaded()
    {
        return _unloaded;
    }

    public void finishLoading()
    {
        _unloaded = false;
    }



    SchemaTypeImpl(SchemaTypeSystem typeSystem)
    {
        _typeSystem = typeSystem;
    }

    SchemaTypeImpl(SchemaTypeSystem typeSystem, boolean unloaded)
    {
        _typeSystem = typeSystem;
        _unloaded = unloaded;
        if (unloaded)
            finishQuick();
    }

    public boolean isSGResolved()
        { return _resolvePhase >= RESOLVED_SGS; }

    public boolean isSGResolving()
        { return _resolvePhase >= RESOLVING_SGS; }

    public boolean isResolved()
        { return _resolvePhase >= RESOLVED; }

    public boolean isResolving()
        { return _resolvePhase == RESOLVING; }

    public boolean isUnjavaized()
        { return _resolvePhase < JAVAIZED; }

    public boolean isJavaized()
        { return _resolvePhase == JAVAIZED; }

    public void startResolvingSGs()
    {
        if (_resolvePhase != UNRESOLVED)
            throw new IllegalStateException();
        _resolvePhase = RESOLVING_SGS;
    }

    public void finishResolvingSGs()
    {
        if (_resolvePhase != RESOLVING_SGS)
            throw new IllegalStateException();
        _resolvePhase = RESOLVED_SGS;
    }

    public void startResolving()
    {
        if ( (_isDocumentType && _resolvePhase != RESOLVED_SGS) ||
             (!_isDocumentType && _resolvePhase != UNRESOLVED))
            throw new IllegalStateException();
        _resolvePhase = RESOLVING;
    }

    public void finishResolving()
    {
        if (_resolvePhase != RESOLVING)
            throw new IllegalStateException();
        _resolvePhase = RESOLVED;
    }

    public void startJavaizing()
    {
        if (_resolvePhase != RESOLVED)
            throw new IllegalStateException();
        _resolvePhase = JAVAIZING;
    }

    public void finishJavaizing()
    {
        if (_resolvePhase != JAVAIZING)
            throw new IllegalStateException();
        _resolvePhase = JAVAIZED;
    }

    private void finishQuick()
    {
        _resolvePhase = JAVAIZED;
    }

    private void assertUnresolved()
    {
        if (_resolvePhase != UNRESOLVED && !_unloaded)
            throw new IllegalStateException();
    }

    private void assertSGResolving()
    {
        if (_resolvePhase != RESOLVING_SGS && !_unloaded)
            throw new IllegalStateException();
    }

    private void assertSGResolved()
    {
        if (_resolvePhase != RESOLVED_SGS && !_unloaded)
            throw new IllegalStateException();
    }

    private void assertResolving()
    {
        if (_resolvePhase != RESOLVING && !_unloaded)
            throw new IllegalStateException();
    }

    private void assertResolved()
    {
        if (_resolvePhase != RESOLVED && !_unloaded)
            throw new IllegalStateException();
    }

    private void assertJavaizing()
    {
        if (_resolvePhase != JAVAIZING && !_unloaded)
            throw new IllegalStateException();
    }

    public QName getName()
        { return _name; }

    public void setName(QName name)
        { assertUnresolved(); _name = name; }

    public String getSourceName()
    {
        if (_filename != null)
            return _filename;
        if (getOuterType() != null)
            return getOuterType().getSourceName();

        SchemaField field = getContainerField();
        if (field != null)
        {
            if (field instanceof SchemaGlobalElement)
                return ((SchemaGlobalElement)field).getSourceName();
            if (field instanceof SchemaGlobalAttribute)
                return ((SchemaGlobalAttribute)field).getSourceName();
        }
        return null;
    }

    public void setFilename(String filename)
        { assertUnresolved(); _filename = filename; }

    public int getComponentType()
        { return SchemaComponent.TYPE; }

    public boolean isAnonymousType()
        { return _name == null; }

    public boolean isDocumentType()
        { return _isDocumentType; }

    public boolean isAttributeType()
        { return _isAttributeType; }

    public QName getDocumentElementName()
    {
        if (_isDocumentType)
        {
            SchemaParticle sp = getContentModel();
            if (sp != null)
                return sp.getName();
        }

        return null;
    }

    public QName getAttributeTypeAttributeName()
    {
        if (_isAttributeType)
        {
            SchemaAttributeModel sam = getAttributeModel();
            if (sam != null)
            {
                SchemaLocalAttribute[] slaArray = sam.getAttributes();
                if (slaArray != null && slaArray.length > 0)
                {
                    SchemaLocalAttribute sla = slaArray[0];
                    return sla.getName();
                }
            }
        }

        return null;
    }

    public void setDocumentType(boolean isDocument)
        { assertUnresolved(); _isDocumentType = isDocument; }

    public void setAttributeType(boolean isAttribute)
        { assertUnresolved(); _isAttributeType = isAttribute; }

    public int getContentType()
        { return _complexTypeVariety; }

    public void setComplexTypeVariety(int complexTypeVariety)
        { assertResolving(); _complexTypeVariety = complexTypeVariety; }

    /** Set the abstract and final flags for a complex type */
    void setAbstractFinal(
        boolean abs, boolean finalExt, boolean finalRest, boolean finalList, boolean finalUnion)
    {
        assertResolving();
        _abs = abs;
        _finalExt = finalExt; _finalRest = finalRest;
        _finalList = finalList; _finalUnion = finalUnion;
    }

    /** Set the final flags for a simple type */
    void setSimpleFinal(boolean finalRest, boolean finalList, boolean finalUnion)
    {
        assertResolving(); _finalRest = finalRest; _finalList = finalList ; _finalUnion = finalUnion;
    }

    void setBlock(boolean blockExt, boolean blockRest)
    {
        assertResolving(); _blockExt = blockExt ; _blockRest = blockRest;
    }

    public boolean blockRestriction()
    { return _blockRest; }

    public boolean blockExtension()
    { return _blockExt; }

    public boolean isAbstract()
    { return _abs; }

    public boolean finalExtension()
    { return _finalExt; }

    public boolean finalRestriction()
    { return _finalRest; }

    public boolean finalList()
    { return _finalList; }

    public boolean finalUnion()
    { return _finalUnion; }

    public synchronized SchemaField getContainerField()
    {
        if (_containerFieldCode != -1)
        {
            SchemaType outer = getOuterType();
            if (_containerFieldCode == 0)
                _containerField = _containerFieldRef == null ? null : (SchemaField)_containerFieldRef.getComponent();
            else if (_containerFieldCode == 1)
                _containerField = outer.getAttributeModel().getAttributes()[_containerFieldIndex];
            else
                _containerField = ((SchemaTypeImpl)outer).getLocalElementByIndex(_containerFieldIndex);
            _containerFieldCode = -1;
        }
        return _containerField;
    }

    public void setContainerField(SchemaField field)
    {
        assertUnresolved();
        _containerField = field;
        _containerFieldCode = -1;
    }

    public void setContainerFieldRef(SchemaComponent.Ref ref)
    {
        assertUnresolved();
        _containerFieldRef = ref;
        _containerFieldCode = 0;
    }

    public void setContainerFieldIndex(short code, int index)
    {
        assertUnresolved();
        _containerFieldCode = code;
        _containerFieldIndex = index;
    }

    public SchemaType getOuterType()
        { return _outerSchemaTypeRef == null ? null : _outerSchemaTypeRef.get(); }

    public void setOuterSchemaTypeRef(SchemaType.Ref typeref)
        { assertUnresolved(); _outerSchemaTypeRef = typeref; }

    public boolean isCompiled()
        { return _isCompiled; }

    public void setCompiled(boolean f)
        { assertJavaizing(); _isCompiled = f; }

    public boolean isSkippedAnonymousType()
        { return _outerSchemaTypeRef.get().getBaseType() == this; }

    public String getShortJavaName()
        { return _shortJavaName; }

    public void setShortJavaName(String name)
    {
        assertResolved();
        _shortJavaName = name;
        SchemaType outer = _outerSchemaTypeRef.get();
        while (outer.getFullJavaName() == null)
            outer = outer.getOuterType();

        _fullJavaName = outer.getFullJavaName() + "$" + _shortJavaName;
    }

    public String getFullJavaName()
        { return _fullJavaName; }

    public void setFullJavaName(String name)
    {
        assertResolved();
        _fullJavaName = name;
        int index = Math.max(_fullJavaName.lastIndexOf('$'),
                             _fullJavaName.lastIndexOf('.')) + 1;
        _shortJavaName = _fullJavaName.substring(index);
    }

    public void setShortJavaImplName(String name)
    {
        assertResolved();
        _shortJavaImplName = name;
        SchemaType outer = _outerSchemaTypeRef.get();
        while (outer.getFullJavaImplName() == null)
            outer = outer.getOuterType();

        _fullJavaImplName = outer.getFullJavaImplName() + "$" + _shortJavaImplName;
    }

    public void setFullJavaImplName(String name)
    {
        assertResolved();
        _fullJavaImplName = name;
        int index = Math.max(_fullJavaImplName.lastIndexOf('$'),
                             _fullJavaImplName.lastIndexOf('.')) + 1;
        _shortJavaImplName = _fullJavaImplName.substring(index);
    }

    public String getFullJavaImplName() { return _fullJavaImplName;}
    public String getShortJavaImplName() { return _shortJavaImplName;}

    public SchemaTypeSystem getTypeSystem()
        { return _typeSystem; }

    public SchemaParticle getContentModel()
        { return _contentModel; }

    private static void buildEltList(List eltList, SchemaParticle contentModel)
    {
        if (contentModel == null)
            return;

        switch (contentModel.getParticleType())
        {
            case SchemaParticle.ELEMENT:
                eltList.add(contentModel);
                return;
            case SchemaParticle.ALL:
            case SchemaParticle.CHOICE:
            case SchemaParticle.SEQUENCE:
                for (int i = 0; i < contentModel.countOfParticleChild(); i++)
                    buildEltList(eltList, contentModel.getParticleChild(i));
                return;
            default:
                return;
        }
    }

    private void buildLocalElts()
    {
        List eltList = new ArrayList();
        buildEltList(eltList, _contentModel);
        _localElts = (SchemaLocalElement[])eltList.toArray(new SchemaLocalElement[eltList.size()]);
    }

    public SchemaLocalElement getLocalElementByIndex(int i)
    {
        SchemaLocalElement[] elts = _localElts;
        if (elts == null)
        {
            buildLocalElts();
            elts = _localElts;
        }
        return elts[i];
    }

    public int getIndexForLocalElement(SchemaLocalElement elt)
    {
        Map localEltMap = _eltToIndexMap;
        if (localEltMap == null)
        {
            if (_localElts == null)
                buildLocalElts();
            localEltMap = new HashMap();
            for (int i = 0; i < _localElts.length; i++)
            {
                localEltMap.put(_localElts[i], new Integer(i));
            }
            _eltToIndexMap = localEltMap;
        }
        return ((Integer)localEltMap.get(elt)).intValue();
    }

    public int getIndexForLocalAttribute(SchemaLocalAttribute attr)
    {
        Map localAttrMap = _attrToIndexMap;
        if (localAttrMap == null)
        {
            localAttrMap = new HashMap();
            SchemaLocalAttribute[] attrs = this._attributeModel.getAttributes();
            for (int i = 0; i < attrs.length; i++)
            {
                localAttrMap.put(attrs[i], new Integer(i));
            }
            _attrToIndexMap = localAttrMap;
        }
        return ((Integer)localAttrMap.get(attr)).intValue();
    }

    public SchemaAttributeModel getAttributeModel()
        { return _attributeModel; }

    public SchemaProperty[] getProperties()
    {
        if (_propertyModelByElementName == null)
            return getAttributeProperties();

        if (_propertyModelByAttributeName == null)
            return getElementProperties();

        List list = new ArrayList();
        list.addAll(_propertyModelByElementName.values());
        list.addAll(_propertyModelByAttributeName.values());
        return (SchemaProperty[])list.toArray(new SchemaProperty[list.size()]);
    }

    private static final SchemaProperty[] NO_PROPERTIES = new SchemaProperty[0];

    public SchemaProperty[] getDerivedProperties()
    {
        SchemaType baseType = getBaseType();
        if (baseType == null)
            return getProperties();

        List results = new ArrayList();

        if (_propertyModelByElementName != null)
            results.addAll(_propertyModelByElementName.values());

        if (_propertyModelByAttributeName != null)
            results.addAll(_propertyModelByAttributeName.values());

        for (Iterator it = results.iterator() ; it.hasNext() ; )
        {
            SchemaProperty prop = (SchemaProperty)it.next();
            SchemaProperty baseProp = prop.isAttribute() ?
                baseType.getAttributeProperty(prop.getName()) :
                baseType.getElementProperty(prop.getName());


            // Remove the derived property from the results if it is
            // A) present in the base type and
            // B) all the details are the same (cardinality, nillability)

            if (baseProp != null)
            {
                if ( eq(prop.getMinOccurs(), baseProp.getMinOccurs()) &&
                     eq(prop.getMaxOccurs(), baseProp.getMaxOccurs()) &&
                     prop.hasNillable() == baseProp.hasNillable())
                {
                    it.remove();
                }

            }

        }

        return (SchemaProperty[])results.toArray(new SchemaProperty[results.size()]);
    }

    private static boolean eq(BigInteger a, BigInteger b)
    {
        if (a == null && b == null)
            return true;
        if (a== null || b == null)
            return false;
        return a.equals(b);
    }

    public SchemaProperty[] getElementProperties()
    {
        if (_propertyModelByElementName == null)
            return NO_PROPERTIES;

        return (SchemaProperty[])
                _propertyModelByElementName.values().toArray(new SchemaProperty[_propertyModelByElementName.size()]);
    }

    public SchemaProperty[] getAttributeProperties()
    {
        if (_propertyModelByAttributeName == null)
            return NO_PROPERTIES;

        return (SchemaProperty[])
                _propertyModelByAttributeName.values().toArray(new SchemaProperty[_propertyModelByAttributeName.size()]);
    }

    public SchemaProperty getElementProperty(QName eltName)
        { return _propertyModelByElementName == null ? null : (SchemaProperty)_propertyModelByElementName.get(eltName); }

    public SchemaProperty getAttributeProperty(QName attrName)
        { return _propertyModelByAttributeName == null ? null : (SchemaProperty)_propertyModelByAttributeName.get(attrName); }

    public boolean hasAllContent()
        { return _hasAllContent; }

    public boolean isOrderSensitive()
        { return _orderSensitive; }

    public void setOrderSensitive(boolean sensitive)
        { assertJavaizing(); _orderSensitive = sensitive; }

    public void setContentModel(
            SchemaParticle contentModel,
            SchemaAttributeModel attrModel,
            Map propertyModelByElementName,
            Map propertyModelByAttributeName,
            boolean isAll)
    {
        assertResolving();
        _contentModel = contentModel;
        _attributeModel = attrModel;
        _propertyModelByElementName = propertyModelByElementName;
        _propertyModelByAttributeName = propertyModelByAttributeName;
        _hasAllContent = isAll;


        // Add entries for each element property for substitution group members
        if (_propertyModelByElementName != null)
        {
            _validSubstitutions = new LinkedHashSet();
            Collection eltProps = _propertyModelByElementName.values();
            for (Iterator it = eltProps.iterator() ; it.hasNext() ; )
            {
                SchemaProperty prop = (SchemaProperty)it.next();
                QName[] names = prop.acceptedNames();
                for (int i = 0 ; i < names.length ; i++)
                {
                    if (! _propertyModelByElementName.containsKey(names[i]))
                        _validSubstitutions.add(names[i]);
                }
            }
        }
    }

    private boolean containsElements()
    {
        return getContentType() == ELEMENT_CONTENT ||
               getContentType() == MIXED_CONTENT;
    }

    public boolean hasAttributeWildcards()
    {
        return _hasWildcardAttributes;
    }

    public boolean hasElementWildcards()
    {
        return _hasWildcardElements;
    }

    public boolean isValidSubstitution(QName name)
    {
        return _validSubstitutions.contains(name);
    }

    public SchemaType getElementType(QName eltName, QName xsiType, SchemaTypeLoader wildcardTypeLoader)
    {
        if (isSimpleType() || !containsElements() || isNoType())
            return BuiltinSchemaTypeSystem.ST_NO_TYPE;

        SchemaType type;
        SchemaProperty prop = (SchemaProperty)_propertyModelByElementName.get(eltName);
        if (prop != null)
        {
            type = prop.getType();
        }
        else
        {
            if (!_typedWildcardElements.contains(eltName))
                return BuiltinSchemaTypeSystem.ST_NO_TYPE;

            SchemaGlobalElement elt = wildcardTypeLoader.findElement(eltName);
            if (elt == null)
                return BuiltinSchemaTypeSystem.ST_NO_TYPE;
            type = elt.getType();
        }

        if (xsiType != null)
        {
            SchemaType itype = wildcardTypeLoader.findType(xsiType);
            if (itype == null)
                return BuiltinSchemaTypeSystem.ST_NO_TYPE;
            if (type.isAssignableFrom(itype))
                return itype;
            else
                return BuiltinSchemaTypeSystem.ST_NO_TYPE;
        }

        return type;
    }

    public SchemaType getAttributeType(QName attrName, SchemaTypeLoader wildcardTypeLoader)
    {
        if (isSimpleType() || isNoType())
            return BuiltinSchemaTypeSystem.ST_NO_TYPE;

        if (isURType())
            return BuiltinSchemaTypeSystem.ST_ANY_SIMPLE;

        SchemaProperty prop = (SchemaProperty)_propertyModelByAttributeName.get(attrName);
        if (prop != null)
            return prop.getType();

        if (!_typedWildcardAttributes.contains(attrName))
            return BuiltinSchemaTypeSystem.ST_NO_TYPE;

        SchemaGlobalAttribute attr = wildcardTypeLoader.findAttribute(attrName);
        if (attr == null)
            return BuiltinSchemaTypeSystem.ST_NO_TYPE;
        return attr.getType();
    }

    public XmlObject createElementType(QName eltName, QName xsiType, SchemaTypeLoader wildcardTypeLoader)
    {
        SchemaType type = null;
        SchemaProperty prop = null;
        if (isSimpleType() || !containsElements() || isNoType())
        {
            type = BuiltinSchemaTypeSystem.ST_NO_TYPE;
        }
        else
        {
            prop = (SchemaProperty)_propertyModelByElementName.get(eltName);
            if (prop != null)
            {
                type = prop.getType();
            }
            else if (!_typedWildcardElements.contains(eltName) &&
                     !_validSubstitutions.contains(eltName))
            {
                type = BuiltinSchemaTypeSystem.ST_NO_TYPE;
            }
            else
            {
                SchemaGlobalElement elt = wildcardTypeLoader.findElement(eltName);
                if (elt != null)
                    type = elt.getType();
                else
                    type = BuiltinSchemaTypeSystem.ST_NO_TYPE;
            }

            if (xsiType != null)
            {
                SchemaType itype = wildcardTypeLoader.findType(xsiType);
                if (itype == null || !type.isAssignableFrom(itype))
                    type = BuiltinSchemaTypeSystem.ST_NO_TYPE;
                else
                    type = itype;
            }
        }

        if (type != null)
            return ((SchemaTypeImpl)type).createUnattachedNode(prop);
        return null;
    }

    public XmlObject createAttributeType(QName attrName, SchemaTypeLoader wildcardTypeLoader)
    {
        SchemaTypeImpl type = null;
        SchemaProperty prop = null;
        if (isSimpleType() || isNoType())
        {
            type = BuiltinSchemaTypeSystem.ST_NO_TYPE;
        }
        else if (isURType())
        {
            type = BuiltinSchemaTypeSystem.ST_ANY_SIMPLE;
        }
        else
        {
            prop = (SchemaProperty)_propertyModelByAttributeName.get(attrName);
            if (prop != null)
            {
                type = (SchemaTypeImpl)prop.getType();
            }
            else if (!_typedWildcardAttributes.contains(attrName))
            {
                type = BuiltinSchemaTypeSystem.ST_NO_TYPE;
            }
            else
            {
                SchemaGlobalAttribute attr = wildcardTypeLoader.findAttribute(attrName);
                if (attr != null)
                    type = (SchemaTypeImpl)attr.getType();
                else
                    type = BuiltinSchemaTypeSystem.ST_NO_TYPE;
            }
        }

        if (type != null)
            return type.createUnattachedNode(prop);

        return null;
    }

    public void setWildcardSummary(QNameSet elementSet, boolean haswcElt, QNameSet attributeSet, boolean haswcAtt)
    {
        assertResolving(); _typedWildcardElements = elementSet; _hasWildcardElements = haswcElt; _typedWildcardAttributes = attributeSet; _hasWildcardAttributes = haswcAtt;
    }

    public SchemaType[] getAnonymousTypes()
    {
        SchemaType[] result = new SchemaType[_anonymousTyperefs.length];
        for (int i = 0; i < result.length; i++)
            result[i] = _anonymousTyperefs[i].get();
        return result;
    }

    public void setAnonymousTypeRefs(SchemaType.Ref[] anonymousTyperefs)
    {
        _anonymousTyperefs = anonymousTyperefs;
    }


    private static SchemaType[] staCopy(SchemaType[] a)
    {
        if (a == null)
            return null;

        SchemaType[] result = new SchemaType[a.length];
        System.arraycopy(a, 0, result, 0, a.length);
        return result;
    }

    private static boolean[] boaCopy(boolean[] a)
    {
        if (a == null)
            return null;

        boolean[] result = new boolean[a.length];
        System.arraycopy(a, 0, result, 0, a.length);
        return result;
    }



    public void setSimpleTypeVariety(int variety)
        { assertResolving(); _simpleTypeVariety = variety; }

    public int getSimpleVariety()
        { return _simpleTypeVariety; }

    public boolean isURType()
        { return _builtinTypeCode == BTC_ANY_TYPE || _builtinTypeCode == BTC_ANY_SIMPLE; }

    public boolean isNoType()
        { return this == BuiltinSchemaTypeSystem.ST_NO_TYPE; }

    public boolean isSimpleType()
        { return _isSimpleType; }

    public void setSimpleType(boolean f)
        { assertUnresolved(); _isSimpleType = f; }

    public boolean isUnionOfLists()
        { return _isUnionOfLists; }

    public void setUnionOfLists(boolean f)
        { assertResolving(); _isUnionOfLists = f; }

    public SchemaType getPrimitiveType()
        { return _primitiveTypeRef == null ? null : _primitiveTypeRef.get(); }

    public void setPrimitiveTypeRef(SchemaType.Ref typeref)
        { assertResolving(); _primitiveTypeRef = typeref; }

    public int getDecimalSize()
        { return _decimalSize; }

    public void setDecimalSize(int bits)
        { assertResolving(); _decimalSize = bits; }

    public SchemaType getBaseType()
        { return _baseTyperef == null ? null : _baseTyperef.get(); }

    public void setBaseTypeRef(SchemaType.Ref typeref)
        { assertResolving(); _baseTyperef = typeref; }

    public int getBaseDepth()
        { return _baseDepth; }

    public void setBaseDepth(int depth)
        { assertResolving(); _baseDepth = depth; }

    public int getDerivationType()
        { return _derivationType; }

    public void setDerivationType(int type)
        { assertResolving(); _derivationType = type; }

    public SchemaType getListItemType()
        { return _listItemTyperef == null ? null : _listItemTyperef.get(); }

    public void setListItemTypeRef(SchemaType.Ref typeref)
        { assertResolving(); _listItemTyperef = typeref; }

    public SchemaType[] getUnionMemberTypes()
    {
        SchemaType[] result = new SchemaType[_unionMemberTyperefs.length];
        for (int i = 0; i < result.length; i++)
            result[i] = _unionMemberTyperefs[i].get();
        return result;
    }

    public void setUnionMemberTypeRefs(SchemaType.Ref[] typerefs)
        { assertResolving(); _unionMemberTyperefs = typerefs; }

    public int getAnonymousUnionMemberOrdinal()
        { return _anonymousUnionMemberOrdinal; }

    public void setAnonymousUnionMemberOrdinal(int i)
        { assertUnresolved(); _anonymousUnionMemberOrdinal = i; }

    public synchronized SchemaType[] getUnionConstituentTypes()
    {
        if (_unionCommonBaseType == null)
            computeFlatUnionModel();
        return staCopy(_unionConstituentTypes);
    }

    private void setUnionConstituentTypes(SchemaType[] types)
        { _unionConstituentTypes = types; }

    public synchronized SchemaType[] getUnionSubTypes()
    {
        if (_unionCommonBaseType == null)
            computeFlatUnionModel();
        return staCopy(_unionSubTypes);
    }

    private void setUnionSubTypes(SchemaType[] types)
        { _unionSubTypes = types; }

    public synchronized SchemaType getUnionCommonBaseType()
    {
        if (_unionCommonBaseType == null)
            computeFlatUnionModel();
        return _unionCommonBaseType;
    }

    private void setUnionCommonBaseType(SchemaType type)
        { _unionCommonBaseType = type; }

    private void computeFlatUnionModel()
    {
        Set constituentMemberTypes = new LinkedHashSet();
        Set allSubTypes = new LinkedHashSet();
        SchemaType commonBaseType = null;

        allSubTypes.add(this);

        for (int i = 0; i < _unionMemberTyperefs.length; i++)
        {
            SchemaTypeImpl mImpl = (SchemaTypeImpl)_unionMemberTyperefs[i].get();

            switch (mImpl.getSimpleVariety())
            {
                case SchemaType.LIST:
                    constituentMemberTypes.add(mImpl);
                    allSubTypes.add(mImpl);
                    commonBaseType = mImpl.getCommonBaseType(commonBaseType);
                    break;
                case SchemaType.UNION:
                    constituentMemberTypes.addAll(Arrays.asList(mImpl.getUnionConstituentTypes()));
                    allSubTypes.addAll(Arrays.asList(mImpl.getUnionSubTypes()));
                    SchemaType otherCommonBaseType = mImpl.getUnionCommonBaseType();
                    if (otherCommonBaseType != null)
                        commonBaseType = otherCommonBaseType.getCommonBaseType(commonBaseType);
                    break;
                case SchemaType.ATOMIC:
                    constituentMemberTypes.add(mImpl);
                    allSubTypes.add(mImpl);
                    commonBaseType = mImpl.getCommonBaseType(commonBaseType);
                    break;
                default:
                    assert(false);
            }
        }

        setUnionConstituentTypes((SchemaType[])
                constituentMemberTypes.toArray(StscState.EMPTY_ST_ARRAY));
        setUnionSubTypes((SchemaType[])
                allSubTypes.toArray(StscState.EMPTY_ST_ARRAY));
        setUnionCommonBaseType(commonBaseType);
    }

    public QName getSubstitutionGroup()
        { return _sg; }

    public void setSubstitutionGroup(QName sg)
        { assertSGResolving(); _sg = sg; }

    public void addSubstitutionGroupMember(QName member)
        { assertSGResolved(); _sgMembers.add(member); }

    public QName[] getSubstitutionGroupMembers()
    {
        QName[] result = new QName[_sgMembers.size()];
        return (QName[])_sgMembers.toArray(result);
    }

    public int getWhiteSpaceRule()
        { return _whiteSpaceRule; }

    public void setWhiteSpaceRule(int ws)
        { assertResolving(); _whiteSpaceRule = ws; }

    public XmlAnySimpleType getFacet(int facetCode)
    {
        if (_facetArray == null)
            return null;
        XmlValueRef ref = _facetArray[facetCode];
        if (ref == null)
            return null;
        return ref.get();
    }

    public boolean isFacetFixed(int facetCode)
    {
        return _fixedFacetArray[facetCode];
    }

    public XmlAnySimpleType[] getBasicFacets()
    {
        XmlAnySimpleType[] result = new XmlAnySimpleType[SchemaType.LAST_FACET + 1];
        for (int i = 0; i <= SchemaType.LAST_FACET; i++)
        {
            result[i] = getFacet(i);
        }
        return result;
    }

    public boolean[] getFixedFacets()
    {
        return boaCopy(_fixedFacetArray);
    }

    public void setBasicFacets(XmlValueRef[] values, boolean[] fixed)
    {
        assertResolving();
        _facetArray = values;
        _fixedFacetArray = fixed;
    }

    public int ordered()
        { return _ordered; }

    public void setOrdered(int ordering)
        { assertResolving(); _ordered = ordering; }

    public boolean isBounded()
        { return _isBounded; }

    public void setBounded(boolean f)
        { assertResolving(); _isBounded = f; }

    public boolean isFinite()
        { return _isFinite; }

    public void setFinite(boolean f)
        { assertResolving(); _isFinite = f; }

    public boolean isNumeric()
        { return _isNumeric; }

    public void setNumeric(boolean f)
        { assertResolving(); _isNumeric = f; }


    public boolean hasPatternFacet()
        { return _hasPatterns; }

    public void setPatternFacet(boolean hasPatterns)
        { assertResolving(); _hasPatterns = hasPatterns; }

    public synchronized boolean matchPatternFacet(String s)
    {
        if (!_hasPatterns)
            return true;

        if (_patterns != null && _patterns.length > 0)
        {
            int i;
            for (i = 0; i < _patterns.length; i++)
            {
                if (_patterns[i].matches(s))
                    break;
            }
            if (i >= _patterns.length)
                return false;
        }

        return getBaseType().matchPatternFacet(s);
    }

    public String[] getPatterns()
    {
        if (_patterns == null)
            return new String[0];
        String[] patterns = new String[_patterns.length];
        for (int i=0; i< _patterns.length; i++)
            patterns[i] = _patterns[i].getPattern();
        return patterns;
    }

    public org.apache.xmlbeans.impl.regex.RegularExpression[] getPatternExpressions()
    {
        if (_patterns == null)
            return new org.apache.xmlbeans.impl.regex.RegularExpression[0];
        org.apache.xmlbeans.impl.regex.RegularExpression[] result = new org.apache.xmlbeans.impl.regex.RegularExpression[_patterns.length];
        System.arraycopy(_patterns, 0, result, 0, _patterns.length);
        return result;
    }

    public void setPatterns(org.apache.xmlbeans.impl.regex.RegularExpression[] list)
        { assertResolving(); _patterns = list; }

    public XmlAnySimpleType[] getEnumerationValues()
    {
        if (_enumerationValues == null)
            return null;
        XmlAnySimpleType[] result = new XmlAnySimpleType[_enumerationValues.length];
        for (int i = 0; i < result.length; i++)
        {
            XmlValueRef ref = _enumerationValues[i];
            result[i] = (ref == null ? null : ref.get());

        }
        return result;
    }

    public void setEnumerationValues(XmlValueRef[] a)
        { assertResolving(); _enumerationValues = a; }

    public StringEnumAbstractBase enumForString(String s)
    {
        ensureStringEnumInfo();
        if (_lookupStringEnum == null)
            return null;
        return (StringEnumAbstractBase)_lookupStringEnum.get(s);
    }

    public StringEnumAbstractBase enumForInt(int i)
    {
        ensureStringEnumInfo();
        if (_listOfStringEnum == null || i < 0 || i >= _listOfStringEnum.size())
            return null;
        return (StringEnumAbstractBase)_listOfStringEnum.get(i);
    }

    public SchemaStringEnumEntry enumEntryForString(String s)
    {
        ensureStringEnumInfo();
        if (_lookupStringEnumEntry == null)
            return null;
        return (SchemaStringEnumEntry)_lookupStringEnumEntry.get(s);
    }

    public SchemaType getBaseEnumType()
    {
        return _baseEnumTyperef == null ? null : _baseEnumTyperef.get();
    }

    public void setBaseEnumTypeRef(SchemaType.Ref baseEnumTyperef)
    {
        _baseEnumTyperef = baseEnumTyperef;
    }

    public SchemaStringEnumEntry[] getStringEnumEntries()
    {
        if (_stringEnumEntries == null)
            return null;
        SchemaStringEnumEntry[] result = new SchemaStringEnumEntry[_stringEnumEntries.length];
        System.arraycopy(_stringEnumEntries, 0, result, 0, result.length);
        return result;
    }

    public void setStringEnumEntries(SchemaStringEnumEntry sEnums[])
    {
        assertJavaizing();
        _stringEnumEntries = sEnums;
    }

    private void ensureStringEnumInfo()
    {
        if (_stringEnumEnsured)
            return;

        SchemaStringEnumEntry[] sEnums = _stringEnumEntries;
        if (sEnums == null)
        {
            _stringEnumEnsured = true;
            return;
        }

        Map lookupStringEnum = new HashMap(sEnums.length);
        List listOfStringEnum = new ArrayList(sEnums.length + 1);
        Map lookupStringEnumEntry = new HashMap(sEnums.length);

        for (int i = 0; i < sEnums.length; i++)
        {
            lookupStringEnumEntry.put(sEnums[i].getString(), sEnums[i]);
        }

        Class jc = _baseEnumTyperef.get().getEnumJavaClass();
        if (jc != null)
        {
            try
            {
                StringEnumAbstractBase.Table table = (StringEnumAbstractBase.Table)jc.getField("table").get(null);
                for (int i = 0; i < sEnums.length; i++)
                {
                    int j = sEnums[i].getIntValue();
                    StringEnumAbstractBase enumVal = table.forInt(j);
                    lookupStringEnum.put(sEnums[i].getString(), enumVal);
                    while (listOfStringEnum.size() <= j)
                        listOfStringEnum.add(null);
                    listOfStringEnum.set(j, enumVal);
                }
            }
            catch (Exception e)
            {
                System.err.println("Something wrong: could not locate enum table for " + jc);
                jc = null;
                lookupStringEnum.clear();
                listOfStringEnum.clear();
            }
        }

        if (jc == null)
        {
            for (int i = 0; i < sEnums.length; i++)
            {
                int j = sEnums[i].getIntValue();
                String s = sEnums[i].getString();
                StringEnumAbstractBase enumVal = new StringEnumValue(s, j);
                lookupStringEnum.put(s, enumVal);
                while (listOfStringEnum.size() <= j)
                    listOfStringEnum.add(null);
                listOfStringEnum.set(j, enumVal);
            }
        }

        synchronized (this)
        {
            if (!_stringEnumEnsured)
            {
                _lookupStringEnum = lookupStringEnum;
                _listOfStringEnum = listOfStringEnum;
                _lookupStringEnumEntry = lookupStringEnumEntry;
            }
        }
        // HACKHACK: two syncrhonized blocks force a memory barrier:
        // BUGBUG: this behavior is likely to change in future VMs
        synchronized (this)
        {
            _stringEnumEnsured = true;
        }
    }

    public boolean hasStringEnumValues()
    {
        return _stringEnumEntries != null;
    }

    public void copyEnumerationValues(SchemaTypeImpl baseImpl)
    {
        assertResolving();
        _enumerationValues = baseImpl._enumerationValues;
        _baseEnumTyperef = baseImpl._baseEnumTyperef;
    }

    public int getBuiltinTypeCode()
        { return _builtinTypeCode; } // special: set up pre-init

    public void setBuiltinTypeCode(int builtinTypeCode)
        { assertResolving(); _builtinTypeCode = builtinTypeCode; }

    public Class getJavaClass()
    {
        // This field is declared volatile and Class is immutable so this is allowed.
        if (_javaClass == null && getFullJavaName() != null)
        {
            try
                { _javaClass = Class.forName(getFullJavaName(), false, _typeSystem.getClassLoader()); }
            catch (ClassNotFoundException e)
            {
                System.err.println("Could not find class name " + getFullJavaName());
                System.err.println("Searched in classloader " + _typeSystem.getClassLoader());
                e.printStackTrace(System.err);
                _javaClass = null;
            }
        }

        return _javaClass;
    }

    public Class getJavaImplClass() {
        if (_implNotAvailable)
            return null;

        if (_javaImplClass == null)
        {
            try {
                if (getFullJavaImplName() != null)
                    _javaImplClass = Class.forName(getFullJavaImplName(), false, _typeSystem.getClassLoader());
                else
                    _implNotAvailable = true;
            }
            catch (ClassNotFoundException e) {
                _implNotAvailable = true;
            }
        }

        return _javaImplClass;
    }

    public Constructor getJavaImplConstructor()
    {
        if (_javaImplConstructor == null && !_implNotAvailable)
        {
            final Class impl = getJavaImplClass();
            if (impl == null) return null;
            try
            {
                _javaImplConstructor = impl.getConstructor(new Class[] { SchemaType.class });
            }
            catch (NoSuchMethodException e)
            {
                e.printStackTrace();
            }
        }

        return _javaImplConstructor;

    }

    public Constructor getJavaImplConstructor2()
    {
        if (_javaImplConstructor2 == null && !_implNotAvailable)
        {
            final Class impl = getJavaImplClass();
            if (impl == null) return null;
            try
            {
                _javaImplConstructor2 = impl.getConstructor(new Class[] { SchemaType.class, boolean.class });
            }
            catch (NoSuchMethodException e)
            {
                e.printStackTrace();
            }
        }

        return _javaImplConstructor2;

    }

    public Class getEnumJavaClass()
    {
        // This field is declared volatile and Class is immutable so this is allowed.
        if (_javaEnumClass == null)
        {
            try
                { _javaEnumClass = Class.forName(getBaseEnumType().getFullJavaName() + "$Enum", false, _typeSystem.getClassLoader()); }
            catch (ClassNotFoundException e)
                { _javaEnumClass = null; }
        }

        return _javaEnumClass;
    }

    public void setJavaClass(Class javaClass)
    {
        assertResolved();
        _javaClass = javaClass;
        setFullJavaName(javaClass.getName());
    }

    public boolean isPrimitiveType()
    {
        return (getBuiltinTypeCode() >= BTC_FIRST_PRIMITIVE &&
                getBuiltinTypeCode() <= BTC_LAST_PRIMITIVE);
    }

    public boolean isBuiltinType()
    {
        return getBuiltinTypeCode() != 0;
    }

    public XmlObject createUnwrappedNode()
    {
        // Todo: attach a new xml store!
        XmlObject result = createUnattachedNode(null);
        return result;
    }

    /**
     * TypeStoreUserFactory implementation
     */
    public TypeStoreUser createTypeStoreUser()
    {
        return (TypeStoreUser)createUnattachedNode(null);
    }


    public XmlAnySimpleType newValidatingValue(Object obj)
    {
        return newValue(obj, true);
    }
    /**
     * Creates an immutable simple value.
     */
    public XmlAnySimpleType newValue(Object obj)
    {
        return newValue(obj, false);
    }

    public XmlAnySimpleType newValue(Object obj, boolean validateOnSet)
    {
        if (!isSimpleType() && getContentType() != SchemaType.SIMPLE_CONTENT)
            throw new XmlValueOutOfRangeException(); // values must be simple

        XmlObjectBase result = (XmlObjectBase)createUnattachedNode(null);
        if (validateOnSet)
            result.setValidateOnSet();

        // In the case of tree copy, need to call a specla setter to avoid
        // set(XmlObject)
        if (obj instanceof XmlObject)
            result.set_newValue((XmlObject)obj);
        else
            result.objectSet(obj);

        result.check_dated();
        result.setImmutable();

        return (XmlAnySimpleType) result;
    }

    /**
     * Creates an instance of this type.
     */
    private XmlObject createUnattachedNode(SchemaProperty prop)
    {
        XmlObject result = null;

        if (!isBuiltinType() && !isNoType())
        {
            // System.out.println("Attempting to load impl class: " + getFullJavaImplName());
            Constructor ctr = getJavaImplConstructor();
            if (ctr != null)
            {
                try
                {
                    // System.out.println("Succeeded!");
                    return (XmlObject)ctr.newInstance(_ctrArgs);
                }
                catch (Exception e)
                {
                    System.out.println("Exception trying to instantiate impl class.");
                    e.printStackTrace();
                }
            }
        }
        else
        {
            result = createBuiltinInstance();
        }

        // if no result, we must be a restriction of some compiled type
        for (SchemaType sType = this; result == null; sType = sType.getBaseType())
            result = ((SchemaTypeImpl)sType).createUnattachedSubclass(this);

        ((XmlObjectBase)result).init_flags(prop);
        return result;
    }

    private XmlObject createUnattachedSubclass(SchemaType sType)
    {
        if (!isBuiltinType() && !isNoType())
        {
            // System.out.println("Attempting to load impl class: " + getFullJavaImplName());
            Constructor ctr = getJavaImplConstructor2();
            if (ctr != null)
            {
                try
                {
                    // System.out.println("Succeeded!");
                    return (XmlObject)ctr.newInstance(new Object[] { sType, sType.isSimpleType() ? Boolean.FALSE : Boolean.TRUE });
                }
                catch (Exception e)
                {
                    System.out.println("Exception trying to instantiate impl class.");
                    e.printStackTrace();
                }
            }
            return null;
        }
        else
        {
            return createBuiltinSubclass(sType);
        }
    }

    private XmlObject createBuiltinInstance()
    {
        switch (getBuiltinTypeCode())
        {
            case BTC_NOT_BUILTIN:
                return new XmlAnyTypeImpl(BuiltinSchemaTypeSystem.ST_NO_TYPE);
            case BTC_ANY_TYPE:
                return new XmlAnyTypeImpl();
            case BTC_ANY_SIMPLE:
                return new XmlAnySimpleTypeImpl();
            case BTC_BOOLEAN:
                return new XmlBooleanImpl();
            case BTC_BASE_64_BINARY:
                return new XmlBase64BinaryImpl();
            case BTC_HEX_BINARY:
                return new XmlHexBinaryImpl();
            case BTC_ANY_URI:
                return new XmlAnyUriImpl();
            case BTC_QNAME:
                return new XmlQNameImpl();
            case BTC_NOTATION:
                return new XmlNotationImpl();
            case BTC_FLOAT:
                return new XmlFloatImpl();
            case BTC_DOUBLE:
                return new XmlDoubleImpl();
            case BTC_DECIMAL:
                return new XmlDecimalImpl();
            case BTC_STRING:
                return new XmlStringImpl();
            case BTC_DURATION:
                return new XmlDurationImpl();
            case BTC_DATE_TIME:
                return new XmlDateTimeImpl();
            case BTC_TIME:
                return new XmlTimeImpl();
            case BTC_DATE:
                return new XmlDateImpl();
            case BTC_G_YEAR_MONTH:
                return new XmlGYearMonthImpl();
            case BTC_G_YEAR:
                return new XmlGYearImpl();
            case BTC_G_MONTH_DAY:
                return new XmlGMonthDayImpl();
            case BTC_G_DAY:
                return new XmlGDayImpl();
            case BTC_G_MONTH:
                return new XmlGMonthImpl();
            case BTC_INTEGER:
                return new XmlIntegerImpl();
            case BTC_LONG:
                return new XmlLongImpl();
            case BTC_INT:
                return new XmlIntImpl();
            case BTC_SHORT:
                return new XmlShortImpl();
            case BTC_BYTE:
                return new XmlByteImpl();
            case BTC_NON_POSITIVE_INTEGER:
                return new XmlNonPositiveIntegerImpl();
            case BTC_NEGATIVE_INTEGER:
                return new XmlNegativeIntegerImpl();
            case BTC_NON_NEGATIVE_INTEGER:
                return new XmlNonNegativeIntegerImpl();
            case BTC_POSITIVE_INTEGER:
                return new XmlPositiveIntegerImpl();
            case BTC_UNSIGNED_LONG:
                return new XmlUnsignedLongImpl();
            case BTC_UNSIGNED_INT:
                return new XmlUnsignedIntImpl();
            case BTC_UNSIGNED_SHORT:
                return new XmlUnsignedShortImpl();
            case BTC_UNSIGNED_BYTE:
                return new XmlUnsignedByteImpl();
            case BTC_NORMALIZED_STRING:
                return new XmlNormalizedStringImpl();
            case BTC_TOKEN:
                return new XmlTokenImpl();
            case BTC_NAME:
                return new XmlNameImpl();
            case BTC_NCNAME:
                return new XmlNCNameImpl();
            case BTC_LANGUAGE:
                return new XmlLanguageImpl();
            case BTC_ID:
                return new XmlIdImpl();
            case BTC_IDREF:
                return new XmlIdRefImpl();
            case BTC_IDREFS:
                return new XmlIdRefsImpl();
            case BTC_ENTITY:
                return new XmlEntityImpl();
            case BTC_ENTITIES:
                return new XmlEntitiesImpl();
            case BTC_NMTOKEN:
                return new XmlNmTokenImpl();
            case BTC_NMTOKENS:
                return new XmlNmTokensImpl();
            default:
                throw new IllegalStateException("Unrecognized builtin type: " + getBuiltinTypeCode());
        }
    }

    private XmlObject createBuiltinSubclass(SchemaType sType)
    {
        boolean complex = !sType.isSimpleType();
        switch (getBuiltinTypeCode())
        {
            case BTC_NOT_BUILTIN:
                return new XmlAnyTypeImpl(BuiltinSchemaTypeSystem.ST_NO_TYPE);
            case BTC_ANY_TYPE:
            case BTC_ANY_SIMPLE:
                switch (sType.getSimpleVariety())
                {
                    case NOT_SIMPLE:
                        return new XmlComplexContentImpl(sType);
                    case ATOMIC:
                        return new XmlAnySimpleTypeRestriction(sType, complex);
                    case LIST:
                        return new XmlListImpl(sType, complex);
                    case UNION:
                        return new XmlUnionImpl(sType, complex);
                    default:
                        throw new IllegalStateException();
                }
            case BTC_BOOLEAN:
                return new XmlBooleanRestriction(sType, complex);
            case BTC_BASE_64_BINARY:
                return new XmlBase64BinaryRestriction(sType, complex);
            case BTC_HEX_BINARY:
                return new XmlHexBinaryRestriction(sType, complex);
            case BTC_ANY_URI:
                return new XmlAnyUriRestriction(sType, complex);
            case BTC_QNAME:
                return new XmlQNameRestriction(sType, complex);
            case BTC_NOTATION:
                return new XmlNotationRestriction(sType, complex);
            case BTC_FLOAT:
                return new XmlFloatRestriction(sType, complex);
            case BTC_DOUBLE:
                return new XmlDoubleRestriction(sType, complex);
            case BTC_DECIMAL:
                return new XmlDecimalRestriction(sType, complex);
            case BTC_STRING:
                if (sType.hasStringEnumValues())
                    return new XmlStringEnumeration(sType, complex);
                else
                    return new XmlStringRestriction(sType, complex);
            case BTC_DURATION:
                return new XmlDurationImpl(sType, complex);
            case BTC_DATE_TIME:
                return new XmlDateTimeImpl(sType, complex);
            case BTC_TIME:
                return new XmlTimeImpl(sType, complex);
            case BTC_DATE:
                return new XmlDateImpl(sType, complex);
            case BTC_G_YEAR_MONTH:
                return new XmlGYearMonthImpl(sType, complex);
            case BTC_G_YEAR:
                return new XmlGYearImpl(sType, complex);
            case BTC_G_MONTH_DAY:
                return new XmlGMonthDayImpl(sType, complex);
            case BTC_G_DAY:
                return new XmlGDayImpl(sType, complex);
            case BTC_G_MONTH:
                return new XmlGMonthImpl(sType, complex);
            case BTC_INTEGER:
                return new XmlIntegerRestriction(sType, complex);
            case BTC_LONG:
                return new XmlLongRestriction(sType, complex);
            case BTC_INT:
                return new XmlIntRestriction(sType, complex);
            case BTC_SHORT:
                return new XmlShortImpl(sType, complex);
            case BTC_BYTE:
                return new XmlByteImpl(sType, complex);
            case BTC_NON_POSITIVE_INTEGER:
                return new XmlNonPositiveIntegerImpl(sType, complex);
            case BTC_NEGATIVE_INTEGER:
                return new XmlNegativeIntegerImpl(sType, complex);
            case BTC_NON_NEGATIVE_INTEGER:
                return new XmlNonNegativeIntegerImpl(sType, complex);
            case BTC_POSITIVE_INTEGER:
                return new XmlPositiveIntegerImpl(sType, complex);
            case BTC_UNSIGNED_LONG:
                return new XmlUnsignedLongImpl(sType, complex);
            case BTC_UNSIGNED_INT:
                return new XmlUnsignedIntImpl(sType, complex);
            case BTC_UNSIGNED_SHORT:
                return new XmlUnsignedShortImpl(sType, complex);
            case BTC_UNSIGNED_BYTE:
                return new XmlUnsignedByteImpl(sType, complex);
            case BTC_NORMALIZED_STRING:
                return new XmlNormalizedStringImpl(sType, complex);
            case BTC_TOKEN:
                return new XmlTokenImpl(sType, complex);
            case BTC_NAME:
                return new XmlNameImpl(sType, complex);
            case BTC_NCNAME:
                return new XmlNCNameImpl(sType, complex);
            case BTC_LANGUAGE:
                return new XmlLanguageImpl(sType, complex);
            case BTC_ID:
                return new XmlIdImpl(sType, complex);
            case BTC_IDREF:
                return new XmlIdRefImpl(sType, complex);
            case BTC_IDREFS:
                return new XmlIdRefsImpl(sType, complex);
            case BTC_ENTITY:
                return new XmlEntityImpl(sType, complex);
            case BTC_ENTITIES:
                return new XmlEntitiesImpl(sType, complex);
            case BTC_NMTOKEN:
                return new XmlNmTokenImpl(sType, complex);
            case BTC_NMTOKENS:
                return new XmlNmTokensImpl(sType, complex);
            default:
                throw new IllegalStateException("Unrecognized builtin type: " + getBuiltinTypeCode());
        }
    }

    public SchemaType getCommonBaseType(SchemaType type)
    {
        // null type is treated as the no-type
        if (this == BuiltinSchemaTypeSystem.ST_ANY_TYPE || type == null || type.isNoType())
            return this;

        // any type is the universal base type; noType is the universal derived type
        if (type == BuiltinSchemaTypeSystem.ST_ANY_TYPE || isNoType())
            return type;

        // the regular case:
        SchemaTypeImpl sImpl1 = (SchemaTypeImpl)type;
        while (sImpl1.getBaseDepth() > getBaseDepth())
            sImpl1 = (SchemaTypeImpl)sImpl1.getBaseType();
        SchemaTypeImpl sImpl2 = this;
        while (sImpl2.getBaseDepth() > sImpl1.getBaseDepth())
            sImpl2 = (SchemaTypeImpl)sImpl2.getBaseType();
        for (;;)
        {
            if (sImpl1.equals(sImpl2))
                break;
            sImpl1 = (SchemaTypeImpl)sImpl1.getBaseType();
            sImpl2 = (SchemaTypeImpl)sImpl2.getBaseType();
            assert(sImpl1 != null && sImpl2 != null); // must meet at anyType
        }
        return sImpl1;
    }

    public boolean isAssignableFrom(SchemaType type)
    {
        if (type == null || type.isNoType())
            return true;

        if (isNoType())
            return false;

        int depth = ((SchemaTypeImpl)type).getBaseDepth() - getBaseDepth();
        if (depth < 0)
            return false;
        while (depth > 0)
        {
            type = type.getBaseType();
            depth -= 1;
        }
        return (type.equals(this));
    }


    public String toString()
    {
        if (getName() != null)
            return "T=" + QNameHelper.pretty(getName());

        if (isDocumentType())
            return "D=" + QNameHelper.pretty(getDocumentElementName());

        if (isAttributeType())
            return "R=" + QNameHelper.pretty(getAttributeTypeAttributeName());

        String prefix;

        if (getContainerField() != null)
        {
            prefix = (getContainerField().getName().getNamespaceURI().length() > 0 ?
                            (getContainerField().isAttribute() ? "Q=" : "E=") :
                            (getContainerField().isAttribute() ? "A=" : "U="))
                    + getContainerField().getName().getLocalPart();
            if (getOuterType() == null)
                return prefix + "@" + getContainerField().getName().getNamespaceURI();
        }
        else if (isNoType())
            return "N=";
        else if (getOuterType() == null)
            return "noouter";
        else if (getOuterType().getBaseType() == this)
            prefix = "B=";
        else if (getOuterType().getSimpleVariety() == SchemaType.LIST)
            prefix = "I=";
        else if (getOuterType().getSimpleVariety() == SchemaType.UNION)
            prefix = "M=" + getAnonymousUnionMemberOrdinal();
        else
            prefix = "strange=";

        return prefix + "|" + getOuterType().toString();
    }

    private XmlObject _parseObject;
    private String _parseTNS;
    private boolean _chameleon;
    private boolean _redefinition;

    public void setParseContext(XmlObject parseObject, String targetNamespace, boolean chameleon, boolean redefinition)
    {
        _parseObject = parseObject;
        _parseTNS = targetNamespace;
        _chameleon = chameleon;
        _redefinition = redefinition;
    }

    public XmlObject getParseObject()
        { return _parseObject; }

    public String getTargetNamespace()
        { return _parseTNS; }

    public boolean isChameleon ( )
        { return _chameleon; }

    public String getChameleonNamespace()
        { return _chameleon ? _parseTNS : null; }

    public boolean isRedefinition()
        { return _redefinition; }

    private SchemaType.Ref _selfref = new SchemaType.Ref(this);

    public SchemaType.Ref getRef()
        { return _selfref; }

    public SchemaComponent.Ref getComponentRef()
        { return getRef(); }

}
