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

package org.apache.xmlbeans.impl.schema;

import org.apache.xmlbeans.*;
import org.apache.xmlbeans.impl.common.QNameHelper;
import org.apache.xmlbeans.impl.common.XBeanDebug;
import org.apache.xmlbeans.impl.values.*;

import javax.xml.namespace.QName;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.math.BigInteger;
import java.util.*;

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

    // annotation on the type
    private SchemaAnnotation _annotation;

    // 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 volatile QName[] _groupReferenceContext;
    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;
    private InterfaceExtension[] _interfaces;
    private PrePostExtension _prepost;

    // runtime java type support: volatile because they're cached
    private volatile Class<? extends XmlObject> _javaClass;
    private volatile Class<? extends StringEnumAbstractBase> _javaEnumClass;
    private volatile Class<? extends XmlObjectBase> _javaImplClass;
    private volatile Constructor<? extends XmlObjectBase> _javaImplConstructor;
    private volatile Constructor<? extends XmlObjectBase> _javaImplConstructor2;
    private volatile boolean _implNotAvailable;

    // user data objects not persisted
    private volatile Object _userData;

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

    // reflective support
    private SchemaContainer _container;
    private String _filename;

    // complex content support
    private SchemaParticle _contentModel;
    private volatile SchemaLocalElement[] _localElts; // lazily computed
    private volatile Map<SchemaLocalElement, Integer> _eltToIndexMap; // lazily computed
    private volatile Map<SchemaLocalAttribute, Integer> _attrToIndexMap; // lazily computed
    private Map<QName, SchemaProperty> _propertyModelByElementName;
    private Map<QName, SchemaProperty> _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<QName> _validSubstitutions = Collections.emptySet();

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

    // user type support
    private String _userTypeName;
    private String _userTypeHandler;

    // for complex types with simple content
    private SchemaType.Ref _contentBasedOnTyperef;

    // 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<String, StringEnumAbstractBase> _lookupStringEnum;
    private volatile List<StringEnumAbstractBase> _listOfStringEnum;
    private volatile Map<String, SchemaStringEnumEntry> _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 final List<QName> _sgMembers = new ArrayList<>();

    public boolean isUnloaded() {
        return _unloaded;
    }

    public void finishLoading() {
        _unloaded = false;
    }


    SchemaTypeImpl(SchemaContainer container) {
        _container = container;
    }

    SchemaTypeImpl(SchemaContainer container, boolean unloaded) {
        _container = container;
        _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 setAnnotation(SchemaAnnotation ann) {
        assertUnresolved();
        _annotation = ann;
    }

    public SchemaAnnotation getAnnotation() {
        return _annotation;
    }

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

    public SchemaTypeElementSequencer getElementSequencer() {
        if (_complexTypeVariety == NOT_COMPLEX_TYPE) {
            return new SequencerImpl(null);
        }

        return new SequencerImpl(new SchemaTypeVisitorImpl(_contentModel));
    }

    /**
     * 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) {
                assert (outer != null);
                _containerField = outer.getAttributeModel().getAttributes()[_containerFieldIndex];
            } else {
                assert (outer != null);
                _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;
    }

    /* package */ void setGroupReferenceContext(QName[] groupNames) {
        assertUnresolved();
        _groupReferenceContext = groupNames;
    }

    /* package */ QName[] getGroupReferenceContext() {
        return _groupReferenceContext;
    }

    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() {
        SchemaType outerType = getOuterType();
        return (outerType != null && (outerType.getBaseType() == this ||
                                      outerType.getContentBasedOnType() == 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 String getUserTypeName() {
        return _userTypeName;
    }

    public void setUserTypeName(String userTypeName) {
        _userTypeName = userTypeName;
    }

    public String getUserTypeHandlerName() {
        return _userTypeHandler;
    }

    public void setUserTypeHandlerName(String typeHandler) {
        _userTypeHandler = typeHandler;
    }

    public void setInterfaceExtensions(InterfaceExtension[] interfaces) {
        assertResolved();
        _interfaces = (interfaces == null) ? null : interfaces.clone();
    }

    public InterfaceExtension[] getInterfaceExtensions() {
        return _interfaces;
    }

    public void setPrePostExtension(PrePostExtension prepost) {
        assertResolved();
        _prepost = prepost;
    }

    public PrePostExtension getPrePostExtension() {
        return _prepost;
    }

    public Object getUserData() {
        return _userData;
    }

    public void setUserData(Object data) {
        _userData = data;
    }

    /* Only used for asserts */
    SchemaContainer getContainer() {
        return _container;
    }

    void setContainer(SchemaContainer container) {
        _container = container;
    }

    public SchemaTypeSystem getTypeSystem() {
        return _container.getTypeSystem();
    }

    public SchemaParticle getContentModel() {
        return _contentModel;
    }

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

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

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

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

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

    public int getIndexForLocalAttribute(SchemaLocalAttribute attr) {
        Map<SchemaLocalAttribute, Integer> 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], i);
            }
            _attrToIndexMap = localAttrMap;
        }
        return localAttrMap.get(attr);
    }

    public SchemaAttributeModel getAttributeModel() {
        return _attributeModel;
    }

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

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

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

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

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

        List<SchemaProperty> results = new ArrayList<>();

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

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

        for (Iterator<SchemaProperty> it = results.iterator(); it.hasNext(); ) {
            SchemaProperty prop = 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, default)

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

            }

        }

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

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

    private static boolean eq(String a, String 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 _propertyModelByElementName.values().toArray(new SchemaProperty[0]);
    }

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

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

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

    public SchemaProperty getAttributeProperty(QName attrName) {
        return _propertyModelByAttributeName == null ? null : _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<QName, SchemaProperty> propertyModelByElementName,
        Map<QName, SchemaProperty> 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<SchemaProperty> eltProps = _propertyModelByElementName.values();
            for (SchemaProperty prop : eltProps) {
                QName[] names = prop.acceptedNames();
                for (QName name : names) {
                    if (!_propertyModelByElementName.containsKey(name)) {
                        _validSubstitutions.add(name);
                    }
                }
            }
        }
    }

    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 = _propertyModelByElementName.get(eltName);
        if (prop != null) {
            type = prop.getType();
        } else {
            if (wildcardTypeLoader == null) {
                return BuiltinSchemaTypeSystem.ST_NO_TYPE;
            }

            if (_typedWildcardElements.contains(eltName) ||
                _validSubstitutions.contains(eltName)) {
                SchemaGlobalElement elt = wildcardTypeLoader.findElement(eltName);
                if (elt == null) {
                    return BuiltinSchemaTypeSystem.ST_NO_TYPE;
                }
                // According to http://www.w3.org/TR/xmlschema-1/#key-lva,
                // the line above should return ST_ANY_TYPE.
                type = elt.getType();
            } else {
                // Substitution groups
                // Actually, better not enable this yet
                /*SchemaGlobalElement elt = wildcardTypeLoader.findElement(eltName);
                SchemaGlobalElement sghead = elt == null ? null : elt.substitutionGroup();
                while (sghead != null)
                {
                    prop = (SchemaProperty)_propertyModelByElementName.get(sghead.getName());
                    if (prop != null)
                    {
                        type = elt.getType();
                        break;
                    }
                    sghead = sghead.substitutionGroup();
                }
                */
                return BuiltinSchemaTypeSystem.ST_NO_TYPE;
            }
        }

        if (xsiType != null && wildcardTypeLoader != 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 = _propertyModelByAttributeName.get(attrName);
        if (prop != null) {
            return prop.getType();
        }

        if (!_typedWildcardAttributes.contains(attrName) || wildcardTypeLoader == null) {
            return BuiltinSchemaTypeSystem.ST_NO_TYPE;
        }
        // For symmetry with the element case (as well as with URType), perhaps
        // the above line should be returning ST_ANY_SIMPLE

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

    /* These two methods, createElementType and getElementType have to stay
     * synchronized, because they create an XmlObject and return the type
     * for that object, respectively. But since they do slightly different
     * things, they can't be refactored to share code, so exercise caution
     */
    public XmlObject createElementType(QName eltName, QName xsiType, SchemaTypeLoader wildcardTypeLoader) {
        SchemaType type;
        SchemaProperty prop = null;
        if (isSimpleType() || !containsElements() || isNoType()) {
            type = BuiltinSchemaTypeSystem.ST_NO_TYPE;
        } else {
            prop = _propertyModelByElementName.get(eltName);
            if (prop != null) {
                type = prop.getType();
            } else if (_typedWildcardElements.contains(eltName) ||
                       _validSubstitutions.contains(eltName)) {
                SchemaGlobalElement elt = wildcardTypeLoader.findElement(eltName);
                if (elt != null) {
                    type = elt.getType();
                    SchemaType docType = wildcardTypeLoader.findDocumentType(eltName);
                    if (docType != null) {
                        prop = docType.getElementProperty(eltName);
                    }
                } else {
                    type = BuiltinSchemaTypeSystem.ST_NO_TYPE;
                }
            } else {
                // Check if the requested element isn't by any chance part of a
                // substitution group headed by one of the declared elements
                // Better not enable this yet
                /*
                SchemaGlobalElement elt = wildcardTypeLoader.findElement(eltName);
                SchemaGlobalElement sghead = elt == null ? null : elt.substitutionGroup();
                while (sghead != null)
                {
                    if (_propertyModelByElementName.containsKey(sghead.getName()))
                    {
                        type = elt.getType();
                        SchemaType docType = wildcardTypeLoader.findDocumentType(elt.getName());
                        if (docType != null)
                            prop = docType.getElementProperty(elt.getName());
                        break;
                    }
                    sghead = sghead.substitutionGroup();
                }
                */
                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;
        SchemaProperty prop = null;
        if (isSimpleType() || isNoType()) {
            type = BuiltinSchemaTypeSystem.ST_NO_TYPE;
        } else if (isURType()) {
            type = BuiltinSchemaTypeSystem.ST_ANY_SIMPLE;
        } else {
            prop = _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 == null ? null : anonymousTyperefs.clone();
    }


    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 SchemaType getContentBasedOnType() {
        return _contentBasedOnTyperef == null ? null : _contentBasedOnTyperef.get();
    }

    public void setContentBasedOnTypeRef(SchemaType.Ref typeref) {
        assertResolving();
        _contentBasedOnTyperef = typeref;
    }

    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 == null ? 0 : _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 == null ? null : typerefs.clone();
    }

    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() {
        if (getSimpleVariety() != SchemaType.UNION) {
            throw new IllegalStateException("Operation is only supported on union types");
        }
        Set<SchemaType> constituentMemberTypes = new LinkedHashSet<>();
        Set<SchemaType> allSubTypes = new LinkedHashSet<>();
        SchemaType commonBaseType = null;

        allSubTypes.add(this);

        for (Ref unionMemberTyperef : _unionMemberTyperefs) {
            SchemaTypeImpl mImpl = (SchemaTypeImpl) unionMemberTyperef.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(constituentMemberTypes.toArray(StscState.EMPTY_ST_ARRAY));
        setUnionSubTypes(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() {
        return _sgMembers.toArray(new QName[0]);
    }

    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 == null ? null : values.clone();
        _fixedFacetArray = fixed == null ? null : fixed.clone();
    }

    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 == null ? null : list.clone();
    }

    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 == null ? null : a.clone();
    }

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

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

    public SchemaStringEnumEntry enumEntryForString(String s) {
        ensureStringEnumInfo();
        if (_lookupStringEnumEntry == null) {
            return null;
        }
        return _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 == null ? null : sEnums.clone();
    }

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

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

        Map<String, StringEnumAbstractBase> lookupStringEnum = new HashMap<>(sEnums.length);
        List<StringEnumAbstractBase> listOfStringEnum = new ArrayList<>(sEnums.length + 1);
        Map<String, SchemaStringEnumEntry> lookupStringEnumEntry = new HashMap<>(sEnums.length);

        for (SchemaStringEnumEntry sEnum : sEnums) {
            lookupStringEnumEntry.put(sEnum.getString(), sEnum);
        }

        Class<? extends StringEnumAbstractBase> jc = _baseEnumTyperef.get().getEnumJavaClass();
        if (jc != null) {
            try {
                StringEnumAbstractBase.Table table = (StringEnumAbstractBase.Table) jc.getField("table").get(null);
                for (SchemaStringEnumEntry sEnum : sEnums) {
                    int j = sEnum.getIntValue();
                    StringEnumAbstractBase enumVal = table.forInt(j);
                    lookupStringEnum.put(sEnum.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 (SchemaStringEnumEntry sEnum : sEnums) {
                int j = sEnum.getIntValue();
                String s = sEnum.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;
    }

    synchronized void assignJavaElementSetterModel() {
        // To compute the element setter model, we need to compute the
        // delimiting elements for each element.

        SchemaProperty[] eltProps = getElementProperties();
        SchemaParticle contentModel = getContentModel();
        Map<SchemaParticle, QNameSet> state = new HashMap<>();
        QNameSet allContents = computeAllContainedElements(contentModel, state);

        for (SchemaProperty eltProp : eltProps) {
            SchemaPropertyImpl sImpl = (SchemaPropertyImpl) eltProp;
            QNameSet nde = computeNondelimitingElements(sImpl.getName(), contentModel, state);
            QNameSetBuilder builder = new QNameSetBuilder(allContents);
            builder.removeAll(nde);
            sImpl.setJavaSetterDelimiter(builder.toQNameSet());
        }
    }

    /**
     * Used to compute setter model.
     * <p>
     * Returns the QNameSet of all elements that can possibly come before an
     * element whose name is given by the target in a valid instance of the
     * contentModel.  When appending an element, it comes before the first
     * one that is not in this set.
     */
    private static QNameSet computeNondelimitingElements(QName target, SchemaParticle contentModel, Map<SchemaParticle, QNameSet> state) {
        QNameSet allContents = computeAllContainedElements(contentModel, state);
        if (!allContents.contains(target)) {
            return QNameSet.EMPTY;
        }

        // If iterated, then all contents are delimiting.
        if (contentModel.getMaxOccurs() == null ||
            contentModel.getMaxOccurs().compareTo(BigInteger.ONE) > 0) {
            return allContents;
        }

        QNameSetBuilder builder;

        switch (contentModel.getParticleType()) {
            case SchemaParticle.ALL:
            case SchemaParticle.ELEMENT:
            default:
                return allContents;

            case SchemaParticle.WILDCARD:
                return QNameSet.singleton(target);

            case SchemaParticle.CHOICE:
                builder = new QNameSetBuilder();
                for (int i = 0; i < contentModel.countOfParticleChild(); i++) {
                    QNameSet childContents = computeAllContainedElements(contentModel.getParticleChild(i), state);
                    if (childContents.contains(target)) {
                        builder.addAll(computeNondelimitingElements(target, contentModel.getParticleChild(i), state));
                    }
                }
                return builder.toQNameSet();

            case SchemaParticle.SEQUENCE:
                builder = new QNameSetBuilder();
                boolean seenTarget = false;
                for (int i = contentModel.countOfParticleChild(); i > 0; ) {
                    i--;
                    QNameSet childContents = computeAllContainedElements(contentModel.getParticleChild(i), state);
                    if (seenTarget) {
                        builder.addAll(childContents);
                    } else if (childContents.contains(target)) {
                        builder.addAll(computeNondelimitingElements(target, contentModel.getParticleChild(i), state));
                        seenTarget = true;
                    }
                }
                return builder.toQNameSet();
        }
    }

    /**
     * Used to compute the setter model.
     * <p>
     * Returns the set of all QNames of elements that could possibly be
     * contained in the given contentModel. The state variable is used
     * to record the results, so that if they are needed again later,
     * they do not need to be recomputed.
     */
    private static QNameSet computeAllContainedElements(SchemaParticle contentModel, Map<SchemaParticle, QNameSet> state) {
        // Remember previously computed results to avoid complexity explosion
        QNameSet result = state.get(contentModel);
        if (result != null) {
            return result;
        }

        QNameSetBuilder builder;

        switch (contentModel.getParticleType()) {
            case SchemaParticle.ALL:
            case SchemaParticle.CHOICE:
            case SchemaParticle.SEQUENCE:
            default:
                builder = new QNameSetBuilder();
                for (int i = 0; i < contentModel.countOfParticleChild(); i++) {
                    builder.addAll(computeAllContainedElements(contentModel.getParticleChild(i), state));
                }
                result = builder.toQNameSet();
                break;

            case SchemaParticle.WILDCARD:
                result = contentModel.getWildcardSet();
                break;

            case SchemaParticle.ELEMENT:
                // Fix for XMLBEANS-228
                result = contentModel.acceptedStartNames();
                break;
        }
        state.put(contentModel, result);
        return result;
    }

    @SuppressWarnings("unchecked")
    public Class<? extends XmlObject> getJavaClass() {
        // This field is declared volatile and Class is immutable so this is allowed.
        if (_javaClass == null && getFullJavaName() != null) {
            try {
                _javaClass = (Class<? extends XmlObject>) Class.forName(getFullJavaName(), false, getTypeSystem().getClassLoader());
            } catch (ClassNotFoundException e) {
                // This is a legitimate use, when users get a SchemaTypeSystem without compiling classes
                _javaClass = null;
            }
        }

        return _javaClass;
    }

    @SuppressWarnings("unchecked")
    public Class<? extends XmlObjectBase> getJavaImplClass() {
        if (_implNotAvailable) {
            return null;
        }

        if (_javaImplClass == null) {
            try {
                if (getFullJavaImplName() != null) {
                    _javaImplClass = (Class<? extends XmlObjectBase>) Class.forName(getFullJavaImplName(), false, getTypeSystem().getClassLoader());
                } else {
                    _implNotAvailable = true;
                }
            } catch (ClassNotFoundException e) {
                _implNotAvailable = true;
            }
        }

        return _javaImplClass;
    }

    public Constructor<? extends XmlObjectBase> getJavaImplConstructor() {
        if (_javaImplConstructor == null && !_implNotAvailable) {
            final Class<? extends XmlObjectBase> impl = getJavaImplClass();
            if (impl == null) {
                return null;
            }
            try {
                _javaImplConstructor = impl.getConstructor(SchemaType.class);
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            }
        }

        return _javaImplConstructor;

    }

    public Constructor<? extends XmlObjectBase> getJavaImplConstructor2() {
        if (_javaImplConstructor2 == null && !_implNotAvailable) {
            final Class<? extends XmlObjectBase> impl = getJavaImplClass();
            if (impl == null) {
                return null;
            }
            try {
                _javaImplConstructor2 = impl.getDeclaredConstructor(SchemaType.class, boolean.class);
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            }
        }

        return _javaImplConstructor2;

    }

    @SuppressWarnings("unchecked")
    @Override
    public Class<? extends StringEnumAbstractBase> getEnumJavaClass() {
        // This field is declared volatile and Class is immutable so this is allowed.
        if (_javaEnumClass == null) {
            if (getBaseEnumType() != null) {
                try {
                    _javaEnumClass = (Class<? extends StringEnumAbstractBase>) Class.forName(getBaseEnumType().getFullJavaName() + "$Enum", false, getTypeSystem().getClassLoader());
                } catch (ClassNotFoundException e) {
                    _javaEnumClass = null;
                }
            }
        }

        return _javaEnumClass;
    }

    public void setJavaClass(Class<? extends XmlObject> 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!
        return createUnattachedNode(null);
    }

    /**
     * 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.setObjectValue(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<? extends XmlObjectBase> ctr = getJavaImplConstructor();
            if (ctr != null) {
                try {
                    return 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()) {
            Constructor<? extends XmlObjectBase> ctr = getJavaImplConstructor2();
            try {
                return (ctr == null) ? null : ctr.newInstance(sType, !sType.isSimpleType());
            } catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
                XBeanDebug.LOG.atDebug().withThrowable(e).log(e.getMessage());
                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();
        }
        while (!sImpl1.equals(sImpl2)) {
            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;
        }

        if (getSimpleVariety() == UNION) {
            SchemaType[] members = getUnionMemberTypes();
            for (SchemaType member : members) {
                if (member.isAssignableFrom(type)) {
                    return true;
                }
            }
        }

        int depth = ((SchemaTypeImpl) type).getBaseDepth() - getBaseDepth();
        if (depth < 0) {
            return false;
        }
        while (depth > 0) {
            type = type.getBaseType();
            depth -= 1;
        }
        return (type != null && 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().getContentBasedOnType() == this) {
            prefix = "S=";
        } 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 String _elemFormDefault;
    private String _attFormDefault;
    private boolean _chameleon;
    private boolean _redefinition;

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

    public XmlObject getParseObject() {
        return _parseObject;
    }

    public String getTargetNamespace() {
        return _parseTNS;
    }

    public boolean isChameleon() {
        return _chameleon;
    }

    public String getElemFormDefault() {
        return _elemFormDefault;
    }

    public String getAttFormDefault() {
        return _attFormDefault;
    }

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

    public boolean isRedefinition() {
        return _redefinition;
    }

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

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

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

    /**
     * Gives access to the internals of element validation
     */
    private static class SequencerImpl implements SchemaTypeElementSequencer {
        private final SchemaTypeVisitorImpl _visitor;

        private SequencerImpl(SchemaTypeVisitorImpl visitor) {
            _visitor = visitor;
        }

        public boolean next(QName elementName) {
            if (_visitor == null) {
                return false;
            }

            return _visitor.visit(elementName);
        }

        public boolean peek(QName elementName) {
            if (_visitor == null) {
                return false;
            }

            return _visitor.testValid(elementName);
        }
    }

    /**
     * Returns a QNameSet of elements that may exist in wildcard
     * buchets and are not explicitly defined in this schema type.
     * Note: In this example:
     * <xs:complexType name="exampleType">
     * <xs:sequence>
     * <xs:element name="someElement" type='xs:string' />
     * <xs:any namespace="##targetNamespace" />
     * </xs:sequence>
     * </xs:complexType>
     * the returned QNameSet will not contain the qname of 'someElement'.
     *
     * @return the constructed QNameSet
     */
    public QNameSet qnameSetForWildcardElements() {
        SchemaParticle model = this.getContentModel();
        QNameSetBuilder wildcardSet = new QNameSetBuilder();
        computeWildcardSet(model, wildcardSet);

        QNameSetBuilder qnsb = new QNameSetBuilder(wildcardSet);
        SchemaProperty[] props = this.getElementProperties();

        for (SchemaProperty prop : props) {
            qnsb.remove(prop.getName());
        }

        return qnsb.toQNameSet();
    }

    private static void computeWildcardSet(SchemaParticle model, QNameSetBuilder result) {
        if (model.getParticleType() == SchemaParticle.WILDCARD) {
            QNameSet cws = model.getWildcardSet();
            result.addAll(cws);
            return;
        }
        for (int i = 0; i < model.countOfParticleChild(); i++) {
            SchemaParticle child = model.getParticleChild(i);
            computeWildcardSet(child, result);
        }
    }

    /**
     * Returns a QNameSet of attributes that may exist in wildcard
     * buchets and are not explicitly defined in this schema type.
     * Note: In this example:
     * <xs:complexType name="exampleType">
     * ...
     * <xs:attribute name='someAttribute' type='xs:string' />
     * <xs:anyAttribute namespace="##targetNamespace" />
     * </xs:complexType>
     * the returned QNameSet will not contain the qname of 'someAttribute'.
     *
     * @return the constructed QNameSet
     */
    public QNameSet qnameSetForWildcardAttributes() {
        SchemaAttributeModel model = this.getAttributeModel();
        QNameSet wildcardSet = model.getWildcardSet();

        if (wildcardSet == null) {
            return QNameSet.EMPTY;
        }

        QNameSetBuilder qnsb = new QNameSetBuilder(wildcardSet);

        SchemaProperty[] props = this.getAttributeProperties();

        for (SchemaProperty prop : props) {
            qnsb.remove(prop.getName());
        }

        return qnsb.toQNameSet();
    }
}
