/*   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.util.ExceptionUtil;
import org.apache.xmlbeans.impl.values.*;
import org.apache.xmlbeans.impl.xb.xsdschema.AnnotationDocument.Annotation;
import org.apache.xmlbeans.impl.xb.xsdschema.DocumentationDocument.Documentation;
import org.apache.xmlbeans.impl.xb.xsdschema.Element;

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

    private String _documentation;

    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 noElements() {
        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() || noElements() || 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() || noElements() || 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 synchronized 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:
     * <pre>{@code
     * <xs:complexType name="exampleType">
     * <xs:sequence>
     * <xs:element name="someElement" type='xs:string' />
     * <xs:any namespace="##targetNamespace" />
     * </xs:sequence>
     * </xs:complexType>
     * }</pre>
     * 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:
     * <pre>{@code
     * <xs:complexType name="exampleType">
     * ...
     * <xs:attribute name='someAttribute' type='xs:string' />
     * <xs:anyAttribute namespace="##targetNamespace" />
     * </xs:complexType>
     * }</pre>
     * 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();
    }

    public String getDocumentation() {
        if (_documentation == null) {
            _documentation = parseDocumentation(_parseObject);
        }
        return _documentation;
    }

    private static String parseDocumentation(XmlObject lcti) {
        String str = lcti.toString();
        Element el;
        try {
            el = Element.Factory.parse(str);
        } catch (Throwable e) {
            if (ExceptionUtil.isFatal(e)) {
                ExceptionUtil.rethrow(e);
            }
            return "";
        }

        Annotation ann = el.getAnnotation();
        if (ann == null || ann.sizeOfDocumentationArray() == 0) {
            return "";
        }

        StringBuilder docBody = new StringBuilder();
        for (Documentation documentation : ann.getDocumentationArray()) {
            try (XmlCursor c = documentation.newCursor()) {
                if (c.getChars() != null) {
                    docBody.append(c.getTextValue());
                }
            }
        }
        return docBody.toString();
    }
}
