/*
* 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);

            // NOTE: a previous version of XMLBeans used ST_NO_TYPE if the
            // xsiType was not derived from 'type', but this results in a
            // ClassCastException.  Instead we ignore xsi:type if it's not
            // found or a derived type.
            if (itype != null && type.isAssignableFrom(itype)) {
                return itype;
            }
        }

        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);

                // NOTE: a previous version of XMLBeans used ST_NO_TYPE if the
                // xsiType was not derived from 'type', but this results in a
                // ClassCastException.  Instead we ignore xsi:type if it's not
                // found or a derived type.
                if (itype != null && type.isAssignableFrom(itype)) {
                    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 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(); }

}
